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