* Newer, simpler stacktrace system
[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 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Stefan Ring
30
31    Changes: Christian Thalinger
32
33    $Id: asmpart.S 2997 2005-07-12 08:39:17Z twisti $
34
35 */
36
37
38 #include "config.h"
39 #include "md-abi.h"
40 #include "md-asm.h"
41
42 #include "vm/jit/powerpc/offsets.h"
43 #include "vm/jit/powerpc/asmoffsets.h"
44
45
46         .text
47
48         .align 2
49
50         .globl asm_calljavafunction
51         .globl asm_calljavafunction_int
52
53         .globl asm_calljavafunction2
54         .globl asm_calljavafunction2int
55         .globl asm_calljavafunction2long
56         .globl asm_calljavafunction2float
57         .globl asm_calljavafunction2double
58
59         .globl asm_call_jit_compiler
60
61         .globl asm_handle_nat_exception
62         .globl asm_handle_exception
63
64         .globl asm_wrapper_patcher
65
66         .globl asm_cacheflush
67         .globl asm_initialize_thread_stack
68         .globl asm_perform_threadswitch
69         .globl asm_switchstackandcall
70         .globl asm_criticalsections
71         .globl asm_getclassvalues_atomic
72
73
74 /********************* function asm_calljavafunction ***************************
75 *                                                                              *
76 *   This function calls a Java-method (which possibly needs compilation)       *
77 *   with up to 4 address parameters.                                           *
78 *                                                                              *
79 *   This functions calls the JIT-compiler which eventually translates the      *
80 *   method into machine code.                                                  *
81 *                                                                              *
82 *   C-prototype:                                                               *
83 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
84 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
85 *                                                                              *
86 *******************************************************************************/
87                 
88         .align 2
89
90         .long   0                         /* catch type all                       */
91         .long   calljava_xhandler         /* handler pc                           */
92         .long   calljava_xhandler         /* end pc                               */
93         .long   asm_calljavafunction      /* start pc                             */
94         .long   1                         /* extable size                         */
95         .long   0                         /* line number table start              */
96         .long   0                         /* line number table size               */
97         .long   0                         /* fltsave                              */
98         .long   0                         /* intsave                              */
99         .long   0                         /* isleaf                               */
100         .long   0                         /* IsSync                               */
101         .long   24                        /* frame size                           */
102         .long   0                         /* method pointer (pointer to name)     */
103
104 asm_calljavafunction:
105 asm_calljavafunction_int:
106         mflr    r0
107         stw     r31,-4(r1)
108 /*      stw     r30,-8(r1)*/
109         stw     pv,-12(r1)
110         stw     r0,LA_LR_OFFSET(r1)
111         stwu    r1,-148(r1)
112
113 #if defined(__DARWIN__)
114         bl      0f
115 0:
116         mflr    r31
117 #endif
118
119         stw     t0,40(r1)
120         stw     t1,44(r1)
121         stw     t2,48(r1)
122         stw     t3,52(r1)
123         stw     t4,56(r1)
124         stw     t5,60(r1)
125         stw     t6,64(r1)
126         stw     t7,68(r1)
127
128         stfd    ftmp1,72(r1)
129         stfd    ftmp2,80(r1)
130         stfd    ft0,88(r1)
131         stfd    ft1,96(r1)
132         stfd    ft2,104(r1)
133         stfd    ft3,112(r1)
134         stfd    ft4,120(r1)
135         stfd    ft5,128(r1)
136
137         stw     a0,36(r1)
138         addi    itmp1,r1,36
139         mr      a0,a1
140         mr      a1,a2
141         mr      a2,a3
142         mr      a3,a4
143
144 #if defined(__DARWIN__)
145 /*      addis   mptr,r31,ha16(_asm_call_jit_compiler-0b)*/
146         addi    mptr,r31,lo16(asm_call_jit_compiler-0b)
147 #else
148 /*      addi    mptr,r31,(asm_call_jit_compiler-0b)@l*/
149         lis     mptr,asm_call_jit_compiler@ha
150         addi    mptr,mptr,asm_call_jit_compiler@l
151 #endif
152         stw     mptr,32(r1)
153         addi    mptr,r1,28
154
155         lwz     pv,4(mptr)
156         mtctr   pv
157         bctrl
158
159 1:
160         mflr    itmp1
161 #if defined(__DARWIN__)
162         addi    pv,itmp1,lo16(asm_calljavafunction-1b)
163 #else
164         addi    pv,itmp1,(asm_calljavafunction-1b)@l
165 #endif
166
167 calljava_regrestore:
168         lwz     t0,40(r1)
169         lwz     t1,44(r1)
170         lwz     t2,48(r1)
171         lwz     t3,52(r1)
172         lwz     t4,56(r1)
173         lwz     t5,60(r1)
174         lwz     t6,64(r1)
175         lwz     t7,68(r1)
176
177         lfd     ftmp1,72(r1)
178         lfd     ftmp2,80(r1)
179         lfd     ft0,88(r1)
180         lfd     ft1,96(r1)
181         lfd     ft2,104(r1)
182         lfd     ft3,112(r1)
183         lfd     ft4,120(r1)
184         lfd     ft5,128(r1)
185
186         lwz     r0,148+LA_LR_OFFSET(r1)
187         mtlr    r0
188         addi    r1,r1,148
189         lwz     pv,-12(r1)
190 /*      lwz     r30,-8(r1)*/
191         lwz     r31,-4(r1)
192         blr
193
194 calljava_xhandler:
195         mr      r3,itmp1
196         bl      builtin_throw_exception
197         li      v0,0                      /* return NULL                          */
198         b       calljava_regrestore
199
200
201
202
203         .align 2
204
205         .long   0                         /* catch type all                       */
206         .long   calljava_xhandler2        /* handler pc                           */
207         .long   calljava_xhandler2        /* end pc                               */
208         .long   asm_calljavafunction2     /* start pc                             */
209         .long   1                         /* extable size                         */
210         .long   0                         /* line number table start              */
211         .long   0                         /* line number table size               */
212         .long   0                         /* fltsave                              */
213         .long   0                         /* intsave                              */
214         .long   0                         /* isleaf                               */
215         .long   0                         /* IsSync                               */
216         .long   24                        /* frame size                           */
217         .long   0                         /* method pointer (pointer to name)     */
218
219 asm_calljavafunction2:
220 asm_calljavafunction2int:
221 asm_calljavafunction2long:
222 asm_calljavafunction2float:
223 asm_calljavafunction2double:
224         mflr    r0
225         stw     r31,-4(r1)
226 /*      stw     r30,-8(r1)*/
227         stw     pv,-12(r1)
228         stw     r0,LA_LR_OFFSET(r1)
229         stwu    r1,-148(r1)
230         bl      0f
231 0:
232         mflr    r31
233
234         stw     r16,40(r1)
235         stw     r17,44(r1)
236         stw     r18,48(r1)
237         stw     r19,52(r1)
238         stw     r20,56(r1)
239         stw     r21,60(r1)
240         stw     r22,64(r1)
241         stw     r23,68(r1)
242         stfd    fr16,72(r1)
243         stfd    fr17,80(r1)
244         stfd    fr18,88(r1)
245         stfd    fr19,96(r1)
246         stfd    fr20,104(r1)
247         stfd    fr21,112(r1)
248         stfd    fr22,120(r1)
249         stfd    fr23,128(r1)
250
251         stw     r3,36(r1)                 /* save method pointer for compiler     */
252         mr      itmp1,r6                  /* pointer to arg block                 */
253         mr      itmp2,r4                  /* arg count                            */
254
255         mr.     itmp2,itmp2
256         ble     calljava_argsloaded
257
258         addi    itmp2,itmp2,-1
259         lwz     r3,offjniitem+4(itmp1)
260         mr.     itmp2,itmp2
261         ble     calljava_argsloaded
262
263         addi    itmp2,itmp2,-1
264         lwz     r4,offjniitem+sizejniblock*1+4(itmp1)
265         mr.     itmp2,itmp2
266         ble     calljava_argsloaded
267         addi    itmp2,itmp2,-1
268
269         addi    itmp2,itmp2,-1
270         lwz     r5,offjniitem+sizejniblock*2+4(itmp1)
271         mr.     itmp2,itmp2
272         ble     calljava_argsloaded
273         addi    itmp2,itmp2,-1
274
275         addi    itmp2,itmp2,-1
276         lwz     r6,offjniitem+sizejniblock*3+4(itmp1)
277         mr.     itmp2,itmp2
278         ble     calljava_argsloaded
279         addi    itmp2,itmp2,-1
280
281 calljava_argsloaded:
282         addi    itmp1,r1,36
283 #if defined(__DARWIN__)
284 /*      addis   mptr,r31,ha16(_asm_call_jit_compiler-0b)*/
285         addi    mptr,r31,lo16(asm_call_jit_compiler-0b)
286 #else
287         addi    mptr,r31,(asm_call_jit_compiler-0b)@l
288 #endif
289         stw     mptr,32(r1)
290         addi    mptr,r1,28
291
292         lwz     pv,4(mptr)
293         mtctr   pv
294         bctrl
295 1:
296         mflr    itmp1
297 #if defined(__DARWIN__)
298         addi    pv,itmp1,lo16(asm_calljavafunction2-1b)
299 #else
300         addi    pv,itmp1,(asm_calljavafunction2-1b)@l
301 #endif
302
303 calljava_regrestore2:
304         lwz     r16,40(r1)
305         lwz     r17,44(r1)
306         lwz     r18,48(r1)
307         lwz     r19,52(r1)
308         lwz     r20,56(r1)
309         lwz     r21,60(r1)
310         lwz     r22,64(r1)
311         lwz     r23,68(r1)
312         lfd     fr16,72(r1)
313         lfd     fr17,80(r1)
314         lfd     fr18,88(r1)
315         lfd     fr19,96(r1)
316         lfd     fr20,104(r1)
317         lfd     fr21,112(r1)
318         lfd     fr22,120(r1)
319         lfd     fr23,128(r1)
320
321         lwz     r0,148+LA_LR_OFFSET(r1)
322         mtlr    r0
323         addi    r1,r1,148
324         lwz     pv,-12(r1)
325 /*      lwz     r30,-8(r1)*/
326         lwz     r31,-4(r1)
327         blr
328
329 calljava_xhandler2:
330         mr      r3,itmp1
331         bl      builtin_throw_exception
332         li      v0,0                      /* return NULL                          */
333         b       calljava_regrestore2
334
335
336 /* asm_call_jit_compiler *******************************************************
337
338    Invokes the compiler for untranslated JavaVM methods.
339
340 *******************************************************************************/
341
342 asm_call_jit_compiler:
343         stw     itmp1,-8(r1)
344         mflr    itmp1
345         stw     r31,-4(r1)
346         stw     r29,-12(r1)
347         stw     itmp1,LA_LR_OFFSET(r1)
348         stwu    r1,-(LA_SIZE + 1*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)(r1)
349         mr      r31,pv
350
351         lwz     itmp3,-12(itmp1)
352         srwi    itmp3,itmp3,16
353         andi.   itmp3,itmp3,31
354         cmpwi   itmp3,mptrn
355         beq     noregchange
356         lwz     itmp3,4(itmp1)
357         extsh   itmp3,itmp3
358         add     mptr,itmp3,itmp1
359         lwz     itmp3,8(itmp1)
360         srwi    itmp3,itmp3,16
361         cmpwi   itmp3,0x3dad
362         bne     noregchange
363         lwz     itmp3,8(itmp1)
364         slwi    itmp3,itmp3,16
365         add     mptr,mptr,itmp3
366                 
367 noregchange:
368         lwz     itmp1,(LA_SIZE + 1*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
369         mr      r29,mptr                    /* save method pointer                */
370
371 #if defined(__DARWIN__)
372         stw     a0,28(r1)
373         stw     a1,32(r1)
374         stw     a2,36(r1)
375         stw     a3,40(r1)
376         stw     a4,44(r1)
377         stw     a5,48(r1)
378         stw     a6,52(r1)
379         stw     a7,56(r1)
380
381         stfd    fa0,60(r1)
382         stfd    fa1,68(r1)
383         stfd    fa2,76(r1)
384         stfd    fa3,84(r1)
385         stfd    fa4,92(r1)
386         stfd    fa5,100(r1)
387         stfd    fa6,108(r1)
388         stfd    fa7,116(r1)
389         stfd    fa8,124(r1)
390         stfd    fa9,132(r1)
391         stfd    fa10,140(r1)
392         stfd    fa11,148(r1)
393         stfd    fa12,156(r1)
394 #else
395         SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE + 1)
396 #endif
397
398         lwz     r3,0(itmp1)
399         bl      jit_compile
400         mr      pv,r3
401
402         mr      mptr,r29                    /* restore method pointer             */
403
404 #if defined(__DARWIN__)
405         lwz     a0,28(r1)
406         lwz     a1,32(r1)
407         lwz     a2,36(r1)
408         lwz     a3,40(r1)
409         lwz     a4,44(r1)
410         lwz     a5,48(r1)
411         lwz     a6,52(r1)
412         lwz     a7,56(r1)
413
414         lfd     fa0,60(r1)
415         lfd     fa1,68(r1)
416         lfd     fa2,76(r1)
417         lfd     fa3,84(r1)
418         lfd     fa4,92(r1)
419         lfd     fa5,100(r1)
420         lfd     fa6,108(r1)
421         lfd     fa7,116(r1)
422         lfd     fa8,124(r1)
423         lfd     fa9,132(r1)
424         lfd     fa10,140(r1)
425         lfd     fa11,148(r1)
426         lfd     fa12,156(r1)
427 #else
428         RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE + 1)
429 #endif
430
431         lwz     itmp1,(LA_SIZE + 1*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+LA_LR_OFFSET(r1)
432         lwz     r0,(LA_SIZE + 1*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+LA_LR_OFFSET(r1)
433         mtlr    r0
434         addi    r1,r1,(LA_SIZE + 1*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
435
436         mr.     pv,pv                       /* test for exception                 */
437         beq     L_asm_call_jit_compiler_exception
438
439         lwz     itmp3,-12(itmp1)
440         extsh   itmp3,itmp3
441         add     mptr,mptr,itmp3
442         stw     pv,0(mptr)
443
444         mtctr   pv
445
446         lwz     r29,-12(r1)
447 /*      lwz     pv,-8(r1)*/
448         lwz     r31,-4(r1)
449         bctr
450
451 L_asm_call_jit_compiler_exception:
452         mflr    r0
453         stw     r0,LA_LR_OFFSET(r1)
454         stwu    r1,-(LA_SIZE+4*4)(r1)
455
456         li      a0,0                        /* fill in correct stacktrace         */
457         addi    a1,r1,LA_SIZE+4*4           /* pass sp of parent Java function    */
458         mr      a2,r0                       /* pass ra of parent Java function    */
459         mr      a3,a2                       /* xpc is equal to ra                 */
460         bl      stacktrace_extern_fillInStackTrace
461         mr      xptr,v0
462
463         lwz     r0,LA_SIZE+4*4+LA_LR_OFFSET(r1)
464         mtlr    r0
465         addi    r1,r1,LA_SIZE+4*4
466
467         mr      xpc,r0                      /* we can not use r0 in addi (it's 0) */
468         addi    xpc,xpc,-4
469         b       asm_handle_nat_exception
470
471
472 /********************* function asm_handle_exception ***************************
473 *                                                                              *
474 *   This function handles an exception. It does not use the usual calling      *
475 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
476 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
477 *   the local exception table for a handler. If no one is found, it unwinds    *
478 *   stacks and continues searching the callers.                                *
479 *                                                                              *
480 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
481 *                                                                              *
482 *******************************************************************************/
483                 
484 asm_handle_nat_exception:
485         mflr    r9
486         lwz     itmp3,4(r9)
487         extsh   itmp3,itmp3
488         add     pv,itmp3,r9
489         lwz     itmp3,8(r9)
490         srwi    itmp3,itmp3,16
491         cmpwi   itmp3,0x3dad
492         bne     asm_handle_exception
493         lwz     itmp3,8(r9)
494         slwi    itmp3,itmp3,16
495         add     pv,pv,itmp3
496
497 asm_handle_exception:
498         addi    r1,r1,-18*4
499         stw     r0,0*4(r1)
500         stw     r2,1*4(r1)
501         stw     r3,2*4(r1)
502         stw     r4,3*4(r1)
503         stw     r5,4*4(r1)
504         stw     r6,5*4(r1)
505         stw     r7,6*4(r1)
506         stw     r8,7*4(r1)
507         stw     r9,8*4(r1)
508         stw     r10,9*4(r1)
509         stw     r16,10*4(r1)
510         stw     r17,11*4(r1)
511         stw     r18,12*4(r1)
512         stw     r19,13*4(r1)
513         stw     r20,14*4(r1)
514         stw     r21,15*4(r1)
515         stw     r22,16*4(r1)
516         stw     r23,17*4(r1)
517
518         li      r9,1
519 ex_stack_loop:
520         addi    r1,r1,-4*4            /* allocate stack                           */
521         stw     xptr,0*4(r1)          /* save used register                       */
522         stw     xpc,1*4(r1)
523         mflr    xptr
524         stw     xptr,2*4(r1)
525         stw     r9,3*4(r1)
526
527         lwz     r3,0*4(r1)            /* exception pointer                        */
528         lwz     r4,MethodPointer(pv)  /* method pointer                           */
529         mr      r5,xpc                /* exception pc                             */
530 /*      mr      r6,r9 */
531         li      r6,0                  /* line number                              */
532         li      r7,4                  /* set no unwind flag                       */
533
534         /* XXX no valid stack frame chaining here */
535         addi    r1,r1,-(24+5*4)       /* 24 linkage area + 5 argument * 4         */
536         bl      builtin_trace_exception
537         addi    r1,r1,(24+5*4)
538
539         lwz     xptr,2*4(r1)
540         mtlr    xptr
541         lwz     xptr,0*4(r1)          /* restore xptr                             */
542         lwz     xpc,1*4(r1)
543         lwz     r9,3*4(r1)
544         addi    r1,r1,4*4
545
546         lwz     r3,ExTableSize(pv)    /* r3 = exception table size                */
547         mr.     r3,r3                 /* if empty table skip                      */
548         beq     empty_table
549
550         addi    r4,pv,ExTableStart    /* r4 = start of exception table            */
551
552 ex_table_loop:
553         lwz     r5,ExStartPC(r4)      /* r5 = exception start pc                  */
554         cmplw   r5,xpc                /* (startpc <= xpc)                         */
555         bgt     ex_table_cont
556         lwz     r5,ExEndPC(r4)        /* r5 = exception end pc                    */
557         cmplw   xpc,r5                /* (xpc < endpc)                            */
558         bge     ex_table_cont
559         lwz     r7,ExCatchType(r4)    /* r7 = exception catch type                */
560         mr.     r7,r7
561         beq     ex_handle_it
562
563         lwz     itmp3,offclassloaded(r7)
564         mr.     itmp3,itmp3
565         bne     L_class_loaded
566
567         /* XXX no valid stack frame chaining here */
568         addi    r1,r1,-16*4           /* allocate stack                           */
569         stw     r3,7*4(r1)            /* save used registers                      */
570         stw     r4,8*4(r1)            /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save)  */
571         stw     r9,9*4(r1)
572         stw     xptr,10*4(r1)
573         stw     xpc,11*4(r1)
574         mflr    xptr
575         stw     xptr,12*4(r1)
576         stw     r7,13*4(r1)
577
578         mr      r3,r7                 /* arg1 = exceptionclass                    */
579         bl      load_class_bootstrap
580
581         lwz     r3,7*4(r1)
582         lwz     r4,8*4(r1)
583         lwz     r9,9*4(r1)
584         lwz     xptr,10*4(r1)
585         lwz     xpc,11*4(r1)
586         lwz     itmp3,12*4(r1)
587         mtlr    itmp3
588         lwz     r7,13*4(r1)     
589         addi    r1,r1,16*4
590
591 L_class_loaded:
592         lwz     itmp3,offclasslinked(r7)
593         mr.     itmp3,itmp3
594         /* XXX no valid stack frame chaining here */
595         addi    r1,r1,-16*4           /* allocate stack                           */
596         stw     r7,13*4(r1)
597         bne     L_class_linked
598
599         stw     r3,7*4(r1)            /* save used registers                      */
600         stw     r4,8*4(r1)            /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save)  */
601         stw     r9,9*4(r1)
602         stw     xptr,10*4(r1)
603         stw     xpc,11*4(r1)
604         mflr    xptr
605         stw     xptr,12*4(r1)
606
607         mr      r3,r7                 /* arg1 = exceptionclass                    */
608         bl      link_class
609
610         lwz     r3,7*4(r1)
611         lwz     r4,8*4(r1)
612         lwz     r9,9*4(r1)
613         lwz     xptr,10*4(r1)
614         lwz     xpc,11*4(r1)
615         lwz     itmp3,12*4(r1)
616         mtlr    itmp3
617
618 L_class_linked:
619 _crit_restart1:
620         lwz     r7,13*4(r1)
621 _crit_begin1:
622         lwz     r6,offobjvftbl(xptr)  /* r6 = vftblptr(xptr)                      */
623         lwz     r7,offclassvftbl(r7)  /* r7 = vftblptr(catchtype) class (not obj) */
624         lwz     r6,offbaseval(r6)     /* r6 = baseval(xptr)                       */
625         lwz     r8,offbaseval(r7)     /* r8 = baseval(catchtype)                  */
626         lwz     r7,offdiffval(r7)     /* r7 = diffval(catchtype)                  */
627 _crit_end1:
628         subf    r6,r8,r6              /* r6 = baseval(xptr) - baseval(catchtype)  */
629         cmplw   r6,r7                 /* xptr is instanceof catchtype             */
630         addi    r1,r1,16*4
631         bgt     ex_table_cont         /* if (false) continue                      */
632
633 ex_handle_it:
634         lwz     xpc,ExHandlerPC(r4)   /* xpc = exception handler pc               */
635         mr.     r9,r9
636         beq     ex_jump
637
638         lwz     r0,0*4(r1)
639         lwz     r2,1*4(r1)
640         lwz     r3,2*4(r1)
641         lwz     r4,3*4(r1)
642         lwz     r5,4*4(r1)
643         lwz     r6,5*4(r1)
644         lwz     r7,6*4(r1)
645         lwz     r8,7*4(r1)
646         lwz     r9,8*4(r1)
647         lwz     r10,9*4(r1)
648         lwz     r16,10*4(r1)
649         lwz     r17,11*4(r1)
650         lwz     r18,12*4(r1)
651         lwz     r19,13*4(r1)
652         lwz     r20,14*4(r1)
653         lwz     r21,15*4(r1)
654         lwz     r22,16*4(r1)
655         lwz     r23,17*4(r1)
656         addi    r1,r1,18*4
657
658 ex_jump:
659         mtctr   xpc
660         bctr
661
662 ex_table_cont:
663         addi    r4,r4,ExEntrySize     /* next exception table entry               */
664         addic.  r3,r3,-1              /* decrement entry counter                  */
665         bgt     ex_table_loop         /* if (t0 > 0) next entry                   */
666
667 empty_table:
668         mr.     r9,r9                 /* if here the first time, then             */
669         beq     ex_already_cleared
670         addi    r1,r1,18*4            /* deallocate stack and                     */
671         li      r9,0                  /* clear the no unwind flag                 */
672 ex_already_cleared:
673         lwz     r3,IsSync(pv)         /* t0 = SyncOffset                          */
674         mr.     r3,r3
675         beq     no_monitor_exit       /* if zero no monitorexit                   */
676
677 #if defined(USE_THREADS)
678         add     r3,r1,r3
679         lwz     r6,-4(r3)
680
681         addi    r1,r1,-6*4
682         stw     r3,0*4(r1)
683         stw     r4,1*4(r1)
684         stw     r9,2*4(r1)
685         stw     xptr,3*4(r1)
686         stw     xpc,4*4(r1)
687         mflr    xptr
688         stw     xptr,5*4(r1)
689
690         mr      r3,r6
691         /* XXX no valid stack frame chaining here */
692         addi    r1,r1,-40
693         bl      builtin_monitorexit
694         addi    r1,r1,40
695
696         lwz     xptr,5*4(r1)
697         mtlr    xptr
698         lwz     r3,0*4(r1)
699         lwz     r4,1*4(r1)
700         lwz     r9,2*4(r1)
701         lwz     xptr,3*4(r1)
702         lwz     xpc,4*4(r1)
703         addi    r1,r1,6*4
704 #endif
705
706 no_monitor_exit:
707         lwz     r3,FrameSize(pv)      /* r3 = frame size                          */
708         add     r1,r1,r3              /* unwind stack                             */
709         mr      r3,r1                 /* r3 = pointer to save area                */
710         lwz     r4,IsLeaf(pv)         /* r4 = is leaf procedure                   */
711         mr.     r4,r4
712         bne     ex_no_restore         /* if (leaf) skip                           */
713         lwz     r4,LA_LR_OFFSET(r3)   /* restore ra                               */
714         mtlr    r4                    /* t0--                                     */
715 ex_no_restore:
716         mflr    r4                    /* the new xpc is ra                        */
717         mr      xpc,r4
718         lwz     r4,IntSave(pv)        /* r4 = saved int register count            */
719         bl      ex_int1
720 ex_int1:
721         mflr    r5
722 #if defined(__DARWIN__)
723         addi    r5,r5,lo16(ex_int2-ex_int1)
724 #else
725         addi    r5,r5,(ex_int2-ex_int1)@l
726 #endif
727         slwi    r4,r4,2
728         subf    r5,r4,r5
729         mtctr   r5
730         bctr
731         lwz     s0,-40(r3)
732         lwz     s1,-36(r3)
733         lwz     s2,-32(r3)
734         lwz     s3,-28(r3)
735         lwz     s4,-24(r3)
736         lwz     s5,-20(r3)
737         lwz     s6,-16(r3)
738         lwz     s7,-12(r3)
739         lwz     s8,-8(r3)
740         lwz     s9,-4(r3)
741
742 ex_int2:
743         subf    r3,r4,r3
744
745         lwz     r4,FltSave(pv)
746         bl      ex_flt1
747 ex_flt1:
748         mflr    r5
749 #if defined(__DARWIN__)
750         addi    r5,r5,lo16(ex_flt2-ex_flt1)
751 #else
752         addi    r5,r5,(ex_flt2-ex_flt1)@l
753 #endif
754         slwi    r4,r4,2
755         subf    r5,r4,r5
756         mtctr   r5
757         bctr
758         lfd     fs0,-80(r3)
759         lfd     fs1,-72(r3)
760         lfd     fs2,-64(r3)
761         lfd     fs3,-56(r3)
762         lfd     fs4,-48(r3)
763         lfd     fs5,-40(r3)
764         lfd     fs6,-32(r3)
765         lfd     fs7,-24(r3)
766         lfd     fs8,-16(r3)
767         lfd     fs9,-8(r3)
768
769 ex_flt2:
770         mtlr    xpc
771         lwz     itmp3,4(xpc)
772         extsh   itmp3,itmp3
773         add     pv,itmp3,xpc
774         lwz     itmp3,8(xpc)
775         srwi    itmp3,itmp3,16
776         cmpwi   itmp3,0x3dad
777         bne     ex_stack_loop
778         lwz     itmp3,8(xpc)
779         slwi    itmp3,itmp3,16
780         add     pv,pv,itmp3
781         b       ex_stack_loop
782
783
784 /* asm_wrapper_patcher *********************************************************
785
786    XXX
787
788    Stack layout:
789      16   return address into JIT code (patch position)
790      12   pointer to virtual java_objectheader
791       8   machine code (which is patched back later)
792       4   unresolved class/method/field reference
793       0   patcher function pointer to call (pv is saved here afterwards)
794
795 *******************************************************************************/
796
797 asm_wrapper_patcher:
798         mflr    r0
799         stw     r0,8*4+LA_LR_OFFSET(r1) /* skip stack frame of patcher stub       */
800                                       /* keep stack 16-bytes aligned: 6+1+37 = 44 */
801         stwu    r1,-(LA_SIZE+(5+38)*4+sizestackframeinfo)(r1)
802
803 #if 1
804         stw     a0,LA_SIZE+(5+0)*4(r1)  /* save argument registers                */
805         stw     a1,LA_SIZE+(5+1)*4(r1)        /* preserve linkage area (24 bytes)       */
806         stw     a2,LA_SIZE+(5+2)*4(r1)        /* and 4 bytes for 4 argument             */
807         stw     a3,LA_SIZE+(5+3)*4(r1)
808         stw     a4,LA_SIZE+(5+4)*4(r1)
809         stw     a5,LA_SIZE+(5+5)*4(r1)
810         stw     a6,LA_SIZE+(5+6)*4(r1)
811         stw     a7,LA_SIZE+(5+7)*4(r1)
812
813         stfd    fa0,LA_SIZE+(5+8)*4(sp)
814         stfd    fa1,LA_SIZE+(5+10)*4(sp)
815         stfd    fa2,LA_SIZE+(5+12)*4(sp)
816         stfd    fa3,LA_SIZE+(5+14)*4(sp)
817         stfd    fa4,LA_SIZE+(5+16)*4(sp)
818         stfd    fa5,LA_SIZE+(5+18)*4(sp)
819         stfd    fa6,LA_SIZE+(5+20)*4(sp)
820         stfd    fa7,LA_SIZE+(5+22)*4(sp)
821         stfd    fa8,LA_SIZE+(5+24)*4(sp)
822         stfd    fa9,LA_SIZE+(5+26)*4(sp)
823         stfd    fa10,LA_SIZE+(5+28)*4(sp)
824         stfd    fa11,LA_SIZE+(5+30)*4(sp)
825         stfd    fa12,LA_SIZE+(5+32)*4(sp)
826 #else
827         SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/13 float arguments  */
828 #endif
829
830 #if 0
831         stw     r2,25*8(r1)
832         stw     r16,26*8(r1)
833         stw     r17,27*8(r1)
834         stw     r18,28*8(r1)
835         stw     r19,29*8(r1)
836         stw     r20,30*8(r1)
837         stw     r21,31*8(r1)
838         stw     r22,32*8(r1)
839         stw     r23,33*8(r1)
840 #endif
841
842         stw     itmp1,LA_SIZE+(5+34)*4(sp)
843         stw     itmp2,LA_SIZE+(5+35)*4(sp)
844         stw     pv,LA_SIZE+(5+36)*4(sp)
845
846         addi    a0,sp,LA_SIZE+(5+38)*4      /* create stackframe info             */
847         mr      a1,pv
848         addi    a2,sp,(8+LA_WORD_SIZE+5+38)*4+sizestackframeinfo
849         mr      a3,r0                       /* this is correct for leafs          */
850         mr      a4,a3                       /* pass xpc                           */
851         bl      stacktrace_create_extern_stackframeinfo
852
853         addi    a0,sp,(0+LA_WORD_SIZE+5+38)*4+sizestackframeinfo  /* pass sp      */
854         lwz     pv,(0+LA_WORD_SIZE+5+38)*4+sizestackframeinfo(sp) /* get function */
855         lwz     itmp1,LA_SIZE+(5+36)*4(sp)  /* move pv to position of fp          */
856         stw     itmp1,(0+LA_WORD_SIZE+5+38)*4+sizestackframeinfo(sp)
857         mtctr   pv                          /* call the patcher function          */
858         bctrl
859         stw     r3,LA_SIZE+(5+37)*4(sp)     /* save return value                  */
860
861         addi    a0,sp,LA_SIZE+(5+38)*4
862         bl      stacktrace_remove_stackframeinfo /* remove stackframe info        */
863
864         lwz     itmp3,LA_SIZE+(5+37)*4(sp)  /* restore return value into temp reg.*/
865
866 #if 1
867         lwz     a0,LA_SIZE+(5+0)*4(r1)
868         lwz     a1,LA_SIZE+(5+1)*4(r1)
869         lwz     a2,LA_SIZE+(5+2)*4(r1)
870         lwz     a3,LA_SIZE+(5+3)*4(r1)
871         lwz     a4,LA_SIZE+(5+4)*4(r1)
872         lwz     a5,LA_SIZE+(5+5)*4(r1)
873         lwz     a6,LA_SIZE+(5+6)*4(r1)
874         lwz     a7,LA_SIZE+(5+7)*4(r1)
875
876         lfd     fa0,LA_SIZE+(5+8)*4(sp)
877         lfd     fa1,LA_SIZE+(5+10)*4(sp)
878         lfd     fa2,LA_SIZE+(5+12)*4(sp)
879         lfd     fa3,LA_SIZE+(5+14)*4(sp)
880         lfd     fa4,LA_SIZE+(5+16)*4(sp)
881         lfd     fa5,LA_SIZE+(5+18)*4(sp)
882         lfd     fa6,LA_SIZE+(5+20)*4(sp)
883         lfd     fa7,LA_SIZE+(5+22)*4(sp)
884         lfd     fa8,LA_SIZE+(5+24)*4(sp)
885         lfd     fa9,LA_SIZE+(5+26)*4(sp)
886         lfd     fa10,LA_SIZE+(5+28)*4(sp)
887         lfd     fa11,LA_SIZE+(5+30)*4(sp)
888         lfd     fa12,LA_SIZE+(5+32)*4(sp)
889 #else
890         RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+4)/* restore 8 int/13 float args  */
891 #endif
892
893 #if 0
894         lwz     r2,25*8(r1)
895         lwz     r16,26*8(r1)
896         lwz     r17,27*8(r1)
897         lwz     r18,28*8(r1)
898         lwz     r19,29*8(r1)
899         lwz     r20,30*8(r1)
900         lwz     r21,31*8(r1)
901         lwz     r22,32*8(r1)
902         lwz     r23,33*8(r1)            
903 #endif
904
905                                       /* get return address (into JIT code)       */
906         lwz     itmp1,(4+LA_WORD_SIZE+5+38)*4+sizestackframeinfo(sp)
907         mtlr    itmp1
908
909         lwz     itmp1,LA_SIZE+(5+34)*4(sp)
910         lwz     itmp2,LA_SIZE+(5+35)*4(sp)
911         lwz     pv,LA_SIZE+(5+36)*4(sp)
912
913                                       /* remove stack frame + patcher stub stack  */
914         addi    r1,r1,(8+LA_WORD_SIZE+5+38)*4+sizestackframeinfo
915
916         mr.     itmp3,itmp3           /* check for an exception                   */
917         beq     L_asm_wrapper_patcher_exception
918
919         blr                           /* jump to new patched code                 */
920
921 L_asm_wrapper_patcher_exception:
922 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
923         mflr    r0
924         stw     r0,LA_LR_OFFSET(r1)
925         stwu    r1,-LA_SIZE_ALIGNED(r1) /* preserve linkage area                  */
926         bl      builtin_asm_get_exceptionptrptr
927         lwz     r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(r1)
928         mtlr    r0      
929         addi    r1,r1,LA_SIZE_ALIGNED
930 #else
931 # if defined(__DARWIN__)
932         lwz     v0,lo16(_exceptionptr-0b)(pv)
933 # else
934         lis     v0,_exceptionptr@ha
935         addi    v0,v0,_exceptionptr@l
936 # endif
937 #endif
938
939         lwz     xptr,0(v0)            /* get the exception pointer                */
940         li      itmp3,0
941         stw     itmp3,0(v0)           /* clear the exception pointer              */
942
943         mflr    xpc
944         b       asm_handle_exception
945
946
947 asm_cacheflush:
948         add     r4,r3,r4
949         rlwinm  r3,r3,0,0,26
950         addi    r4,r4,31
951         rlwinm  r4,r4,0,0,26
952         mr      r5,r3
953 1:
954         cmplw   r3,r4
955         bge     0f
956         dcbst   0,r3
957         addi    r3,r3,32
958         b       1b
959 0:
960         sync
961 1:
962         cmplw   r5,r4
963         bge     0f
964         icbi    0,r5
965         addi    r5,r5,32
966         b       1b
967 0:
968         sync
969         isync
970         blr
971
972
973         .align 3
974 doublezero:
975         .double 0.0
976
977 asm_initialize_thread_stack:
978         addi r4,r4,-256
979         stw r3,120(r4)
980         li r3,0
981         stw r3,124(r4)
982         stw r3,0(r4)
983         stw r3,4(r4)
984         stw r3,8(r4)
985         stw r3,12(r4)
986         stw r3,16(r4)
987         stw r3,20(r4)
988         stw r3,24(r4)
989         stw r3,28(r4)
990         stw r3,32(r4)
991         stw r3,36(r4)
992
993         stw r3,128(r4)
994         stw r3,132(r4)
995         stw r3,136(r4)
996         stw r3,140(r4)
997         stw r3,144(r4)
998         stw r3,148(r4)
999         stw r3,152(r4)
1000         stw r3,156(r4)
1001
1002         mflr r0
1003         bl 0f
1004 0:
1005         mflr r3
1006         mtlr r0
1007 #if defined(__DARWIN__)
1008         lfd fr0,lo16(doublezero-0b)(r3)
1009 #else
1010         lfd fr0,(doublezero-0b)@l(r3)
1011 #endif
1012
1013         stfd fr0,40(r4)
1014         stfd fr0,48(r4)
1015         stfd fr0,56(r4)
1016         stfd fr0,64(r4)
1017         stfd fr0,72(r4)
1018         stfd fr0,80(r4)
1019         stfd fr0,88(r4)
1020         stfd fr0,96(r4)
1021         stfd fr0,104(r4)
1022         stfd fr0,112(r4)
1023
1024         stfd fr0,160(r4)
1025         stfd fr0,168(r4)
1026         stfd fr0,176(r4)
1027         stfd fr0,184(r4)
1028         stfd fr0,192(r4)
1029         stfd fr0,200(r4)
1030         stfd fr0,208(r4)
1031         stfd fr0,216(r4)
1032
1033         mr r3,r4
1034         blr
1035
1036
1037 asm_perform_threadswitch:
1038         mflr r0
1039         addi r1,r1,-224
1040         stw r0,120(r1)
1041         stw pv,124(r1)
1042         stw r14,0(r1)
1043         stw r15,4(r1)
1044         stw r24,8(r1)
1045         stw r25,12(r1)
1046         stw r26,16(r1)
1047         stw r27,20(r1)
1048         stw r28,24(r1)
1049         stw r29,28(r1)
1050         stw r30,32(r1)
1051         stw r31,36(r1)
1052         stfd fr14,40(r1)
1053         stfd fr15,48(r1)
1054         stfd fr24,56(r1)
1055         stfd fr25,64(r1)
1056         stfd fr26,72(r1)
1057         stfd fr27,80(r1)
1058         stfd fr28,88(r1)
1059         stfd fr29,96(r1)
1060         stfd fr30,104(r1)
1061         stfd fr31,112(r1)
1062
1063         stw r16,128(r1)
1064         stw r17,132(r1)
1065         stw r18,136(r1)
1066         stw r19,140(r1)
1067         stw r20,144(r1)
1068         stw r21,148(r1)
1069         stw r22,152(r1)
1070         stw r23,156(r1)
1071         stfd fr16,160(r1)
1072         stfd fr17,168(r1)
1073         stfd fr18,176(r1)
1074         stfd fr19,184(r1)
1075         stfd fr20,192(r1)
1076         stfd fr21,200(r1)
1077         stfd fr22,208(r1)
1078         stfd fr23,216(r1)
1079
1080         stw r1,0(r3)
1081         stw r1,0(r5)
1082         lwz r1,0(r4)
1083
1084         lwz r0,120(r1)
1085         lwz pv,124(r1)
1086         lwz r14,0(r1)
1087         lwz r15,4(r1)
1088         lwz r24,8(r1)
1089         lwz r25,12(r1)
1090         lwz r26,16(r1)
1091         lwz r27,20(r1)
1092         lwz r28,24(r1)
1093         lwz r29,28(r1)
1094         lwz r30,32(r1)
1095         lwz r31,36(r1)
1096         lfd fr14,40(r1)
1097         lfd fr15,48(r1)
1098         lfd fr24,56(r1)
1099         lfd fr25,64(r1)
1100         lfd fr26,72(r1)
1101         lfd fr27,80(r1)
1102         lfd fr28,88(r1)
1103         lfd fr29,96(r1)
1104         lfd fr30,104(r1)
1105         lfd fr31,112(r1)
1106
1107         lwz r16,128(r1)
1108         lwz r17,132(r1)
1109         lwz r18,136(r1)
1110         lwz r19,140(r1)
1111         lwz r20,144(r1)
1112         lwz r21,148(r1)
1113         lwz r22,152(r1)
1114         lwz r23,156(r1)
1115         lfd fr16,160(r1)
1116         lfd fr17,168(r1)
1117         lfd fr18,176(r1)
1118         lfd fr19,184(r1)
1119         lfd fr20,192(r1)
1120         lfd fr21,200(r1)
1121         lfd fr22,208(r1)
1122         lfd fr23,216(r1)
1123
1124         mtlr r0
1125         addi r1,r1,224
1126         blr
1127
1128
1129 asm_switchstackandcall:
1130         mflr r0
1131         stwu r3,-48(r3)
1132         stw r0,40(r3)
1133         stw r1,44(r3)
1134         stw r1,0(r5)
1135         mr r1,r3
1136
1137         mtctr r4
1138         mr r3,r6
1139         bctrl
1140
1141         lwz r0,40(r1)
1142         mtlr r0
1143         lwz r1,44(r1)
1144         blr
1145
1146
1147 asm_getclassvalues_atomic:
1148 _crit_restart2:
1149 _crit_begin2:
1150         lwz     r6,offbaseval(r3)
1151         lwz     r7,offdiffval(r3)
1152         lwz     r8,offbaseval(r4)
1153 _crit_end2:
1154         stw     r6,offcast_super_baseval(r5)
1155         stw     r7,offcast_super_diffval(r5)
1156         stw     r8,offcast_sub_baseval(r5)
1157         blr
1158
1159         .data
1160
1161 asm_criticalsections:
1162 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1163         .long   _crit_begin1
1164         .long   _crit_end1
1165         .long   _crit_restart1
1166         .long   _crit_begin2
1167         .long   _crit_end2
1168         .long   _crit_restart2
1169 #endif
1170         .long 0
1171
1172
1173 /*
1174  * These are local overrides for various environment variables in Emacs.
1175  * Please do not remove this and leave it at the end of the file, where
1176  * Emacs will automagically detect them.
1177  * ---------------------------------------------------------------------
1178  * Local variables:
1179  * mode: asm
1180  * indent-tabs-mode: t
1181  * c-basic-offset: 4
1182  * tab-width: 4
1183  * End:
1184  */