* src/vm/jit/powerpc/asmpart.S (asm_vm_call_method): Replaced $stub
[cacao.git] / src / vm / jit / powerpc / asmpart.S
1 /* src/vm/jit/powerpc/asmpart.S - Java-C interface functions for PowerPC
2                 
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software.text;  you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation;  either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY ;  without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program;  if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Stefan Ring
30
31    Changes: Christian Thalinger
32             Edwin Steiner
33
34    $Id: asmpart.S 4715 2006-03-31 07:50:19Z twisti $
35
36 */
37
38
39 #include "config.h"
40
41 #include "md-abi.h"
42 #include "md-asm.h"
43
44 #include "vm/jit/abi-asm.h"
45 #include "vm/jit/methodheader.h"
46 #include "vm/jit/powerpc/offsets.h"
47
48
49         .text
50
51         .align 2
52
53
54 /* exported functions and variables *******************************************/
55
56         .globl asm_vm_call_method
57         .globl asm_vm_call_method_int
58         .globl asm_vm_call_method_long
59         .globl asm_vm_call_method_float
60         .globl asm_vm_call_method_double
61
62         .globl asm_vm_call_method_exception_handler
63
64         .globl asm_call_jit_compiler
65
66         .globl asm_handle_nat_exception
67         .globl asm_handle_exception
68
69         .globl asm_wrapper_patcher
70
71         .globl asm_replacement_out
72         .globl asm_replacement_in
73
74         .globl asm_cacheflush
75         .globl asm_initialize_thread_stack
76         .globl asm_perform_threadswitch
77         .globl asm_switchstackandcall
78         .globl asm_criticalsections
79         .globl asm_getclassvalues_atomic
80
81
82 /* asm_vm_call_method **********************************************************
83 *                                                                              *
84 *   This function calls a Java-method (which possibly needs compilation)       *
85 *   with up to 4 address parameters.                                           *
86 *                                                                              *
87 *   This functions calls the JIT-compiler which eventually translates the      *
88 *   method into machine code.                                                  *
89 *                                                                              *
90 *   C-prototype:                                                               *
91 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
92 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
93 *                                                                              *
94 *******************************************************************************/
95
96         .align 2
97
98         .long   0                         /* catch type all                       */
99         .long   0                         /* exception handler pc                 */
100         .long   0                         /* end pc                               */
101         .long   0                         /* start pc                             */
102         .long   1                         /* extable size                         */
103         .long   0                         /* line number table start              */
104         .long   0                         /* line number table size               */
105         .long   0                         /* fltsave                              */
106         .long   0                         /* intsave                              */
107         .long   0                         /* isleaf                               */
108         .long   0                         /* IsSync                               */
109         .long   0                         /* frame size                           */
110         .long   0                         /* method pointer (pointer to name)     */
111
112 asm_vm_call_method:
113 asm_vm_call_method_int:
114 asm_vm_call_method_long:
115 asm_vm_call_method_float:
116 asm_vm_call_method_double:
117         mflr    r0
118         stw     r0,LA_LR_OFFSET(r1)
119         stwu    r1,-40*4(r1)
120
121 #if defined(__DARWIN__)
122         stw     itmp1,10*4(sp)            /* register r11 is callee saved         */
123 #endif
124         stw     pv,11*4(sp)               /* save PV register                     */
125
126         stw     itmp3,12*4(sp)            /* registers r14-r31 are callee saved   */
127         stfd    ftmp1,14*4(sp)            /* registers f14-f31 are callee saved   */
128         stfd    ftmp2,16*4(sp)
129
130 #if defined(__DARWIN__)
131         stw     t1,18*4(r1)
132         stw     t2,19*4(r1)
133         stw     t3,20*4(r1)
134         stw     t4,21*4(r1)
135         stw     t5,22*4(r1)
136         stw     t6,23*4(r1)
137         stw     t7,24*4(r1)
138
139         stfd    ft0,26*4(r1)
140         stfd    ft1,28*4(r1)
141         stfd    ft2,30*4(r1)
142         stfd    ft3,32*4(r1)
143         stfd    ft4,34*4(r1)
144         stfd    ft5,36*4(r1)
145 #else
146         SAVE_TEMPORARY_REGISTERS(18)      /* the offset has to be even            */
147 #endif
148
149         stw     a0,9*4(r1)                /* save method pointer for compiler     */
150
151         mr      itmp1,r5                  /* pointer to arg block                 */
152         mr      itmp2,r4                  /* arg count                            */
153
154         addi    itmp1,itmp1,-sizevmarg    /* initialize pointer (smaller code)    */
155         addi    itmp2,itmp2,1             /* initialize argument count            */
156         li      t0,0                      /* initialize integer argument counter  */
157         li      t1,0                      /* initialize float argument counter    */
158
159         mflr    r0                        /* save link register (PIC code)        */
160         bl      L_asm_vm_call_method_get_pc
161 L_asm_vm_call_method_get_pc:
162         mflr    t3                        /* t3 contains the current pc           */
163         mtlr    r0
164
165 L_register_copy:
166         addi    itmp1,itmp1,sizevmarg     /* goto next argument block             */
167         addi    itmp2,itmp2,-1            /* argument count - 1                   */
168         mr.     itmp2,itmp2
169         beq     L_register_copy_done
170
171 #if WORDS_BIGENDIAN == 1
172         lwz     itmp3,offvmargtype+4(itmp1)
173 #else
174 #error XXX
175 #endif
176         andi.   r0,itmp3,0x0002           /* is this a float/double type?         */
177         bne     L_register_handle_float
178
179         cmpwi   t0,INT_ARG_CNT            /* are we out of integer argument       */
180         beq     L_register_copy           /* registers? yes, next loop            */
181
182         andi.   r0,itmp3,0x0001           /* is this a long type?                 */
183         bne     L_register_handle_long
184
185 L_register_handle_int:
186 #if defined(__DARWIN__)
187         addis   itmp3,t3,ha16(L_jumptable_int - L_asm_vm_call_method_get_pc)
188         la      itmp3,lo16(L_jumptable_int - L_asm_vm_call_method_get_pc)(itmp3)
189 #else
190         lis     itmp3,L_jumptable_int@ha
191         addi    itmp3,itmp3,L_jumptable_int@l
192 #endif
193         slwi    t2,t0,2                   /* multiple of 4-bytes                  */
194         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
195         lwz     itmp3,0(itmp3)            /* load function address                */
196         addi    t0,t0,1                   /* integer argument counter + 1         */
197         mtctr   itmp3
198         bctr
199
200 L_register_handle_long:
201 #if defined(__DARWIN__)
202         addis   itmp3,t3,ha16(L_jumptable_long - L_asm_vm_call_method_get_pc)
203         la      itmp3,lo16(L_jumptable_long - L_asm_vm_call_method_get_pc)(itmp3)
204 #else
205         lis     itmp3,L_jumptable_long@ha
206         addi    itmp3,itmp3,L_jumptable_long@l
207 #endif
208         addi    t2,t0,1                   /* align to even numbers                */
209         srwi    t2,t2,1
210         slwi    t2,t2,1
211         slwi    t2,t2,2                   /* multiple of 4-bytes                  */
212         add     itmp3,itmp3,t2            /* calculate address of jumptable       */
213         lwz     itmp3,0(itmp3)            /* load function address                */
214         addi    t0,t0,1                   /* integer argument counter + 1         */
215         mtctr   itmp3
216         bctr
217
218 L_register_handle_float:
219 L_register_copy_done:
220
221 L_stack_copy_done:
222         lwz     itmp1,9*4(sp)             /* pass method pointer via tmp1         */
223
224 #if defined(__DARWIN__)
225         addis   mptr,t3,ha16(L_asm_call_jit_compiler - L_asm_vm_call_method_get_pc)
226         la      mptr,lo16(L_asm_call_jit_compiler - L_asm_vm_call_method_get_pc)(mptr)
227 #else
228         lis     mptr,L_asm_call_jit_compiler@ha
229         addi    mptr,mptr,L_asm_call_jit_compiler@l
230 #endif
231         stw     mptr,8*4(r1)
232         addi    mptr,r1,7*4
233
234         lwz     pv,1*4(mptr)
235         mtctr   pv
236         bctrl
237 1:
238         mflr    itmp1
239 #if defined(__DARWIN__)
240         addi    pv,itmp1,lo16(asm_vm_call_method - 1b)
241 #else
242         addi    pv,itmp1,(asm_vm_call_method - 1b)@l
243 #endif
244
245 L_asm_vm_call_method_return:
246 #if defined(__DARWIN__)
247         lwz     itmp1,10*4(sp)            /* register r11 is callee saved         */
248 #endif
249         lwz     pv,11*4(sp)               /* save PV register                     */
250
251         lwz     itmp3,12*4(sp)
252         lfd     ftmp1,14*4(sp)            /* registers f14-f31 are callee saved   */
253         lfd     ftmp2,16*4(sp)
254
255 #if defined(__DARWIN__)
256         lwz     t1,18*4(r1)
257         lwz     t2,19*4(r1)
258         lwz     t3,20*4(r1)
259         lwz     t4,21*4(r1)
260         lwz     t5,22*4(r1)
261         lwz     t6,23*4(r1)
262         lwz     t7,24*4(r1)
263
264         lfd     ft0,26*4(r1)
265         lfd     ft1,28*4(r1)
266         lfd     ft2,30*4(r1)
267         lfd     ft3,32*4(r1)
268         lfd     ft4,34*4(r1)
269         lfd     ft5,36*4(r1)
270 #else
271         RESTORE_TEMPORARY_REGISTERS(18)   /* the offset has to be even            */
272 #endif
273
274         lwz     r0,40*4+LA_LR_OFFSET(r1)
275         mtlr    r0
276         addi    r1,r1,40*4
277         blr
278
279 asm_vm_call_method_exception_handler:
280 #if !defined(NDEBUG)
281         mr      r3,itmp1
282         bl      builtin_throw_exception
283 #endif
284         li      v0,0                      /* return NULL                          */
285         b       L_asm_vm_call_method_return
286
287
288         .data
289         .align  2
290
291 L_jumptable_int:
292         .long   L_handle_a0
293         .long   L_handle_a1
294         .long   L_handle_a2
295         .long   L_handle_a3
296         .long   L_handle_a4
297         .long   L_handle_a5
298         .long   L_handle_a6
299         .long   L_handle_a7
300
301         .text
302         .align  2
303
304 L_handle_a0:
305         lwz     a0,offvmargdata+4(itmp1)
306         b       L_register_copy
307 L_handle_a1:
308         lwz     a1,offvmargdata+4(itmp1)
309         b       L_register_copy
310 L_handle_a2:
311         lwz     a2,offvmargdata+4(itmp1)
312         b       L_register_copy
313 L_handle_a3:
314         lwz     a3,offvmargdata+4(itmp1)
315         b       L_register_copy
316 L_handle_a4:
317         lwz     a4,offvmargdata+4(itmp1)
318         b       L_register_copy
319 L_handle_a5:
320         lwz     a5,offvmargdata+4(itmp1)
321         b       L_register_copy
322 L_handle_a6:
323         lwz     a6,offvmargdata+4(itmp1)
324         b       L_register_copy
325 L_handle_a7:
326         lwz     a7,offvmargdata+4(itmp1)
327         b       L_register_copy
328
329
330         .data
331         .align  2
332
333 L_jumptable_long:
334 #if defined(__DARWIN__)
335 #else
336         /* we have two entries here, so we get the even argument register
337         alignment for linux */
338
339         .long   L_handle_a0_a1
340         .long   0
341         .long   L_handle_a2_a3
342         .long   0
343         .long   L_handle_a4_a5
344         .long   0
345         .long   L_handle_a6_a7
346         .long   0
347 #endif
348
349         .text
350         .align  2
351
352 L_handle_a0_a1:
353         lwz     a0,offvmargdata+0(itmp1)
354         lwz     a1,offvmargdata+4(itmp1)
355         b       L_register_copy
356 L_handle_a2_a3:
357         lwz     a2,offvmargdata+0(itmp1)
358         lwz     a3,offvmargdata+4(itmp1)
359         b       L_register_copy
360 L_handle_a4_a5:
361         lwz     a4,offvmargdata+0(itmp1)
362         lwz     a5,offvmargdata+4(itmp1)
363         b       L_register_copy
364 L_handle_a6_a7:
365         lwz     a6,offvmargdata+0(itmp1)
366         lwz     a7,offvmargdata+4(itmp1)
367         b       L_register_copy
368
369
370 /* asm_call_jit_compiler *******************************************************
371
372    Invokes the compiler for untranslated JavaVM methods.
373
374 *******************************************************************************/
375
376 asm_call_jit_compiler:
377 L_asm_call_jit_compiler:                /* required for PIC code              */
378         mflr    r0
379         stw     r0,LA_LR_OFFSET(r1)         /* save return address                */
380         stwu    r1,-((LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo)(r1)
381         stw     itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
382
383         mr      itmp1,r0                    /* save return address to other reg.  */
384         lwz     itmp3,-12(itmp1)
385         srwi    itmp3,itmp3,16
386         andi.   itmp3,itmp3,31
387         cmpwi   itmp3,mptrn
388         beq     noregchange
389         lwz     itmp3,4(itmp1)
390         extsh   itmp3,itmp3
391         add     mptr,itmp3,itmp1
392         lwz     itmp3,8(itmp1)
393         srwi    itmp3,itmp3,16
394         cmpwi   itmp3,0x3dad
395         bne     noregchange
396         lwz     itmp3,8(itmp1)
397         slwi    itmp3,itmp3,16
398         add     mptr,mptr,itmp3
399                 
400 noregchange:
401         stw     mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
402
403 #if defined(__DARWIN__)
404         stw     a0,(LA_WORD_SIZE+5+0)*4(r1)
405         stw     a1,(LA_WORD_SIZE+5+1)*4(r1)
406         stw     a2,(LA_WORD_SIZE+5+2)*4(r1)
407         stw     a3,(LA_WORD_SIZE+5+3)*4(r1)
408         stw     a4,(LA_WORD_SIZE+5+4)*4(r1)
409         stw     a5,(LA_WORD_SIZE+5+5)*4(r1)
410         stw     a6,(LA_WORD_SIZE+5+6)*4(r1)
411         stw     a7,(LA_WORD_SIZE+5+7)*4(r1)
412
413         stfd    fa0,(LA_WORD_SIZE+5+8)*4(r1)
414         stfd    fa1,(LA_WORD_SIZE+5+10)*4(r1)
415         stfd    fa2,(LA_WORD_SIZE+5+12)*4(r1)
416         stfd    fa3,(LA_WORD_SIZE+5+14)*4(r1)
417         stfd    fa4,(LA_WORD_SIZE+5+16)*4(r1)
418         stfd    fa5,(LA_WORD_SIZE+5+18)*4(r1)
419         stfd    fa6,(LA_WORD_SIZE+5+20)*4(r1)
420         stfd    fa7,(LA_WORD_SIZE+5+22)*4(r1)
421         stfd    fa8,(LA_WORD_SIZE+5+24)*4(r1)
422         stfd    fa9,(LA_WORD_SIZE+5+26)*4(r1)
423         stfd    fa10,(LA_WORD_SIZE+5+28)*4(r1)
424         stfd    fa11,(LA_WORD_SIZE+5+30)*4(r1)
425         stfd    fa12,(LA_WORD_SIZE+5+32)*4(r1)
426 #else
427         SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
428 #endif
429
430         addi    a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
431         li      a1,0                        /* we don't have pv handy             */
432         addi    a2,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
433         lwz     a3,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(sp)
434         mr      a4,a3                       /* xpc is equal to ra                 */
435         bl      stacktrace_create_extern_stackframeinfo
436
437         lwz     a0,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
438         bl      jit_compile                 /* compile the Java method            */
439         mr      pv,r3                       /* move address to pv register        */
440
441         addi    a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
442         bl      stacktrace_remove_stackframeinfo
443
444 #if defined(__DARWIN__)
445         lwz     a0,(LA_WORD_SIZE+5+0)*4(r1)
446         lwz     a1,(LA_WORD_SIZE+5+1)*4(r1)
447         lwz     a2,(LA_WORD_SIZE+5+2)*4(r1)
448         lwz     a3,(LA_WORD_SIZE+5+3)*4(r1)
449         lwz     a4,(LA_WORD_SIZE+5+4)*4(r1)
450         lwz     a5,(LA_WORD_SIZE+5+5)*4(r1)
451         lwz     a6,(LA_WORD_SIZE+5+6)*4(r1)
452         lwz     a7,(LA_WORD_SIZE+5+7)*4(r1)
453
454         lfd     fa0,(LA_WORD_SIZE+5+8)*4(r1)
455         lfd     fa1,(LA_WORD_SIZE+5+10)*4(r1)
456         lfd     fa2,(LA_WORD_SIZE+5+12)*4(r1)
457         lfd     fa3,(LA_WORD_SIZE+5+14)*4(r1)
458         lfd     fa4,(LA_WORD_SIZE+5+16)*4(r1)
459         lfd     fa5,(LA_WORD_SIZE+5+18)*4(r1)
460         lfd     fa6,(LA_WORD_SIZE+5+20)*4(r1)
461         lfd     fa7,(LA_WORD_SIZE+5+22)*4(r1)
462         lfd     fa8,(LA_WORD_SIZE+5+24)*4(r1)
463         lfd     fa9,(LA_WORD_SIZE+5+26)*4(r1)
464         lfd     fa10,(LA_WORD_SIZE+5+28)*4(r1)
465         lfd     fa11,(LA_WORD_SIZE+5+30)*4(r1)
466         lfd     fa12,(LA_WORD_SIZE+5+32)*4(r1)
467 #else
468         RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
469 #endif
470
471         lwz     mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
472
473         lwz     itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(r1)
474         mtlr    itmp1
475         addi    r1,r1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
476
477         mr.     pv,pv                       /* test for exception                 */
478         beq     L_asm_call_jit_compiler_exception
479
480         lwz     itmp3,-12(itmp1)
481         extsh   itmp3,itmp3
482         add     mptr,mptr,itmp3
483         stw     pv,0(mptr)                  /* store method address               */
484
485         mtctr   pv                          /* move method address to control reg */
486         bctr                                /* and call the Java method           */
487
488 L_asm_call_jit_compiler_exception:
489 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
490         mflr    r0
491         stw     r0,LA_LR_OFFSET(sp)
492         stwu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
493         bl      builtin_asm_get_exceptionptrptr
494         lwz     r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
495         mtlr    r0      
496         addi    sp,sp,LA_SIZE_ALIGNED
497 #else
498 # if defined(__DARWIN__)
499         lis     v0,ha16(_no_threads_exceptionptr)
500         addi    v0,v0,lo16(_no_threads_exceptionptr)
501 # else
502         lis     v0,_no_threads_exceptionptr@ha
503         addi    v0,v0,_no_threads_exceptionptr@l
504 # endif
505 #endif
506         lwz     xptr,0(v0)                  /* get the exception pointer          */
507         li      itmp3,0
508         stw     itmp3,0(v0)                 /* clear the exception pointer        */
509
510         mflr    xpc
511         addi    xpc,xpc,-4
512         b       L_asm_handle_nat_exception
513
514
515 /********************* function asm_handle_exception ***************************
516 *                                                                              *
517 *   This function handles an exception. It does not use the usual calling      *
518 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
519 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
520 *   the local exception table for a handler. If no one is found, it unwinds    *
521 *   stacks and continues searching the callers.                                *
522 *                                                                              *
523 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
524 *                                                                              *
525 *******************************************************************************/
526                 
527 asm_handle_nat_exception:
528 L_asm_handle_nat_exception:             /* required for PIC code              */
529         mflr    r9
530         lwz     itmp3,4(r9)
531         extsh   itmp3,itmp3
532         add     pv,itmp3,r9
533         lwz     itmp3,8(r9)
534         srwi    itmp3,itmp3,16
535         cmpwi   itmp3,0x3dad
536         bne     L_asm_handle_exception
537         lwz     itmp3,8(r9)
538         slwi    itmp3,itmp3,16
539         add     pv,pv,itmp3
540
541 asm_handle_exception:
542 L_asm_handle_exception:                 /* required for PIC code              */
543         addi    sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
544
545 #if defined(__DARWIN__)
546 #else
547         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
548         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
549 #endif
550
551         li      a3,(ARG_CNT+TMP_CNT)*8      /* prepare a3 for handle_exception    */
552         li      a4,1                        /* set maybe-leaf flag                */
553
554 L_asm_handle_exception_stack_loop:
555         addi    sp,sp,-(LA_WORD_SIZE+4+5)*4 /* allocate stack                     */
556         stw     xptr,LA_SIZE+4*4(sp)        /* save exception pointer             */
557         stw     xpc,LA_SIZE+5*4(sp)         /* save exception pc                  */
558         stw     pv,LA_SIZE+6*4(sp)          /* save data segment pointer          */
559         mflr    r0                          /* save return address                */
560         stw     r0,LA_SIZE+5*4(sp)
561         add     a3,a3,sp                    /* calculate Java sp into a3...       */
562         addi    a3,a3,(LA_WORD_SIZE+4+5)*4
563         stw     a4,LA_SIZE+8*4(sp)          /* save maybe-leaf flag               */
564
565         mr      a0,xptr                     /* pass exception pointer             */
566         mr      a1,xpc                      /* pass exception pc                  */
567         mr      a2,pv                       /* pass data segment pointer          */
568                                             /* a3 is still set                    */
569         bl      exceptions_handle_exception
570
571         mr.     v0,v0
572         beq     L_asm_handle_exception_not_catched
573
574         mr      xpc,v0                      /* move handlerpc into xpc            */
575         lwz     xptr,LA_SIZE+4*4(sp)        /* restore exception pointer          */
576         lwz     pv,LA_SIZE+6*4(sp)          /* restore data segment pointer       */
577         lwz     r0,LA_SIZE+5*4(sp)          /* restore return address             */
578         mtlr    r0
579         lwz     a4,LA_SIZE+8*4(sp)          /* get maybe-leaf flag                */
580         addi    sp,sp,(LA_WORD_SIZE+4+5)*4  /* free stack frame                   */
581
582         mr.     a4,a4
583         beq     L_asm_handle_exception_no_leaf
584
585 #if defined(__DARWIN__)
586 #else
587         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
588         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
589 #endif
590
591         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
592
593 L_asm_handle_exception_no_leaf:
594         mtctr   xpc                         /* jump to the handler                */
595         bctr
596
597 L_asm_handle_exception_not_catched:
598         lwz     xptr,LA_SIZE+4*4(sp)        /* restore exception pointer          */
599         lwz     pv,LA_SIZE+6*4(sp)          /* restore data segment pointer       */
600         lwz     r0,LA_SIZE+5*4(sp)          /* restore return address             */
601         mtlr    r0
602         lwz     a4,LA_SIZE+8*4(sp)          /* get maybe-leaf flag                */
603         addi    sp,sp,(LA_WORD_SIZE+4+5)*4  /* free stack frame                   */
604
605         mr.     a4,a4
606         beq     L_asm_handle_exception_no_leaf_stack
607
608         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
609         li      a4,0                        /* clear the maybe-leaf flag          */
610
611 L_asm_handle_exception_no_leaf_stack:
612         lwz     t0,FrameSize(pv)            /* get frame size                     */
613         add     t0,sp,t0                    /* pointer to save area               */
614
615         lwz     t1,IsLeaf(pv)               /* is leaf procedure                  */
616         mr.     t1,t1
617         bne     L_asm_handle_exception_no_ra_restore
618
619         lwz     r0,LA_LR_OFFSET(t0)         /* restore ra                         */
620         mtlr    r0
621
622 L_asm_handle_exception_no_ra_restore:
623         mflr    xpc                         /* the new xpc is ra                  */
624         lwz     t1,IntSave(pv)              /* t1 = saved int register count      */
625         bl      ex_int1
626 ex_int1:
627         mflr    t2                          /* t2 = current pc                    */
628 #if defined(__DARWIN__)
629         addi    t2,t2,lo16(ex_int2-ex_int1)
630 #else
631         addi    t2,t2,(ex_int2-ex_int1)@l
632 #endif
633         slwi    t1,t1,2                     /* t1 = register count * 4            */
634         subf    t2,t1,t2                    /* t2 = IntSave - t1                  */
635         mtctr   t2
636         bctr
637
638         lwz     s0,-10*4(t0)
639         lwz     s1,-9*4(t0)
640         lwz     s2,-8*4(t0)
641         lwz     s3,-7*4(t0)
642         lwz     s4,-6*4(t0)
643         lwz     s5,-5*4(t0)
644         lwz     s6,-4*4(t0)
645         lwz     s7,-3*4(t0)
646         lwz     s8,-2*4(t0)
647         lwz     s9,-1*4(t0)
648
649 ex_int2:
650         subf    t0,t1,t0                    /* t0 = t0 - register count * 4       */
651
652         lwz     t1,FltSave(pv)
653         bl      ex_flt1
654 ex_flt1:
655         mflr    t2
656 #if defined(__DARWIN__)
657         addi    t2,t2,lo16(ex_flt2-ex_flt1)
658 #else
659         addi    t2,t2,(ex_flt2-ex_flt1)@l
660 #endif
661         slwi    t1,t1,2                     /* t1 = register count * 4            */
662         subf    t2,t1,t2                    /* t2 = FltSave - t1                  */
663         mtctr   t2
664         bctr
665
666         lfd     fs0,-10*8(t0)
667         lfd     fs1,-9*8(t0)
668         lfd     fs2,-8*8(t0)
669         lfd     fs3,-7*8(t0)
670         lfd     fs4,-6*8(t0)
671         lfd     fs5,-5*8(t0)
672         lfd     fs6,-4*8(t0)
673         lfd     fs7,-3*8(t0)
674         lfd     fs8,-2*8(t0)
675         lfd     fs9,-1*8(t0)
676
677 ex_flt2:
678         lwz     t0,FrameSize(pv)            /* get frame size                     */
679         add     sp,sp,t0                    /* unwind stack                       */
680         li      a3,0                        /* prepare a3 for handle_exception    */
681
682         mtlr    xpc
683         lwz     itmp3,4(xpc)
684         extsh   itmp3,itmp3
685         add     pv,itmp3,xpc
686         lwz     itmp3,8(xpc)
687         srwi    itmp3,itmp3,16
688         cmpwi   itmp3,0x3dad
689         bne     L_asm_handle_exception_stack_loop
690         lwz     itmp3,8(xpc)
691         slwi    itmp3,itmp3,16
692         add     pv,pv,itmp3
693
694         b       L_asm_handle_exception_stack_loop
695
696
697 /* asm_wrapper_patcher *********************************************************
698
699    XXX
700
701    Stack layout:
702      20   return address into JIT code (patch position)
703      16   pointer to virtual java_objectheader
704      12   machine code (which is patched back later)
705       8   unresolved class/method/field reference
706       4   data segment displacement from load instructions
707       0   patcher function pointer to call (pv is saved here afterwards)
708
709 *******************************************************************************/
710
711 asm_wrapper_patcher:
712         mflr    r0                    /* get Java return address (leaf)           */
713         stw     r0,6*4(sp)            /* store it in the stub stackframe          */
714                                       /* keep stack 16-bytes aligned: 6+1+37 = 44 */
715         stwu    sp,-(LA_SIZE+(5+58)*4+sizestackframeinfo)(sp)
716
717 #if defined(__DARWIN__)
718         stw     a0,LA_SIZE+(5+0)*4(r1)      /* save argument registers            */
719         stw     a1,LA_SIZE+(5+1)*4(r1)      /* preserve linkage area (24 bytes)   */
720         stw     a2,LA_SIZE+(5+2)*4(r1)      /* and 4 bytes for 4 argument         */
721         stw     a3,LA_SIZE+(5+3)*4(r1)
722         stw     a4,LA_SIZE+(5+4)*4(r1)
723         stw     a5,LA_SIZE+(5+5)*4(r1)
724         stw     a6,LA_SIZE+(5+6)*4(r1)
725         stw     a7,LA_SIZE+(5+7)*4(r1)
726
727         stfd    fa0,LA_SIZE+(5+8)*4(sp)
728         stfd    fa1,LA_SIZE+(5+10)*4(sp)
729         stfd    fa2,LA_SIZE+(5+12)*4(sp)
730         stfd    fa3,LA_SIZE+(5+14)*4(sp)
731         stfd    fa4,LA_SIZE+(5+16)*4(sp)
732         stfd    fa5,LA_SIZE+(5+18)*4(sp)
733         stfd    fa6,LA_SIZE+(5+20)*4(sp)
734         stfd    fa7,LA_SIZE+(5+22)*4(sp)
735         stfd    fa8,LA_SIZE+(5+24)*4(sp)
736         stfd    fa9,LA_SIZE+(5+26)*4(sp)
737         stfd    fa10,LA_SIZE+(5+28)*4(sp)
738         stfd    fa11,LA_SIZE+(5+30)*4(sp)
739         stfd    fa12,LA_SIZE+(5+32)*4(sp)
740
741         stw     t0,(LA_WORD_SIZE+5+33)*4(r1)
742         stw     t1,(LA_WORD_SIZE+5+34)*4(r1)
743         stw     t2,(LA_WORD_SIZE+5+35)*4(r1)
744         stw     t3,(LA_WORD_SIZE+5+36)*4(r1)
745         stw     t4,(LA_WORD_SIZE+5+37)*4(r1)
746         stw     t5,(LA_WORD_SIZE+5+38)*4(r1)
747         stw     t6,(LA_WORD_SIZE+5+39)*4(r1)
748         stw     t7,(LA_WORD_SIZE+5+40)*4(r1)
749
750         stfd    ft0,(LA_WORD_SIZE+5+42)*4(r1)
751         stfd    ft1,(LA_WORD_SIZE+5+44)*4(r1)
752         stfd    ft2,(LA_WORD_SIZE+5+46)*4(r1)
753         stfd    ft3,(LA_WORD_SIZE+5+48)*4(r1)
754         stfd    ft4,(LA_WORD_SIZE+5+50)*4(r1)
755         stfd    ft5,(LA_WORD_SIZE+5+52)*4(r1)
756 #else
757         SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/8 float arguments   */
758         SAVE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
759 #endif
760
761         stw     itmp1,LA_SIZE+(5+54)*4(sp)
762         stw     itmp2,LA_SIZE+(5+55)*4(sp)
763         stw     pv,LA_SIZE+(5+56)*4(sp)
764
765         addi    a0,sp,LA_SIZE+(5+58)*4      /* create stackframe info             */
766         mr      a1,pv
767         addi    a2,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
768         mr      a3,r0                       /* this is correct for leafs          */
769         lwz     a4,((5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo)(sp) /* pass xpc   */
770         bl      stacktrace_create_extern_stackframeinfo
771
772         addi    a0,sp,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo  /* pass sp      */
773         lwz     pv,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* get function */
774         lwz     itmp1,LA_SIZE+(5+56)*4(sp)  /* move pv to position of fp          */
775         stw     itmp1,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
776         mtctr   pv                          /* call the patcher function          */
777         bctrl
778         stw     v0,LA_SIZE+(5+57)*4(sp)     /* save return value                  */
779
780         addi    a0,sp,LA_SIZE+(5+58)*4
781         bl      stacktrace_remove_stackframeinfo /* remove stackframe info        */
782
783 #if defined(__DARWIN__)
784         lwz     a0,LA_SIZE+(5+0)*4(r1)
785         lwz     a1,LA_SIZE+(5+1)*4(r1)
786         lwz     a2,LA_SIZE+(5+2)*4(r1)
787         lwz     a3,LA_SIZE+(5+3)*4(r1)
788         lwz     a4,LA_SIZE+(5+4)*4(r1)
789         lwz     a5,LA_SIZE+(5+5)*4(r1)
790         lwz     a6,LA_SIZE+(5+6)*4(r1)
791         lwz     a7,LA_SIZE+(5+7)*4(r1)
792
793         lfd     fa0,LA_SIZE+(5+8)*4(sp)
794         lfd     fa1,LA_SIZE+(5+10)*4(sp)
795         lfd     fa2,LA_SIZE+(5+12)*4(sp)
796         lfd     fa3,LA_SIZE+(5+14)*4(sp)
797         lfd     fa4,LA_SIZE+(5+16)*4(sp)
798         lfd     fa5,LA_SIZE+(5+18)*4(sp)
799         lfd     fa6,LA_SIZE+(5+20)*4(sp)
800         lfd     fa7,LA_SIZE+(5+22)*4(sp)
801         lfd     fa8,LA_SIZE+(5+24)*4(sp)
802         lfd     fa9,LA_SIZE+(5+26)*4(sp)
803         lfd     fa10,LA_SIZE+(5+28)*4(sp)
804         lfd     fa11,LA_SIZE+(5+30)*4(sp)
805         lfd     fa12,LA_SIZE+(5+32)*4(sp)
806
807         lwz     t0,(LA_WORD_SIZE+5+33)*4(r1)
808         lwz     t1,(LA_WORD_SIZE+5+34)*4(r1)
809         lwz     t2,(LA_WORD_SIZE+5+35)*4(r1)
810         lwz     t3,(LA_WORD_SIZE+5+36)*4(r1)
811         lwz     t4,(LA_WORD_SIZE+5+37)*4(r1)
812         lwz     t5,(LA_WORD_SIZE+5+38)*4(r1)
813         lwz     t6,(LA_WORD_SIZE+5+39)*4(r1)
814         lwz     t7,(LA_WORD_SIZE+5+40)*4(r1)
815
816         lfd     ft0,(LA_WORD_SIZE+5+42)*4(r1)
817         lfd     ft1,(LA_WORD_SIZE+5+44)*4(r1)
818         lfd     ft2,(LA_WORD_SIZE+5+46)*4(r1)
819         lfd     ft3,(LA_WORD_SIZE+5+48)*4(r1)
820         lfd     ft4,(LA_WORD_SIZE+5+50)*4(r1)
821         lfd     ft5,(LA_WORD_SIZE+5+52)*4(r1)
822 #else
823         RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* restore 8 int/8 float args  */
824         RESTORE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
825 #endif
826
827         lwz     itmp1,LA_SIZE+(5+54)*4(sp)
828         lwz     itmp2,LA_SIZE+(5+55)*4(sp)
829         lwz     pv,LA_SIZE+(5+56)*4(sp)
830         lwz     itmp3,LA_SIZE+(5+57)*4(sp)  /* restore return value into temp reg.*/
831
832         lwz     r0,(6+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* restore RA   */
833         mtlr    r0
834
835         mr.     itmp3,itmp3           /* check for an exception                   */
836         beq     L_asm_wrapper_patcher_exception
837
838                                       /* get return address (into JIT code)       */
839         lwz     itmp3,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
840
841                                       /* remove stack frame + patcher stub stack  */
842         addi    sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
843
844         mtctr   itmp3
845         bctr                          /* jump to new patched code                 */
846
847 L_asm_wrapper_patcher_exception:
848         lwz     xpc,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
849         addi    sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
850
851 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
852         mflr    r0
853         stw     r0,LA_LR_OFFSET(sp)
854         stwu    sp,-(LA_SIZE+1*4)(sp) /* preserve linkage area                    */
855         stw     xpc,LA_SIZE+0*4(sp)
856         bl      builtin_asm_get_exceptionptrptr
857         lwz     xpc,LA_SIZE+0*4(sp)
858         lwz     r0,LA_SIZE+1*4+LA_LR_OFFSET(sp)
859         mtlr    r0
860         addi    sp,sp,LA_SIZE+1*4
861 #else
862 # if defined(__DARWIN__)
863         lis     v0,ha16(_no_threads_exceptionptr)
864         addi    v0,v0,lo16(_no_threads_exceptionptr)
865 # else
866         lis     v0,_no_threads_exceptionptr@ha
867         addi    v0,v0,_no_threads_exceptionptr@l
868 # endif
869 #endif
870
871         lwz     xptr,0(v0)            /* get the exception pointer                */
872         li      itmp3,0
873         stw     itmp3,0(v0)           /* clear the exception pointer              */
874         b       L_asm_handle_exception
875
876
877 /* asm_replacement_out *********************************************************
878
879    This code is jumped to from the replacement-out stubs that are executed
880    when a thread reaches an activated replacement point.
881
882    The purpose of asm_replacement_out is to read out the parts of the
883    execution state that cannot be accessed from C code, store this state,
884    and then call the C function replace_me.
885
886    Stack layout:
887       16                start of stack inside method to replace
888       0   rplpoint *    info on the replacement point that was reached
889
890    NOTE: itmp3 has been clobbered by the replacement-out stub!
891
892 *******************************************************************************/
893
894 /* some room to accomodate changes of the stack frame size during replacement */
895         /* XXX we should find a cleaner solution here */
896 #define REPLACEMENT_ROOM  512
897
898 asm_replacement_out:
899     /* create stack frame */
900         addi    sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
901
902         /* save link register */
903         mflr    r16
904
905         /* save registers in execution state */
906         stw     r0 ,( 0*8+offes_intregs)(sp)
907         stw     r1 ,( 1*8+offes_intregs)(sp)
908         stw     r2 ,( 2*8+offes_intregs)(sp)
909         stw     r3 ,( 3*8+offes_intregs)(sp)
910         stw     r4 ,( 4*8+offes_intregs)(sp)
911         stw     r5 ,( 5*8+offes_intregs)(sp)
912         stw     r6 ,( 6*8+offes_intregs)(sp)
913         stw     r7 ,( 7*8+offes_intregs)(sp)
914         stw     r8 ,( 8*8+offes_intregs)(sp)
915         stw     r9 ,( 9*8+offes_intregs)(sp)
916         stw     r10,(10*8+offes_intregs)(sp)
917         stw     r11,(11*8+offes_intregs)(sp)
918         stw     r12,(12*8+offes_intregs)(sp)
919         stw     r13,(13*8+offes_intregs)(sp)
920         stw     r14,(14*8+offes_intregs)(sp)
921         stw     r15,(15*8+offes_intregs)(sp)
922         stw     r16,(16*8+offes_intregs)(sp) /* link register */
923         stw     r17,(17*8+offes_intregs)(sp)
924         stw     r18,(18*8+offes_intregs)(sp)
925         stw     r19,(19*8+offes_intregs)(sp)
926         stw     r20,(20*8+offes_intregs)(sp)
927         stw     r21,(21*8+offes_intregs)(sp)
928         stw     r22,(22*8+offes_intregs)(sp)
929         stw     r23,(23*8+offes_intregs)(sp)
930         stw     r24,(24*8+offes_intregs)(sp)
931         stw     r25,(25*8+offes_intregs)(sp)
932         stw     r26,(26*8+offes_intregs)(sp)
933         stw     r27,(27*8+offes_intregs)(sp)
934         stw     r28,(28*8+offes_intregs)(sp)
935         stw     r29,(29*8+offes_intregs)(sp)
936         stw     r30,(30*8+offes_intregs)(sp)
937         stw     r31,(31*8+offes_intregs)(sp)
938         
939         stfd    fr0 ,( 0*8+offes_fltregs)(sp)
940         stfd    fr1 ,( 1*8+offes_fltregs)(sp)
941         stfd    fr2 ,( 2*8+offes_fltregs)(sp)
942         stfd    fr3 ,( 3*8+offes_fltregs)(sp)
943         stfd    fr4 ,( 4*8+offes_fltregs)(sp)
944         stfd    fr5 ,( 5*8+offes_fltregs)(sp)
945         stfd    fr6 ,( 6*8+offes_fltregs)(sp)
946         stfd    fr7 ,( 7*8+offes_fltregs)(sp)
947         stfd    fr8 ,( 8*8+offes_fltregs)(sp)
948         stfd    fr9 ,( 9*8+offes_fltregs)(sp)
949         stfd    fr10,(10*8+offes_fltregs)(sp)
950         stfd    fr11,(11*8+offes_fltregs)(sp)
951         stfd    fr12,(12*8+offes_fltregs)(sp)
952         stfd    fr13,(13*8+offes_fltregs)(sp)
953         stfd    fr14,(14*8+offes_fltregs)(sp)
954         stfd    fr15,(15*8+offes_fltregs)(sp)
955         stfd    fr16,(16*8+offes_fltregs)(sp)
956         stfd    fr17,(17*8+offes_fltregs)(sp)
957         stfd    fr18,(18*8+offes_fltregs)(sp)
958         stfd    fr19,(19*8+offes_fltregs)(sp)
959         stfd    fr20,(20*8+offes_fltregs)(sp)
960         stfd    fr21,(21*8+offes_fltregs)(sp)
961         stfd    fr22,(22*8+offes_fltregs)(sp)
962         stfd    fr23,(23*8+offes_fltregs)(sp)
963         stfd    fr24,(24*8+offes_fltregs)(sp)
964         stfd    fr25,(25*8+offes_fltregs)(sp)
965         stfd    fr26,(26*8+offes_fltregs)(sp)
966         stfd    fr27,(27*8+offes_fltregs)(sp)
967         stfd    fr28,(28*8+offes_fltregs)(sp)
968         stfd    fr29,(29*8+offes_fltregs)(sp)
969         stfd    fr30,(30*8+offes_fltregs)(sp)
970         stfd    fr31,(31*8+offes_fltregs)(sp)
971         
972         /* calculate sp of method */
973         addi    itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
974         stw     itmp1,(offes_sp)(sp)
975
976         /* store pv */
977         stw     pv,(offes_pv)(sp)
978
979         /* call replace_me */
980         lwz     a0,-(4*4)(itmp1)            /* arg0: rplpoint *                   */
981         mr      a1,sp                       /* arg1: execution state              */
982         addi    sp,sp,-(LA_SIZE_ALIGNED)
983         b       replace_me                  /* call C function replace_me         */
984
985 /* asm_replacement_in **********************************************************
986
987    This code writes the given execution state and jumps to the replacement
988    code.
989
990    This function never returns!
991
992    NOTE: itmp3 is not restored!
993
994    C prototype:
995       void asm_replacement_in(executionstate *es);
996
997 *******************************************************************************/
998
999 asm_replacement_in:
1000         /* a0 == executionstate *es */
1001
1002         /* set new sp and pv */
1003         lwz     sp,(offes_sp)(a0)
1004         lwz     pv,(offes_pv)(a0)
1005         
1006         /* copy registers from execution state */
1007         lwz     r0 ,( 0*8+offes_intregs)(a0)
1008         /* r1 is sp                       */
1009         /* r2 is reserved                 */
1010         /* a0 is loaded below             */
1011         lwz     r4 ,( 4*8+offes_intregs)(a0)
1012         lwz     r5 ,( 5*8+offes_intregs)(a0)
1013         lwz     r6 ,( 6*8+offes_intregs)(a0)
1014         lwz     r7 ,( 7*8+offes_intregs)(a0)
1015         lwz     r8 ,( 8*8+offes_intregs)(a0)
1016         lwz     r9 ,( 9*8+offes_intregs)(a0)
1017         lwz     r10,(10*8+offes_intregs)(a0)
1018         lwz     r11,(11*8+offes_intregs)(a0)
1019         lwz     r12,(12*8+offes_intregs)(a0)
1020         /* r13 is pv                      */
1021         lwz     r14,(14*8+offes_intregs)(a0)
1022         lwz     r15,(15*8+offes_intregs)(a0)
1023         lwz     r16,(16*8+offes_intregs)(a0) /* link register */
1024         lwz     r17,(17*8+offes_intregs)(a0)
1025         lwz     r18,(18*8+offes_intregs)(a0)
1026         lwz     r19,(19*8+offes_intregs)(a0)
1027         lwz     r20,(20*8+offes_intregs)(a0)
1028         lwz     r21,(21*8+offes_intregs)(a0)
1029         lwz     r22,(22*8+offes_intregs)(a0)
1030         lwz     r23,(23*8+offes_intregs)(a0)
1031         lwz     r24,(24*8+offes_intregs)(a0)
1032         lwz     r25,(25*8+offes_intregs)(a0)
1033         lwz     r26,(26*8+offes_intregs)(a0)
1034         lwz     r27,(27*8+offes_intregs)(a0)
1035         lwz     r28,(28*8+offes_intregs)(a0)
1036         lwz     r29,(29*8+offes_intregs)(a0)
1037         lwz     r30,(30*8+offes_intregs)(a0)
1038         lwz     r31,(31*8+offes_intregs)(a0)
1039         
1040         lfd     fr0 ,( 0*8+offes_fltregs)(a0)
1041         lfd     fr1 ,( 1*8+offes_fltregs)(a0)
1042         lfd     fr2 ,( 2*8+offes_fltregs)(a0)
1043         lfd     fr3 ,( 3*8+offes_fltregs)(a0)
1044         lfd     fr4 ,( 4*8+offes_fltregs)(a0)
1045         lfd     fr5 ,( 5*8+offes_fltregs)(a0)
1046         lfd     fr6 ,( 6*8+offes_fltregs)(a0)
1047         lfd     fr7 ,( 7*8+offes_fltregs)(a0)
1048         lfd     fr8 ,( 8*8+offes_fltregs)(a0)
1049         lfd     fr9 ,( 9*8+offes_fltregs)(a0)
1050         lfd     fr10,(10*8+offes_fltregs)(a0)
1051         lfd     fr11,(11*8+offes_fltregs)(a0)
1052         lfd     fr12,(12*8+offes_fltregs)(a0)
1053         lfd     fr13,(13*8+offes_fltregs)(a0)
1054         lfd     fr14,(14*8+offes_fltregs)(a0)
1055         lfd     fr15,(15*8+offes_fltregs)(a0)
1056         lfd     fr16,(16*8+offes_fltregs)(a0)
1057         lfd     fr17,(17*8+offes_fltregs)(a0)
1058         lfd     fr18,(18*8+offes_fltregs)(a0)
1059         lfd     fr19,(19*8+offes_fltregs)(a0)
1060         lfd     fr20,(20*8+offes_fltregs)(a0)
1061         lfd     fr21,(21*8+offes_fltregs)(a0)
1062         lfd     fr22,(22*8+offes_fltregs)(a0)
1063         lfd     fr23,(23*8+offes_fltregs)(a0)
1064         lfd     fr24,(24*8+offes_fltregs)(a0)
1065         lfd     fr25,(25*8+offes_fltregs)(a0)
1066         lfd     fr26,(26*8+offes_fltregs)(a0)
1067         lfd     fr27,(27*8+offes_fltregs)(a0)
1068         lfd     fr28,(28*8+offes_fltregs)(a0)
1069         lfd     fr29,(29*8+offes_fltregs)(a0)
1070         lfd     fr30,(30*8+offes_fltregs)(a0)
1071         lfd     fr31,(31*8+offes_fltregs)(a0)
1072
1073         /* restore link register */
1074
1075         mtlr    r16
1076         
1077         /* load new pc */
1078
1079         lwz     itmp3,offes_pc(a0)
1080
1081         /* load a0 */
1082         
1083         lwz     a0,(3*8+offes_intregs)(a0)
1084
1085         /* jump to new code */
1086
1087         mtctr   itmp3
1088         bctr
1089
1090 /*********************************************************************/
1091
1092 asm_cacheflush:
1093         add     r4,r3,r4
1094         rlwinm  r3,r3,0,0,26
1095         addi    r4,r4,31
1096         rlwinm  r4,r4,0,0,26
1097         mr      r5,r3
1098 1:
1099         cmplw   r3,r4
1100         bge     0f
1101         dcbst   0,r3
1102         addi    r3,r3,32
1103         b       1b
1104 0:
1105         sync
1106 1:
1107         cmplw   r5,r4
1108         bge     0f
1109         icbi    0,r5
1110         addi    r5,r5,32
1111         b       1b
1112 0:
1113         sync
1114         isync
1115         blr
1116
1117
1118         .align 3
1119 doublezero:
1120         .double 0.0
1121
1122 asm_initialize_thread_stack:
1123         addi r4,r4,-256
1124         stw r3,120(r4)
1125         li r3,0
1126         stw r3,124(r4)
1127         stw r3,0(r4)
1128         stw r3,4(r4)
1129         stw r3,8(r4)
1130         stw r3,12(r4)
1131         stw r3,16(r4)
1132         stw r3,20(r4)
1133         stw r3,24(r4)
1134         stw r3,28(r4)
1135         stw r3,32(r4)
1136         stw r3,36(r4)
1137
1138         stw r3,128(r4)
1139         stw r3,132(r4)
1140         stw r3,136(r4)
1141         stw r3,140(r4)
1142         stw r3,144(r4)
1143         stw r3,148(r4)
1144         stw r3,152(r4)
1145         stw r3,156(r4)
1146
1147         mflr r0
1148         bl 0f
1149 0:
1150         mflr r3
1151         mtlr r0
1152 #if defined(__DARWIN__)
1153         lfd fr0,lo16(doublezero-0b)(r3)
1154 #else
1155         lfd fr0,(doublezero-0b)@l(r3)
1156 #endif
1157
1158         stfd fr0,40(r4)
1159         stfd fr0,48(r4)
1160         stfd fr0,56(r4)
1161         stfd fr0,64(r4)
1162         stfd fr0,72(r4)
1163         stfd fr0,80(r4)
1164         stfd fr0,88(r4)
1165         stfd fr0,96(r4)
1166         stfd fr0,104(r4)
1167         stfd fr0,112(r4)
1168
1169         stfd fr0,160(r4)
1170         stfd fr0,168(r4)
1171         stfd fr0,176(r4)
1172         stfd fr0,184(r4)
1173         stfd fr0,192(r4)
1174         stfd fr0,200(r4)
1175         stfd fr0,208(r4)
1176         stfd fr0,216(r4)
1177
1178         mr r3,r4
1179         blr
1180
1181
1182 asm_perform_threadswitch:
1183         mflr r0
1184         addi r1,r1,-224
1185         stw r0,120(r1)
1186         stw pv,124(r1)
1187         stw r14,0(r1)
1188         stw r15,4(r1)
1189         stw r24,8(r1)
1190         stw r25,12(r1)
1191         stw r26,16(r1)
1192         stw r27,20(r1)
1193         stw r28,24(r1)
1194         stw r29,28(r1)
1195         stw r30,32(r1)
1196         stw r31,36(r1)
1197         stfd fr14,40(r1)
1198         stfd fr15,48(r1)
1199         stfd fr24,56(r1)
1200         stfd fr25,64(r1)
1201         stfd fr26,72(r1)
1202         stfd fr27,80(r1)
1203         stfd fr28,88(r1)
1204         stfd fr29,96(r1)
1205         stfd fr30,104(r1)
1206         stfd fr31,112(r1)
1207
1208         stw r16,128(r1)
1209         stw r17,132(r1)
1210         stw r18,136(r1)
1211         stw r19,140(r1)
1212         stw r20,144(r1)
1213         stw r21,148(r1)
1214         stw r22,152(r1)
1215         stw r23,156(r1)
1216         stfd fr16,160(r1)
1217         stfd fr17,168(r1)
1218         stfd fr18,176(r1)
1219         stfd fr19,184(r1)
1220         stfd fr20,192(r1)
1221         stfd fr21,200(r1)
1222         stfd fr22,208(r1)
1223         stfd fr23,216(r1)
1224
1225         stw r1,0(r3)
1226         stw r1,0(r5)
1227         lwz r1,0(r4)
1228
1229         lwz r0,120(r1)
1230         lwz pv,124(r1)
1231         lwz r14,0(r1)
1232         lwz r15,4(r1)
1233         lwz r24,8(r1)
1234         lwz r25,12(r1)
1235         lwz r26,16(r1)
1236         lwz r27,20(r1)
1237         lwz r28,24(r1)
1238         lwz r29,28(r1)
1239         lwz r30,32(r1)
1240         lwz r31,36(r1)
1241         lfd fr14,40(r1)
1242         lfd fr15,48(r1)
1243         lfd fr24,56(r1)
1244         lfd fr25,64(r1)
1245         lfd fr26,72(r1)
1246         lfd fr27,80(r1)
1247         lfd fr28,88(r1)
1248         lfd fr29,96(r1)
1249         lfd fr30,104(r1)
1250         lfd fr31,112(r1)
1251
1252         lwz r16,128(r1)
1253         lwz r17,132(r1)
1254         lwz r18,136(r1)
1255         lwz r19,140(r1)
1256         lwz r20,144(r1)
1257         lwz r21,148(r1)
1258         lwz r22,152(r1)
1259         lwz r23,156(r1)
1260         lfd fr16,160(r1)
1261         lfd fr17,168(r1)
1262         lfd fr18,176(r1)
1263         lfd fr19,184(r1)
1264         lfd fr20,192(r1)
1265         lfd fr21,200(r1)
1266         lfd fr22,208(r1)
1267         lfd fr23,216(r1)
1268
1269         mtlr r0
1270         addi r1,r1,224
1271         blr
1272
1273
1274 asm_switchstackandcall:
1275         mflr r0
1276         stwu r3,-48(r3)
1277         stw r0,40(r3)
1278         stw r1,44(r3)
1279         stw r1,0(r5)
1280         mr r1,r3
1281
1282         mtctr r4
1283         mr r3,r6
1284         bctrl
1285
1286         lwz r0,40(r1)
1287         mtlr r0
1288         lwz r1,44(r1)
1289         blr
1290
1291
1292 asm_getclassvalues_atomic:
1293 _crit_restart:
1294 _crit_begin:
1295         lwz     r6,offbaseval(r3)
1296         lwz     r7,offdiffval(r3)
1297         lwz     r8,offbaseval(r4)
1298 _crit_end:
1299         stw     r6,offcast_super_baseval(r5)
1300         stw     r7,offcast_super_diffval(r5)
1301         stw     r8,offcast_sub_baseval(r5)
1302         blr
1303
1304         .data
1305
1306 asm_criticalsections:
1307 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1308         .long   _crit_begin
1309         .long   _crit_end
1310         .long   _crit_restart
1311 #endif
1312         .long 0
1313
1314
1315 #if defined(__DARWIN__)
1316
1317 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1318         .align 2
1319 L_builtin_throw_exception$stub:
1320         .indirect_symbol _builtin_throw_exception
1321         mflr r0
1322         bcl 20,31,L00$_builtin_throw_exception
1323 L00$_builtin_throw_exception:
1324         mflr r11
1325         addis r11,r11,ha16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)
1326         mtlr r0
1327         lwzu r12,lo16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)(r11)
1328         mtctr r12
1329         bctr
1330 .data
1331 .lazy_symbol_pointer
1332 L_builtin_throw_exception$lazy_ptr:
1333         .indirect_symbol _builtin_throw_exception
1334         .long dyld_stub_binding_helper
1335
1336
1337 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1338         .align 2
1339 L_exceptions_handle_exception$stub:
1340         .indirect_symbol _exceptions_handle_exception
1341         mflr r0
1342         bcl 20,31,L00$_exceptions_handle_exception
1343 L00$_exceptions_handle_exception:
1344         mflr r11
1345         addis r11,r11,ha16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)
1346         mtlr r0
1347         lwzu r12,lo16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)(r11)
1348         mtctr r12
1349         bctr
1350 .data
1351 .lazy_symbol_pointer
1352 L_exceptions_handle_exception$lazy_ptr:
1353         .indirect_symbol _exceptions_handle_exception
1354         .long dyld_stub_binding_helper
1355
1356
1357 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1358         .align 2
1359 L_stacktrace_create_extern_stackframeinfo$stub:
1360         .indirect_symbol _stacktrace_create_extern_stackframeinfo
1361         mflr r0
1362         bcl 20,31,L00$_stacktrace_create_extern_stackframeinfo
1363 L00$_stacktrace_create_extern_stackframeinfo:
1364         mflr r11
1365         addis r11,r11,ha16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)
1366         mtlr r0
1367         lwzu r12,lo16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)(r11)
1368         mtctr r12
1369         bctr
1370 .data
1371 .lazy_symbol_pointer
1372 L_stacktrace_create_extern_stackframeinfo$lazy_ptr:
1373         .indirect_symbol _stacktrace_create_extern_stackframeinfo
1374         .long dyld_stub_binding_helper
1375
1376
1377 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1378         .align 2
1379 L_jit_compile$stub:
1380         .indirect_symbol _jit_compile
1381         mflr r0
1382         bcl 20,31,L00$_jit_compile
1383 L00$_jit_compile:
1384         mflr r11
1385         addis r11,r11,ha16(L_jit_compile$lazy_ptr - L00$_jit_compile)
1386         mtlr r0
1387         lwzu r12,lo16(L_jit_compile$lazy_ptr - L00$_jit_compile)(r11)
1388         mtctr r12
1389         bctr
1390 .data
1391 .lazy_symbol_pointer
1392 L_jit_compile$lazy_ptr:
1393         .indirect_symbol _jit_compile
1394         .long dyld_stub_binding_helper
1395
1396
1397 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1398         .align 2
1399 L_stacktrace_remove_stackframeinfo$stub:
1400         .indirect_symbol _stacktrace_remove_stackframeinfo
1401         mflr r0
1402         bcl 20,31,L00$_stacktrace_remove_stackframeinfo
1403 L00$_stacktrace_remove_stackframeinfo:
1404         mflr r11
1405         addis r11,r11,ha16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)
1406         mtlr r0
1407         lwzu r12,lo16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)(r11)
1408         mtctr r12
1409         bctr
1410 .data
1411 .lazy_symbol_pointer
1412 L_stacktrace_remove_stackframeinfo$lazy_ptr:
1413         .indirect_symbol _stacktrace_remove_stackframeinfo
1414         .long dyld_stub_binding_helper
1415
1416
1417 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1418         .align 2
1419 L_builtin_asm_get_exceptionptrptr$stub:
1420         .indirect_symbol _builtin_asm_get_exceptionptrptr
1421         mflr r0
1422         bcl 20,31,L00$_builtin_asm_get_exceptionptrptr
1423 L00$_builtin_asm_get_exceptionptrptr:
1424         mflr r11
1425         addis r11,r11,ha16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)
1426         mtlr r0
1427         lwzu r12,lo16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)(r11)
1428         mtctr r12
1429         bctr
1430 .data
1431 .lazy_symbol_pointer
1432 L_builtin_asm_get_exceptionptrptr$lazy_ptr:
1433         .indirect_symbol _builtin_asm_get_exceptionptrptr
1434         .long dyld_stub_binding_helper
1435
1436
1437 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1438         .align 2
1439 L_replace_me$stub:
1440         .indirect_symbol _replace_me
1441         mflr r0
1442         bcl 20,31,L00$_replace_me
1443 L00$_replace_me:
1444         mflr r11
1445         addis r11,r11,ha16(L_replace_me$lazy_ptr - L00$_replace_me)
1446         mtlr r0
1447         lwzu r12,lo16(L_replace_me$lazy_ptr - L00$_replace_me)(r11)
1448         mtctr r12
1449         bctr
1450 .data
1451 .lazy_symbol_pointer
1452 L_replace_me$lazy_ptr:
1453         .indirect_symbol _replace_me
1454         .long dyld_stub_binding_helper
1455
1456 #endif /* defined(__DARWIN__) */
1457
1458
1459 /* Disable exec-stacks, required for Gentoo ***********************************/
1460
1461 #if defined(__GCC__) && defined(__ELF__)
1462         .section .note.GNU-stack,"",@progbits
1463 #endif
1464
1465
1466 /*
1467  * These are local overrides for various environment variables in Emacs.
1468  * Please do not remove this and leave it at the end of the file, where
1469  * Emacs will automagically detect them.
1470  * ---------------------------------------------------------------------
1471  * Local variables:
1472  * mode: asm
1473  * indent-tabs-mode: t
1474  * c-basic-offset: 4
1475  * tab-width: 4
1476  * End:
1477  * vim:noexpandtab:sw=4:ts=4:
1478  */