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