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