* Implemented stacktraces
[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 2957 2005-07-09 15:48:43Z 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
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
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     itmp3,-12(itmp1)
433         extsh   itmp3,itmp3
434         add     mptr,mptr,itmp3
435         stw     pv,0(mptr)
436
437         mtctr   pv
438
439         lwz     r0,(LA_SIZE + 1*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+LA_LR_OFFSET(r1)
440         mtlr    r0
441         addi    r1,r1,(LA_SIZE + 1*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
442         lwz     r29,-12(r1)
443 /*      lwz     pv,-8(r1)*/
444         lwz     r31,-4(r1)
445         bctr
446
447
448 /********************* function asm_handle_exception ***************************
449 *                                                                              *
450 *   This function handles an exception. It does not use the usual calling      *
451 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
452 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
453 *   the local exception table for a handler. If no one is found, it unwinds    *
454 *   stacks and continues searching the callers.                                *
455 *                                                                              *
456 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
457 *                                                                              *
458 *******************************************************************************/
459                 
460 asm_handle_nat_exception:
461         mflr    r9
462         lwz     itmp3,4(r9)
463         extsh   itmp3,itmp3
464         add     pv,itmp3,r9
465         lwz     itmp3,8(r9)
466         srwi    itmp3,itmp3,16
467         cmpwi   itmp3,0x3dad
468         bne     asm_handle_exception
469         lwz     itmp3,8(r9)
470         slwi    itmp3,itmp3,16
471         add     pv,pv,itmp3
472
473 asm_handle_exception:
474         addi    r1,r1,-18*4
475         stw     r0,0*4(r1)
476         stw     r2,1*4(r1)
477         stw     r3,2*4(r1)
478         stw     r4,3*4(r1)
479         stw     r5,4*4(r1)
480         stw     r6,5*4(r1)
481         stw     r7,6*4(r1)
482         stw     r8,7*4(r1)
483         stw     r9,8*4(r1)
484         stw     r10,9*4(r1)
485         stw     r16,10*4(r1)
486         stw     r17,11*4(r1)
487         stw     r18,12*4(r1)
488         stw     r19,13*4(r1)
489         stw     r20,14*4(r1)
490         stw     r21,15*4(r1)
491         stw     r22,16*4(r1)
492         stw     r23,17*4(r1)
493
494         li      r9,1
495 ex_stack_loop:
496         addi    r1,r1,-4*4            /* allocate stack                           */
497         stw     xptr,0*4(r1)          /* save used register                       */
498         stw     xpc,1*4(r1)
499         mflr    xptr
500         stw     xptr,2*4(r1)
501         stw     r9,3*4(r1)
502
503         lwz     r3,0*4(r1)            /* exception pointer                        */
504         lwz     r4,MethodPointer(pv)  /* method pointer                           */
505         mr      r5,xpc                /* exception pc                             */
506 /*      mr      r6,r9 */
507         li      r6,0                  /* line number                              */
508         li      r7,4                  /* set no unwind flag                       */
509
510         /* XXX no valid stack frame chaining here */
511         addi    r1,r1,-(24+5*4)       /* 24 linkage area + 5 argument * 4         */
512         bl      builtin_trace_exception
513         addi    r1,r1,(24+5*4)
514
515         lwz     xptr,2*4(r1)
516         mtlr    xptr
517         lwz     xptr,0*4(r1)          /* restore xptr                             */
518         lwz     xpc,1*4(r1)
519         lwz     r9,3*4(r1)
520         addi    r1,r1,4*4
521
522         lwz     r3,ExTableSize(pv)    /* r3 = exception table size                */
523         mr.     r3,r3                 /* if empty table skip                      */
524         beq     empty_table
525
526         addi    r4,pv,ExTableStart    /* r4 = start of exception table            */
527
528 ex_table_loop:
529         lwz     r5,ExStartPC(r4)      /* r5 = exception start pc                  */
530         cmplw   r5,xpc                /* (startpc <= xpc)                         */
531         bgt     ex_table_cont
532         lwz     r5,ExEndPC(r4)        /* r5 = exception end pc                    */
533         cmplw   xpc,r5                /* (xpc < endpc)                            */
534         bge     ex_table_cont
535         lwz     r7,ExCatchType(r4)    /* r7 = exception catch type                */
536         mr.     r7,r7
537         beq     ex_handle_it
538
539         lwz     itmp3,offclassloaded(r7)
540         mr.     itmp3,itmp3
541         bne     L_class_loaded
542
543         /* XXX no valid stack frame chaining here */
544         addi    r1,r1,-16*4           /* allocate stack                           */
545         stw     r3,7*4(r1)            /* save used registers                      */
546         stw     r4,8*4(r1)            /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save)  */
547         stw     r9,9*4(r1)
548         stw     xptr,10*4(r1)
549         stw     xpc,11*4(r1)
550         mflr    xptr
551         stw     xptr,12*4(r1)
552         stw     r7,13*4(r1)
553
554         mr      r3,r7                 /* arg1 = exceptionclass                    */
555         bl      load_class_bootstrap
556
557         lwz     r3,7*4(r1)
558         lwz     r4,8*4(r1)
559         lwz     r9,9*4(r1)
560         lwz     xptr,10*4(r1)
561         lwz     xpc,11*4(r1)
562         lwz     itmp3,12*4(r1)
563         mtlr    itmp3
564         lwz     r7,13*4(r1)     
565         addi    r1,r1,16*4
566
567 L_class_loaded:
568         lwz     itmp3,offclasslinked(r7)
569         mr.     itmp3,itmp3
570         /* XXX no valid stack frame chaining here */
571         addi    r1,r1,-16*4           /* allocate stack                           */
572         stw     r7,13*4(r1)
573         bne     L_class_linked
574
575         stw     r3,7*4(r1)            /* save used registers                      */
576         stw     r4,8*4(r1)            /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save)  */
577         stw     r9,9*4(r1)
578         stw     xptr,10*4(r1)
579         stw     xpc,11*4(r1)
580         mflr    xptr
581         stw     xptr,12*4(r1)
582
583         mr      r3,r7                 /* arg1 = exceptionclass                    */
584         bl      link_class
585
586         lwz     r3,7*4(r1)
587         lwz     r4,8*4(r1)
588         lwz     r9,9*4(r1)
589         lwz     xptr,10*4(r1)
590         lwz     xpc,11*4(r1)
591         lwz     itmp3,12*4(r1)
592         mtlr    itmp3
593
594 L_class_linked:
595 _crit_restart1:
596         lwz     r7,13*4(r1)
597 _crit_begin1:
598         lwz     r6,offobjvftbl(xptr)  /* r6 = vftblptr(xptr)                      */
599         lwz     r7,offclassvftbl(r7)  /* r7 = vftblptr(catchtype) class (not obj) */
600         lwz     r6,offbaseval(r6)     /* r6 = baseval(xptr)                       */
601         lwz     r8,offbaseval(r7)     /* r8 = baseval(catchtype)                  */
602         lwz     r7,offdiffval(r7)     /* r7 = diffval(catchtype)                  */
603 _crit_end1:
604         subf    r6,r8,r6              /* r6 = baseval(xptr) - baseval(catchtype)  */
605         cmplw   r6,r7                 /* xptr is instanceof catchtype             */
606         addi    r1,r1,16*4
607         bgt     ex_table_cont         /* if (false) continue                      */
608
609 ex_handle_it:
610         lwz     xpc,ExHandlerPC(r4)   /* xpc = exception handler pc               */
611         mr.     r9,r9
612         beq     ex_jump
613
614         lwz     r0,0*4(r1)
615         lwz     r2,1*4(r1)
616         lwz     r3,2*4(r1)
617         lwz     r4,3*4(r1)
618         lwz     r5,4*4(r1)
619         lwz     r6,5*4(r1)
620         lwz     r7,6*4(r1)
621         lwz     r8,7*4(r1)
622         lwz     r9,8*4(r1)
623         lwz     r10,9*4(r1)
624         lwz     r16,10*4(r1)
625         lwz     r17,11*4(r1)
626         lwz     r18,12*4(r1)
627         lwz     r19,13*4(r1)
628         lwz     r20,14*4(r1)
629         lwz     r21,15*4(r1)
630         lwz     r22,16*4(r1)
631         lwz     r23,17*4(r1)
632         addi    r1,r1,18*4
633
634 ex_jump:
635         mtctr   xpc
636         bctr
637
638 ex_table_cont:
639         addi    r4,r4,ExEntrySize     /* next exception table entry               */
640         addic.  r3,r3,-1              /* decrement entry counter                  */
641         bgt     ex_table_loop         /* if (t0 > 0) next entry                   */
642
643 empty_table:
644         mr.     r9,r9                 /* if here the first time, then             */
645         beq     ex_already_cleared
646         addi    r1,r1,18*4            /* deallocate stack and                     */
647         li      r9,0                  /* clear the no unwind flag                 */
648 ex_already_cleared:
649         lwz     r3,IsSync(pv)         /* t0 = SyncOffset                          */
650         mr.     r3,r3
651         beq     no_monitor_exit       /* if zero no monitorexit                   */
652
653 #if defined(USE_THREADS)
654         add     r3,r1,r3
655         lwz     r6,-4(r3)
656
657         addi    r1,r1,-6*4
658         stw     r3,0*4(r1)
659         stw     r4,1*4(r1)
660         stw     r9,2*4(r1)
661         stw     xptr,3*4(r1)
662         stw     xpc,4*4(r1)
663         mflr    xptr
664         stw     xptr,5*4(r1)
665
666         mr      r3,r6
667         /* XXX no valid stack frame chaining here */
668         addi    r1,r1,-40
669         bl      builtin_monitorexit
670         addi    r1,r1,40
671
672         lwz     xptr,5*4(r1)
673         mtlr    xptr
674         lwz     r3,0*4(r1)
675         lwz     r4,1*4(r1)
676         lwz     r9,2*4(r1)
677         lwz     xptr,3*4(r1)
678         lwz     xpc,4*4(r1)
679         addi    r1,r1,6*4
680 #endif
681
682 no_monitor_exit:
683         lwz     r3,FrameSize(pv)      /* r3 = frame size                          */
684         add     r1,r1,r3              /* unwind stack                             */
685         mr      r3,r1                 /* r3 = pointer to save area                */
686         lwz     r4,IsLeaf(pv)         /* r4 = is leaf procedure                   */
687         mr.     r4,r4
688         bne     ex_no_restore         /* if (leaf) skip                           */
689         lwz     r4,LA_LR_OFFSET(r3)   /* restore ra                               */
690         mtlr    r4                    /* t0--                                     */
691 ex_no_restore:
692         mflr    r4                    /* the new xpc is ra                        */
693         mr      xpc,r4
694         lwz     r4,IntSave(pv)        /* r4 = saved int register count            */
695         bl      ex_int1
696 ex_int1:
697         mflr    r5
698 #if defined(__DARWIN__)
699         addi    r5,r5,lo16(ex_int2-ex_int1)
700 #else
701         addi    r5,r5,(ex_int2-ex_int1)@l
702 #endif
703         slwi    r4,r4,2
704         subf    r5,r4,r5
705         mtctr   r5
706         bctr
707         lwz     s0,-40(r3)
708         lwz     s1,-36(r3)
709         lwz     s2,-32(r3)
710         lwz     s3,-28(r3)
711         lwz     s4,-24(r3)
712         lwz     s5,-20(r3)
713         lwz     s6,-16(r3)
714         lwz     s7,-12(r3)
715         lwz     s8,-8(r3)
716         lwz     s9,-4(r3)
717
718 ex_int2:
719         subf    r3,r4,r3
720
721         lwz     r4,FltSave(pv)
722         bl      ex_flt1
723 ex_flt1:
724         mflr    r5
725 #if defined(__DARWIN__)
726         addi    r5,r5,lo16(ex_flt2-ex_flt1)
727 #else
728         addi    r5,r5,(ex_flt2-ex_flt1)@l
729 #endif
730         slwi    r4,r4,2
731         subf    r5,r4,r5
732         mtctr   r5
733         bctr
734         lfd     fs0,-80(r3)
735         lfd     fs1,-72(r3)
736         lfd     fs2,-64(r3)
737         lfd     fs3,-56(r3)
738         lfd     fs4,-48(r3)
739         lfd     fs5,-40(r3)
740         lfd     fs6,-32(r3)
741         lfd     fs7,-24(r3)
742         lfd     fs8,-16(r3)
743         lfd     fs9,-8(r3)
744
745 ex_flt2:
746         mtlr    xpc
747         lwz     itmp3,4(xpc)
748         extsh   itmp3,itmp3
749         add     pv,itmp3,xpc
750         lwz     itmp3,8(xpc)
751         srwi    itmp3,itmp3,16
752         cmpwi   itmp3,0x3dad
753         bne     ex_stack_loop
754         lwz     itmp3,8(xpc)
755         slwi    itmp3,itmp3,16
756         add     pv,pv,itmp3
757         b       ex_stack_loop
758
759
760 /* asm_wrapper_patcher *********************************************************
761
762    XXX
763
764    Stack layout:
765      16   return address into JIT code (patch position)
766      12   pointer to virtual java_objectheader
767       8   machine code (which is patched back later)
768       4   unresolved class/method/field reference
769       0   patcher function pointer to call (pv is saved here afterwards)
770
771 *******************************************************************************/
772
773 asm_wrapper_patcher:
774         mflr    r0
775         stw     r0,8*4+LA_LR_OFFSET(r1) /* skip stack frame of patcher stub       */
776                                       /* keep stack 16-bytes aligned: 6+1+37 = 44 */
777         stwu    r1,-((6+1+38)*4+sizestackframeinfo)(r1)
778
779 #if 1
780         stw     a0,(6+1+0)*4(r1)      /* save argument registers                  */
781         stw     a1,(6+1+1)*4(r1)      /* preserve linkage area (24 bytes)         */
782         stw     a2,(6+1+2)*4(r1)      /* and 4 bytes for 1 argument               */
783         stw     a3,(6+1+3)*4(r1)
784         stw     a4,(6+1+4)*4(r1)
785         stw     a5,(6+1+5)*4(r1)
786         stw     a6,(6+1+6)*4(r1)
787         stw     a7,(6+1+7)*4(r1)
788
789         stfd    fa0,(6+1+8)*4(sp)
790         stfd    fa1,(6+1+10)*4(sp)
791         stfd    fa2,(6+1+12)*4(sp)
792         stfd    fa3,(6+1+14)*4(sp)
793         stfd    fa4,(6+1+16)*4(sp)
794         stfd    fa5,(6+1+18)*4(sp)
795         stfd    fa6,(6+1+20)*4(sp)
796         stfd    fa7,(6+1+22)*4(sp)
797         stfd    fa8,(6+1+24)*4(sp)
798         stfd    fa9,(6+1+26)*4(sp)
799         stfd    fa10,(6+1+28)*4(sp)
800         stfd    fa11,(6+1+30)*4(sp)
801         stfd    fa12,(6+1+32)*4(sp)
802 #else
803         SAVE_ARGUMENT_REGISTERS(6+1)  /* save 8 int/13 float argument registers   */
804 #endif
805
806 #if 0
807         stw     r2,25*8(r1)
808         stw     r16,26*8(r1)
809         stw     r17,27*8(r1)
810         stw     r18,28*8(r1)
811         stw     r19,29*8(r1)
812         stw     r20,30*8(r1)
813         stw     r21,31*8(r1)
814         stw     r22,32*8(r1)
815         stw     r23,33*8(r1)
816 #endif
817
818         stw     itmp1,(6+1+34)*4(sp)
819         stw     itmp2,(6+1+35)*4(sp)
820         stw     pv,(6+1+36)*4(sp)
821
822         addi    a0,sp,(6+1+38)*4      /* create stackframe info                   */
823         mr      a1,pv
824                                       /* add stack frame + patcher stub stack     */
825         addi    a2,sp,(8+6+1+38)*4+sizestackframeinfo
826         mr      a3,r0
827         bl      stacktrace_create_inline_stackframeinfo
828
829         addi    a0,sp,(0+6+1+38)*4+sizestackframeinfo  /* pass sp                 */
830         lwz     pv,(0+6+1+38)*4+sizestackframeinfo(sp) /* get function pointer    */
831         lwz     itmp1,(6+1+36)*4(sp)  /* move pv to position of fp                */
832         stw     itmp1,(0+6+1+38)*4+sizestackframeinfo(sp)
833         mtctr   pv                    /* call the patcher function                */
834         bctrl
835         stw     r3,(6+1+37)*4(sp)     /* save return value                        */
836
837         addi    a0,sp,(6+1+38)*4
838         bl      stacktrace_remove_stackframeinfo /* remove stackframe info        */
839
840         lwz     itmp3,(6+1+37)*4(sp)  /* restore return value into temp register  */
841
842 #if 1
843         lwz     a0,(6+1+0)*4(r1)
844         lwz     a1,(6+1+1)*4(r1)
845         lwz     a2,(6+1+2)*4(r1)
846         lwz     a3,(6+1+3)*4(r1)
847         lwz     a4,(6+1+4)*4(r1)
848         lwz     a5,(6+1+5)*4(r1)
849         lwz     a6,(6+1+6)*4(r1)
850         lwz     a7,(6+1+7)*4(r1)
851
852         lfd     fa0,(6+1+8)*4(sp)
853         lfd     fa1,(6+1+10)*4(sp)
854         lfd     fa2,(6+1+12)*4(sp)
855         lfd     fa3,(6+1+14)*4(sp)
856         lfd     fa4,(6+1+16)*4(sp)
857         lfd     fa5,(6+1+18)*4(sp)
858         lfd     fa6,(6+1+20)*4(sp)
859         lfd     fa7,(6+1+22)*4(sp)
860         lfd     fa8,(6+1+24)*4(sp)
861         lfd     fa9,(6+1+26)*4(sp)
862         lfd     fa10,(6+1+28)*4(sp)
863         lfd     fa11,(6+1+30)*4(sp)
864         lfd     fa12,(6+1+32)*4(sp)
865 #else
866         RESTORE_ARGUMENT_REGISTERS(6+1)/* restore 8 int/13 float argument reg.    */
867 #endif
868
869 #if 0
870         lwz     r2,25*8(r1)
871         lwz     r16,26*8(r1)
872         lwz     r17,27*8(r1)
873         lwz     r18,28*8(r1)
874         lwz     r19,29*8(r1)
875         lwz     r20,30*8(r1)
876         lwz     r21,31*8(r1)
877         lwz     r22,32*8(r1)
878         lwz     r23,33*8(r1)            
879 #endif
880
881                                       /* get return address (into JIT code)       */
882         lwz     itmp1,(4+6+1+38)*4+sizestackframeinfo(sp)
883         mtlr    itmp1
884
885         lwz     itmp1,(6+1+34)*4(sp)
886         lwz     itmp2,(6+1+35)*4(sp)
887         lwz     pv,(6+1+36)*4(sp)
888
889                                       /* remove stack frame + patcher stub stack  */
890         addi    r1,r1,(8+6+1+38)*4+sizestackframeinfo
891
892         mr.     itmp3,itmp3           /* check for an exception                   */
893         beq     L_asm_wrapper_patcher_exception
894
895         blr                           /* jump to new patched code                 */
896
897 L_asm_wrapper_patcher_exception:
898 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
899         mflr    r0
900         stw     r0,LA_LR_OFFSET(r1)
901         stwu    r1,-LA_SIZE_ALIGNED(r1) /* preserve linkage area                  */
902         bl      builtin_asm_get_exceptionptrptr
903         lwz     r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(r1)
904         mtlr    r0      
905         addi    r1,r1,LA_SIZE_ALIGNED
906 #else
907 # if defined(__DARWIN__)
908         lwz     v0,lo16(_exceptionptr-0b)(pv)
909 # else
910         lis     v0,_exceptionptr@ha
911         addi    v0,v0,_exceptionptr@l
912 # endif
913 #endif
914
915         lwz     xptr,0(v0)            /* get the exception pointer                */
916         li      itmp3,0
917         stw     itmp3,0(v0)           /* clear the exception pointer              */
918
919         mflr    xpc
920         b       asm_handle_exception
921
922
923 asm_cacheflush:
924         add     r4,r3,r4
925         rlwinm  r3,r3,0,0,26
926         addi    r4,r4,31
927         rlwinm  r4,r4,0,0,26
928         mr      r5,r3
929 1:
930         cmplw   r3,r4
931         bge     0f
932         dcbst   0,r3
933         addi    r3,r3,32
934         b       1b
935 0:
936         sync
937 1:
938         cmplw   r5,r4
939         bge     0f
940         icbi    0,r5
941         addi    r5,r5,32
942         b       1b
943 0:
944         sync
945         isync
946         blr
947
948
949         .align 3
950 doublezero:
951         .double 0.0
952
953 asm_initialize_thread_stack:
954         addi r4,r4,-256
955         stw r3,120(r4)
956         li r3,0
957         stw r3,124(r4)
958         stw r3,0(r4)
959         stw r3,4(r4)
960         stw r3,8(r4)
961         stw r3,12(r4)
962         stw r3,16(r4)
963         stw r3,20(r4)
964         stw r3,24(r4)
965         stw r3,28(r4)
966         stw r3,32(r4)
967         stw r3,36(r4)
968
969         stw r3,128(r4)
970         stw r3,132(r4)
971         stw r3,136(r4)
972         stw r3,140(r4)
973         stw r3,144(r4)
974         stw r3,148(r4)
975         stw r3,152(r4)
976         stw r3,156(r4)
977
978         mflr r0
979         bl 0f
980 0:
981         mflr r3
982         mtlr r0
983 #if defined(__DARWIN__)
984         lfd fr0,lo16(doublezero-0b)(r3)
985 #else
986         lfd fr0,(doublezero-0b)@l(r3)
987 #endif
988
989         stfd fr0,40(r4)
990         stfd fr0,48(r4)
991         stfd fr0,56(r4)
992         stfd fr0,64(r4)
993         stfd fr0,72(r4)
994         stfd fr0,80(r4)
995         stfd fr0,88(r4)
996         stfd fr0,96(r4)
997         stfd fr0,104(r4)
998         stfd fr0,112(r4)
999
1000         stfd fr0,160(r4)
1001         stfd fr0,168(r4)
1002         stfd fr0,176(r4)
1003         stfd fr0,184(r4)
1004         stfd fr0,192(r4)
1005         stfd fr0,200(r4)
1006         stfd fr0,208(r4)
1007         stfd fr0,216(r4)
1008
1009         mr r3,r4
1010         blr
1011
1012
1013 asm_perform_threadswitch:
1014         mflr r0
1015         addi r1,r1,-224
1016         stw r0,120(r1)
1017         stw pv,124(r1)
1018         stw r14,0(r1)
1019         stw r15,4(r1)
1020         stw r24,8(r1)
1021         stw r25,12(r1)
1022         stw r26,16(r1)
1023         stw r27,20(r1)
1024         stw r28,24(r1)
1025         stw r29,28(r1)
1026         stw r30,32(r1)
1027         stw r31,36(r1)
1028         stfd fr14,40(r1)
1029         stfd fr15,48(r1)
1030         stfd fr24,56(r1)
1031         stfd fr25,64(r1)
1032         stfd fr26,72(r1)
1033         stfd fr27,80(r1)
1034         stfd fr28,88(r1)
1035         stfd fr29,96(r1)
1036         stfd fr30,104(r1)
1037         stfd fr31,112(r1)
1038
1039         stw r16,128(r1)
1040         stw r17,132(r1)
1041         stw r18,136(r1)
1042         stw r19,140(r1)
1043         stw r20,144(r1)
1044         stw r21,148(r1)
1045         stw r22,152(r1)
1046         stw r23,156(r1)
1047         stfd fr16,160(r1)
1048         stfd fr17,168(r1)
1049         stfd fr18,176(r1)
1050         stfd fr19,184(r1)
1051         stfd fr20,192(r1)
1052         stfd fr21,200(r1)
1053         stfd fr22,208(r1)
1054         stfd fr23,216(r1)
1055
1056         stw r1,0(r3)
1057         stw r1,0(r5)
1058         lwz r1,0(r4)
1059
1060         lwz r0,120(r1)
1061         lwz pv,124(r1)
1062         lwz r14,0(r1)
1063         lwz r15,4(r1)
1064         lwz r24,8(r1)
1065         lwz r25,12(r1)
1066         lwz r26,16(r1)
1067         lwz r27,20(r1)
1068         lwz r28,24(r1)
1069         lwz r29,28(r1)
1070         lwz r30,32(r1)
1071         lwz r31,36(r1)
1072         lfd fr14,40(r1)
1073         lfd fr15,48(r1)
1074         lfd fr24,56(r1)
1075         lfd fr25,64(r1)
1076         lfd fr26,72(r1)
1077         lfd fr27,80(r1)
1078         lfd fr28,88(r1)
1079         lfd fr29,96(r1)
1080         lfd fr30,104(r1)
1081         lfd fr31,112(r1)
1082
1083         lwz r16,128(r1)
1084         lwz r17,132(r1)
1085         lwz r18,136(r1)
1086         lwz r19,140(r1)
1087         lwz r20,144(r1)
1088         lwz r21,148(r1)
1089         lwz r22,152(r1)
1090         lwz r23,156(r1)
1091         lfd fr16,160(r1)
1092         lfd fr17,168(r1)
1093         lfd fr18,176(r1)
1094         lfd fr19,184(r1)
1095         lfd fr20,192(r1)
1096         lfd fr21,200(r1)
1097         lfd fr22,208(r1)
1098         lfd fr23,216(r1)
1099
1100         mtlr r0
1101         addi r1,r1,224
1102         blr
1103
1104
1105 asm_switchstackandcall:
1106         mflr r0
1107         stwu r3,-48(r3)
1108         stw r0,40(r3)
1109         stw r1,44(r3)
1110         stw r1,0(r5)
1111         mr r1,r3
1112
1113         mtctr r4
1114         mr r3,r6
1115         bctrl
1116
1117         lwz r0,40(r1)
1118         mtlr r0
1119         lwz r1,44(r1)
1120         blr
1121
1122
1123 asm_getclassvalues_atomic:
1124 _crit_restart2:
1125 _crit_begin2:
1126         lwz     r6,offbaseval(r3)
1127         lwz     r7,offdiffval(r3)
1128         lwz     r8,offbaseval(r4)
1129 _crit_end2:
1130         stw     r6,offcast_super_baseval(r5)
1131         stw     r7,offcast_super_diffval(r5)
1132         stw     r8,offcast_sub_baseval(r5)
1133         blr
1134
1135         .data
1136
1137 asm_criticalsections:
1138 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1139         .long   _crit_begin1
1140         .long   _crit_end1
1141         .long   _crit_restart1
1142         .long   _crit_begin2
1143         .long   _crit_end2
1144         .long   _crit_restart2
1145 #endif
1146         .long 0
1147
1148
1149 /*
1150  * These are local overrides for various environment variables in Emacs.
1151  * Please do not remove this and leave it at the end of the file, where
1152  * Emacs will automagically detect them.
1153  * ---------------------------------------------------------------------
1154  * Local variables:
1155  * mode: asm
1156  * indent-tabs-mode: t
1157  * c-basic-offset: 4
1158  * tab-width: 4
1159  * End:
1160  */