4a4cb27f1355c3dd8b3802fb51f5e16e3a301b14
[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, 2007 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    $Id: asmpart.S 8274 2007-08-08 15:58:17Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include "md-abi.h"
33 #include "md-asm.h"
34
35 #include "vm/jit/abi-asm.h"
36 #include "vm/jit/methodheader.h"
37
38
39         .text
40
41         .align 2
42
43
44 /* export functions ***********************************************************/
45
46         .globl asm_vm_call_method
47         .globl asm_vm_call_method_int
48         .globl asm_vm_call_method_long
49         .globl asm_vm_call_method_float
50         .globl asm_vm_call_method_double
51
52         .globl asm_vm_call_method_exception_handler
53         .globl asm_vm_call_method_end
54
55         .globl asm_call_jit_compiler
56
57         .globl asm_handle_nat_exception
58         .globl asm_handle_exception
59
60         .globl asm_abstractmethoderror
61
62 #if defined(ENABLE_REPLACEMENT)
63         .globl asm_replacement_out
64         .globl asm_replacement_in
65 #endif
66
67         .globl asm_cacheflush
68
69         .globl asm_compare_and_swap
70         .globl asm_memory_barrier
71
72
73 /* asm_vm_call_method **********************************************************
74 *                                                                              *
75 *   This function calls a Java-method (which possibly needs compilation)       *
76 *   with up to 4 address parameters.                                           *
77 *                                                                              *
78 *   This functions calls the JIT-compiler which eventually translates the      *
79 *   method into machine code.                                                  *
80 *                                                                              *
81 *   C-prototype:                                                               *
82 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
83 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
84 *                                                                              *
85 *******************************************************************************/
86
87         .align 2
88
89         .long   0                         /* catch type all                       */
90         .long   0                         /* exception handler pc                 */
91         .long   0                         /* end pc                               */
92         .long   0                         /* start pc                             */
93         .long   1                         /* extable size                         */
94         .long   0                         /* line number table start              */
95         .long   0                         /* line number table size               */
96         .long   0                         /* fltsave                              */
97         .long   0                         /* intsave                              */
98         .long   0                         /* IsLeaf                               */
99         .long   0                         /* IsSync                               */
100         .long   0                         /* frame size                           */
101         .long   0                         /* codeinfo pointer                     */
102
103 asm_vm_call_method:
104 asm_vm_call_method_int:
105 asm_vm_call_method_long:
106 asm_vm_call_method_float:
107 asm_vm_call_method_double:
108         mflr    r0
109         stw     r0,LA_LR_OFFSET(sp)
110         stwu    sp,-40*4(sp)              /* keep stack 16-byte aligned           */
111
112         stw     s0,8*4(sp)                /* save used callee saved registers     */
113         stw     a0,9*4(sp)                /* save method PV                       */
114
115 #if defined(__DARWIN__)
116         stw     itmp1,10*4(sp)            /* register r11 is callee saved         */
117 #endif
118         stw     pv,11*4(sp)               /* save PV register                     */
119
120         stw     itmp3,12*4(sp)            /* registers r14-r31 are callee saved   */
121         stfd    ftmp1,14*4(sp)            /* registers f14-f31 are callee saved   */
122         stfd    ftmp2,16*4(sp)
123
124 #if defined(__DARWIN__)
125         stw     t1,18*4(sp)
126         stw     t2,19*4(sp)
127         stw     t3,20*4(sp)
128         stw     t4,21*4(sp)
129         stw     t5,22*4(sp)
130         stw     t6,23*4(sp)
131         stw     t7,24*4(sp)
132
133         stfd    ft0,26*4(sp)
134         stfd    ft1,28*4(sp)
135         stfd    ft2,30*4(sp)
136         stfd    ft3,32*4(sp)
137         stfd    ft4,34*4(sp)
138         stfd    ft5,36*4(sp)
139 #else
140         SAVE_TEMPORARY_REGISTERS(18)        /* the offset has to be even          */
141 #endif
142
143         mr      t0,a1                       /* address of data structure          */
144         mr      t1,a2                       /* stack argument count               */
145
146         mr      s0,sp                       /* save SP                            */
147
148         lwz     a0,0*8+4(t0)                /* we are on big-endian               */
149         lwz     a1,1*8+4(t0)
150         lwz     a2,2*8+4(t0)
151         lwz     a3,3*8+4(t0)
152         lwz     a4,4*8+4(t0)
153         lwz     a5,5*8+4(t0)
154         lwz     a6,6*8+4(t0)
155         lwz     a7,7*8+4(t0)
156
157         lfd     fa0,8*8(t0)
158         lfd     fa1,9*8(t0)
159         lfd     fa2,10*8(t0)
160         lfd     fa3,11*8(t0)
161         lfd     fa4,12*8(t0)
162         lfd     fa5,13*8(t0)
163         lfd     fa6,14*8(t0)
164         lfd     fa7,15*8(t0)
165
166 #if defined(__DARWIN__)
167         lfd     fa8,16*8(t0)
168         lfd     fa9,17*8(t0)
169         lfd     fa10,18*8(t0)
170         lfd     fa11,19*8(t0)
171         lfd     fa12,20*8(t0)
172 #endif
173
174         mr.     t1,t1
175         beq     L_asm_vm_call_method_stack_copy_done
176
177         slwi    t2,t1,3                     /* calculate stackframe size (* 8)    */
178
179         sub     sp,sp,t2                    /* create stackframe                  */
180         mr      t2,sp                       /* temporary stack pointer            */
181
182 L_asm_vm_call_method_stack_copy_loop:
183 #if defined(__DARWIN__)
184         lwz     t3,21*8+0(t0)               /* load argument                      */
185         lwz     t4,21*8+4(t0)
186 #else
187         lwz     t3,16*8+0(t0)               /* load argument                      */
188         lwz     t4,16*8+4(t0)
189 #endif
190         stw     t3,0(t2)                    /* store argument on stack            */
191         stw     t4,4(t2)
192
193         addi    t0,t0,8                     /* load address of next argument      */
194         addi    t2,t2,8                     /* increase stack pointer             */
195         addi    t1,t1,-1                    /* subtract 1 argument                */
196         mr.     t1,t1
197         bgt     L_asm_vm_call_method_stack_copy_loop
198
199 L_asm_vm_call_method_stack_copy_done:
200         addi    mptr,s0,9*4                 /* get address of PV                  */
201         lwz     pv,0*4(mptr)                /* load PV                            */
202         mtctr   pv
203         bctrl
204 1:
205         mflr    itmp1
206 #if defined(__DARWIN__)
207         addi    pv,itmp1,lo16(asm_vm_call_method - 1b)
208 #else
209         addi    pv,itmp1,(asm_vm_call_method - 1b)@l
210 #endif
211
212 L_asm_vm_call_method_return:
213         mr      sp,s0                       /* restore the SP                     */
214
215         lwz     s0,8*4(sp)                  /* restore used callee saved registers*/
216
217 #if defined(__DARWIN__)
218         lwz     itmp1,10*4(sp)              /* register r11 is callee saved       */
219 #endif
220         lwz     pv,11*4(sp)                 /* save PV register                   */
221
222         lwz     itmp3,12*4(sp)
223         lfd     ftmp1,14*4(sp)              /* registers f14-f31 are callee saved */
224         lfd     ftmp2,16*4(sp)
225
226 #if defined(__DARWIN__)
227         lwz     t1,18*4(sp)
228         lwz     t2,19*4(sp)
229         lwz     t3,20*4(sp)
230         lwz     t4,21*4(sp)
231         lwz     t5,22*4(sp)
232         lwz     t6,23*4(sp)
233         lwz     t7,24*4(sp)
234
235         lfd     ft0,26*4(sp)
236         lfd     ft1,28*4(sp)
237         lfd     ft2,30*4(sp)
238         lfd     ft3,32*4(sp)
239         lfd     ft4,34*4(sp)
240         lfd     ft5,36*4(sp)
241 #else
242         RESTORE_TEMPORARY_REGISTERS(18)   /* the offset has to be even            */
243 #endif
244
245         lwz     r0,40*4+LA_LR_OFFSET(sp)
246         mtlr    r0
247         addi    sp,sp,40*4
248         blr
249
250 asm_vm_call_method_exception_handler:
251         mr      a0,itmp1
252         bl      builtin_throw_exception
253         b       L_asm_vm_call_method_return
254
255 asm_vm_call_method_end:
256         nop
257
258
259 /* asm_call_jit_compiler *******************************************************
260
261    Invokes the compiler for untranslated JavaVM methods.
262
263 *******************************************************************************/
264
265 asm_call_jit_compiler:
266 L_asm_call_jit_compiler:                /* required for PIC code              */
267         mflr    r0
268         stw     r0,LA_LR_OFFSET(sp)         /* save return address                */
269         stwu    sp,-(LA_SIZE + 4*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)(sp)
270
271 #if defined(__DARWIN__)
272         stw     a0,LA_SIZE+(4+0)*4(sp)
273         stw     a1,LA_SIZE+(4+1)*4(sp)
274         stw     a2,LA_SIZE+(4+2)*4(sp)
275         stw     a3,LA_SIZE+(4+3)*4(sp)
276         stw     a4,LA_SIZE+(4+4)*4(sp)
277         stw     a5,LA_SIZE+(4+5)*4(sp)
278         stw     a6,LA_SIZE+(4+6)*4(sp)
279         stw     a7,LA_SIZE+(4+7)*4(sp)
280
281         stfd    fa0,LA_SIZE+(4+8)*4(sp)
282         stfd    fa1,LA_SIZE+(4+10)*4(sp)
283         stfd    fa2,LA_SIZE+(4+12)*4(sp)
284         stfd    fa3,LA_SIZE+(4+14)*4(sp)
285         stfd    fa4,LA_SIZE+(4+16)*4(sp)
286         stfd    fa5,LA_SIZE+(4+18)*4(sp)
287         stfd    fa6,LA_SIZE+(4+20)*4(sp)
288         stfd    fa7,LA_SIZE+(4+22)*4(sp)
289         stfd    fa8,LA_SIZE+(4+24)*4(sp)
290         stfd    fa9,LA_SIZE+(4+26)*4(sp)
291         stfd    fa10,LA_SIZE+(4+28)*4(sp)
292         stfd    fa11,LA_SIZE+(4+30)*4(sp)
293         stfd    fa12,LA_SIZE+(4+32)*4(sp)
294 #else
295         SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS)
296 #endif
297
298         mr      a0,itmp1
299         mr      a1,mptr
300         addi    a2,sp,(LA_SIZE + 4*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)
301         lwz     a3,(LA_SIZE + 4*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)+LA_LR_OFFSET(sp)
302         bl      jit_asm_compile
303         mr      pv,v0                       /* move address to pv register        */
304
305 #if defined(__DARWIN__)
306         lwz     a0,LA_SIZE+(4+0)*4(sp)
307         lwz     a1,LA_SIZE+(4+1)*4(sp)
308         lwz     a2,LA_SIZE+(4+2)*4(sp)
309         lwz     a3,LA_SIZE+(4+3)*4(sp)
310         lwz     a4,LA_SIZE+(4+4)*4(sp)
311         lwz     a5,LA_SIZE+(4+5)*4(sp)
312         lwz     a6,LA_SIZE+(4+6)*4(sp)
313         lwz     a7,LA_SIZE+(4+7)*4(sp)
314
315         lfd     fa0,LA_SIZE+(4+8)*4(sp)
316         lfd     fa1,LA_SIZE+(4+10)*4(sp)
317         lfd     fa2,LA_SIZE+(4+12)*4(sp)
318         lfd     fa3,LA_SIZE+(4+14)*4(sp)
319         lfd     fa4,LA_SIZE+(4+16)*4(sp)
320         lfd     fa5,LA_SIZE+(4+18)*4(sp)
321         lfd     fa6,LA_SIZE+(4+20)*4(sp)
322         lfd     fa7,LA_SIZE+(4+22)*4(sp)
323         lfd     fa8,LA_SIZE+(4+24)*4(sp)
324         lfd     fa9,LA_SIZE+(4+26)*4(sp)
325         lfd     fa10,LA_SIZE+(4+28)*4(sp)
326         lfd     fa11,LA_SIZE+(4+30)*4(sp)
327         lfd     fa12,LA_SIZE+(4+32)*4(sp)
328 #else
329         RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS)
330 #endif
331
332         lwz     itmp1,(LA_SIZE + 4*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)+LA_LR_OFFSET(sp)
333         mtlr    itmp1
334
335         addi    sp,sp,(LA_SIZE + 4*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)
336
337         mr.     pv,pv                       /* test for exception                 */
338         beq     L_asm_call_jit_compiler_exception
339
340         mtctr   pv                          /* move method address to control reg */
341         bctr                                /* and call the Java method           */
342
343 L_asm_call_jit_compiler_exception:
344         mflr    r0
345         stw     r0,LA_LR_OFFSET(sp)
346         stwu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
347         bl      exceptions_get_and_clear_exception
348         lwz     xpc,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
349         mtlr    xpc     
350         addi    sp,sp,LA_SIZE_ALIGNED
351
352         mr      xptr,v0                     /* get exception                      */
353         addi    xpc,xpc,-4                  /* exception address is ra - 4        */
354         b       L_asm_handle_nat_exception
355
356
357 /********************* function asm_handle_exception ***************************
358 *                                                                              *
359 *   This function handles an exception. It does not use the usual calling      *
360 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
361 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
362 *   the local exception table for a handler. If no one is found, it unwinds    *
363 *   stacks and continues searching the callers.                                *
364 *                                                                              *
365 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
366 *                                                                              *
367 *******************************************************************************/
368                 
369 asm_handle_nat_exception:
370 L_asm_handle_nat_exception:             /* required for PIC code              */
371 L_asm_handle_exception_stack_loop:
372         mflr    r0
373         addi    sp,sp,-(LA_SIZE+((4+6)*4))  /* allocate stack (+4 for darwin)     */
374         stw     xptr,LA_SIZE+(4+0)*4(sp)    /* save exception pointer             */
375         stw     xpc,LA_SIZE+(4+1)*4(sp)     /* save exception pc                  */
376         stw     r0,LA_SIZE+(4+3)*4(sp)      /* save return address                */
377         li      itmp3,0
378         stw     itmp3,LA_SIZE+(4+4)*4(sp)   /* save maybe-leaf flag (cleared)     */
379
380         mr      a0,r0                       /* pass return address                */
381         bl      md_codegen_get_pv_from_pc   /* get PV from RA                     */
382         stw     v0,LA_SIZE+(4+2)*4(sp)      /* save data segment pointer          */
383
384         lwz     a0,LA_SIZE+(4+0)*4(sp)      /* pass xptr                          */
385         lwz     a1,LA_SIZE+(4+1)*4(sp)      /* pass xpc                           */
386         lwz     a2,LA_SIZE+(4+2)*4(sp)      /* pass PV (v0 == a0)                 */
387         addi    a3,sp,LA_SIZE+((4+6)*4)     /* pass Java SP                       */
388
389         b       L_asm_handle_exception_continue
390
391 asm_handle_exception:
392 L_asm_handle_exception:                 /* required for PIC code              */
393         addi    sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
394
395 #if defined(__DARWIN__)
396 #else
397         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
398         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
399 #endif
400
401         addi    sp,sp,-(LA_SIZE+(4+6)*4)    /* allocate stack                     */
402         stw     xptr,LA_SIZE+(4+0)*4(sp)    /* save xptr                          */
403         stw     pv,LA_SIZE+(4+2)*4(sp)      /* save PV                            */
404         mflr    r0                          /* save RA                            */
405         stw     r0,LA_SIZE+(4+3)*4(sp)
406         li      t0,1                        /* set maybe-leaf flag                */
407         stw     t0,LA_SIZE+(4+4)*4(sp)      /* save maybe-leaf flag               */
408
409         mr      a0,xptr                     /* pass exception pointer             */
410         mr      a1,xpc                      /* pass exception pc                  */
411         mr      a2,pv                       /* pass data segment pointer          */
412         addi    a3,sp,LA_SIZE+(ARG_CNT+TMP_CNT)*8+(4+6)*4
413
414 L_asm_handle_exception_continue:
415         bl      exceptions_handle_exception
416
417         mr.     v0,v0
418         beq     L_asm_handle_exception_not_catched
419
420         mr      xpc,v0                      /* move handlerpc into xpc            */
421         lwz     xptr,LA_SIZE+(4+0)*4(sp)    /* restore xptr                       */
422         lwz     pv,LA_SIZE+(4+2)*4(sp)      /* restore PV                         */
423         lwz     r0,LA_SIZE+(4+3)*4(sp)      /* restore RA                         */
424         mtlr    r0
425         lwz     t0,LA_SIZE+(4+4)*4(sp)      /* get maybe-leaf flag                */
426         addi    sp,sp,LA_SIZE+(4+6)*4       /* free stack frame                   */
427
428         mr.     t0,t0
429         beq     L_asm_handle_exception_no_leaf
430
431 #if defined(__DARWIN__)
432 #else
433         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
434         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
435 #endif
436
437         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
438
439 L_asm_handle_exception_no_leaf:
440         mtctr   xpc                         /* jump to the handler                */
441         bctr
442
443 L_asm_handle_exception_not_catched:
444         lwz     xptr,LA_SIZE+(4+0)*4(sp)    /* restore xptr                       */
445         lwz     pv,LA_SIZE+(4+2)*4(sp)      /* restore PV                         */
446         lwz     r0,LA_SIZE+(4+3)*4(sp)      /* restore RA                         */
447         mtlr    r0
448         lwz     t0,LA_SIZE+(4+4)*4(sp)      /* get maybe-leaf flag                */
449         addi    sp,sp,LA_SIZE+(4+6)*4       /* free stack frame                   */
450
451         mr.     t0,t0
452         beq     L_asm_handle_exception_no_leaf_stack
453
454         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
455         li      t0,0                        /* clear the maybe-leaf flag          */
456
457 L_asm_handle_exception_no_leaf_stack:
458         lwz     t1,FrameSize(pv)            /* get frame size                     */
459         add     t1,sp,t1                    /* pointer to save area               */
460
461         lwz     t2,IsLeaf(pv)               /* is leaf procedure                  */
462         mr.     t2,t2
463         bne     L_asm_handle_exception_no_ra_restore
464
465         lwz     r0,LA_LR_OFFSET(t1)         /* restore ra                         */
466         mtlr    r0
467
468 L_asm_handle_exception_no_ra_restore:
469         mflr    xpc                         /* the new xpc is ra                  */
470         mr      t4,xpc                      /* save RA                            */
471         lwz     t2,IntSave(pv)              /* t2 = saved int register count      */
472         bl      ex_int1
473 ex_int1:
474         mflr    t3                          /* t3 = current pc                    */
475 #if defined(__DARWIN__)
476         addi    t3,t3,lo16(ex_int2-ex_int1)
477 #else
478         addi    t3,t3,(ex_int2-ex_int1)@l
479 #endif
480         slwi    t2,t2,2                     /* t2 = register count * 4            */
481         subf    t3,t2,t3                    /* t3 = IntSave - t2                  */
482         mtctr   t3
483         bctr
484
485         lwz     s0,-10*8(t1)
486         lwz     s1,-9*8(t1)
487         lwz     s2,-8*8(t1)
488         lwz     s3,-7*8(t1)
489         lwz     s4,-6*8(t1)
490         lwz     s5,-5*8(t1)
491         lwz     s6,-4*8(t1)
492         lwz     s7,-3*8(t1)
493         lwz     s8,-2*8(t1)
494         lwz     s9,-1*8(t1)
495
496 ex_int2:
497         subf    t1,t2,t1                    /* t1 = t1 - register count * 4       */
498
499         lwz     t2,FltSave(pv)
500         bl      ex_flt1
501 ex_flt1:
502         mflr    t3
503 #if defined(__DARWIN__)
504         addi    t3,t3,lo16(ex_flt2-ex_flt1)
505 #else
506         addi    t3,t3,(ex_flt2-ex_flt1)@l
507 #endif
508         slwi    t2,t2,2                     /* t2 = register count * 4            */
509         subf    t3,t2,t3                    /* t3 = FltSave - t2                  */
510         mtctr   t3
511         bctr
512
513         lfd     fs0,-10*8(t1)
514         lfd     fs1,-9*8(t1)
515         lfd     fs2,-8*8(t1)
516         lfd     fs3,-7*8(t1)
517         lfd     fs4,-6*8(t1)
518         lfd     fs5,-5*8(t1)
519         lfd     fs6,-4*8(t1)
520         lfd     fs7,-3*8(t1)
521         lfd     fs8,-2*8(t1)
522         lfd     fs9,-1*8(t1)
523
524 ex_flt2:
525         mtlr    t4                          /* restore RA                         */
526         lwz     t1,FrameSize(pv)            /* get frame size                     */
527         add     sp,sp,t1                    /* unwind stack                       */
528         b       L_asm_handle_exception_stack_loop
529
530
531 /* asm_abstractmethoderror *****************************************************
532
533    Creates and throws an AbstractMethodError.
534
535 *******************************************************************************/
536
537 asm_abstractmethoderror:
538         mflr    r0
539         stw     r0,LA_LR_OFFSET(sp)
540         stwu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
541         addi    a0,sp,LA_SIZE_ALIGNED       /* pass java sp                       */
542         mr      a1,r0                       /* pass exception address             */
543         bl      exceptions_asm_new_abstractmethoderror
544         lwz     r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
545         mtlr    r0                          /* restore return address             */
546         addi    sp,sp,LA_SIZE_ALIGNED
547
548         mr      xptr,v0                     /* get exception pointer              */
549         mr      xpc,r0                      /* we can't use r0 directly in addi   */
550         addi    xpc,xpc,-4                  /* exception address is ra - 4        */
551         b       L_asm_handle_nat_exception
552
553
554 #if defined(ENABLE_REPLACEMENT)
555
556 /* asm_replacement_out *********************************************************
557
558    This code is jumped to from the replacement-out stubs that are executed
559    when a thread reaches an activated replacement point.
560
561    The purpose of asm_replacement_out is to read out the parts of the
562    execution state that cannot be accessed from C code, store this state,
563    and then call the C function replace_me.
564
565    Stack layout:
566       16                start of stack inside method to replace
567       0   rplpoint *    info on the replacement point that was reached
568
569    NOTE: itmp3 has been clobbered by the replacement-out stub!
570
571 *******************************************************************************/
572
573 /* some room to accomodate changes of the stack frame size during replacement */
574         /* XXX we should find a cleaner solution here */
575 #define REPLACEMENT_ROOM  512
576
577 #define sizeexecutionstate_ALIGNED  ((sizeexecutionstate + 15) & ~15)
578
579 asm_replacement_out:
580     /* create stack frame */
581         addi    sp,sp,-(sizeexecutionstate_ALIGNED + REPLACEMENT_ROOM)
582
583         /* save link register */
584         mflr    itmp3
585
586         /* save registers in execution state */
587         stw     r0 ,( 0*4+offes_intregs)(sp)
588         stw     r1 ,( 1*4+offes_intregs)(sp)
589         stw     r2 ,( 2*4+offes_intregs)(sp)
590         stw     r3 ,( 3*4+offes_intregs)(sp)
591         stw     r4 ,( 4*4+offes_intregs)(sp)
592         stw     r5 ,( 5*4+offes_intregs)(sp)
593         stw     r6 ,( 6*4+offes_intregs)(sp)
594         stw     r7 ,( 7*4+offes_intregs)(sp)
595         stw     r8 ,( 8*4+offes_intregs)(sp)
596         stw     r9 ,( 9*4+offes_intregs)(sp)
597         stw     r10,(10*4+offes_intregs)(sp)
598         stw     r11,(11*4+offes_intregs)(sp)
599         stw     r12,(12*4+offes_intregs)(sp)
600         stw     r13,(13*4+offes_intregs)(sp)
601         stw     r14,(14*4+offes_intregs)(sp)
602         stw     r15,(15*4+offes_intregs)(sp)
603         stw     r16,(16*4+offes_intregs)(sp) /* link register stored as itmp3 */
604         stw     r17,(17*4+offes_intregs)(sp)
605         stw     r18,(18*4+offes_intregs)(sp)
606         stw     r19,(19*4+offes_intregs)(sp)
607         stw     r20,(20*4+offes_intregs)(sp)
608         stw     r21,(21*4+offes_intregs)(sp)
609         stw     r22,(22*4+offes_intregs)(sp)
610         stw     r23,(23*4+offes_intregs)(sp)
611         stw     r24,(24*4+offes_intregs)(sp)
612         stw     r25,(25*4+offes_intregs)(sp)
613         stw     r26,(26*4+offes_intregs)(sp)
614         stw     r27,(27*4+offes_intregs)(sp)
615         stw     r28,(28*4+offes_intregs)(sp)
616         stw     r29,(29*4+offes_intregs)(sp)
617         stw     r30,(30*4+offes_intregs)(sp)
618         stw     r31,(31*4+offes_intregs)(sp)
619         
620         stfd    fr0 ,( 0*8+offes_fltregs)(sp)
621         stfd    fr1 ,( 1*8+offes_fltregs)(sp)
622         stfd    fr2 ,( 2*8+offes_fltregs)(sp)
623         stfd    fr3 ,( 3*8+offes_fltregs)(sp)
624         stfd    fr4 ,( 4*8+offes_fltregs)(sp)
625         stfd    fr5 ,( 5*8+offes_fltregs)(sp)
626         stfd    fr6 ,( 6*8+offes_fltregs)(sp)
627         stfd    fr7 ,( 7*8+offes_fltregs)(sp)
628         stfd    fr8 ,( 8*8+offes_fltregs)(sp)
629         stfd    fr9 ,( 9*8+offes_fltregs)(sp)
630         stfd    fr10,(10*8+offes_fltregs)(sp)
631         stfd    fr11,(11*8+offes_fltregs)(sp)
632         stfd    fr12,(12*8+offes_fltregs)(sp)
633         stfd    fr13,(13*8+offes_fltregs)(sp)
634         stfd    fr14,(14*8+offes_fltregs)(sp)
635         stfd    fr15,(15*8+offes_fltregs)(sp)
636         stfd    fr16,(16*8+offes_fltregs)(sp)
637         stfd    fr17,(17*8+offes_fltregs)(sp)
638         stfd    fr18,(18*8+offes_fltregs)(sp)
639         stfd    fr19,(19*8+offes_fltregs)(sp)
640         stfd    fr20,(20*8+offes_fltregs)(sp)
641         stfd    fr21,(21*8+offes_fltregs)(sp)
642         stfd    fr22,(22*8+offes_fltregs)(sp)
643         stfd    fr23,(23*8+offes_fltregs)(sp)
644         stfd    fr24,(24*8+offes_fltregs)(sp)
645         stfd    fr25,(25*8+offes_fltregs)(sp)
646         stfd    fr26,(26*8+offes_fltregs)(sp)
647         stfd    fr27,(27*8+offes_fltregs)(sp)
648         stfd    fr28,(28*8+offes_fltregs)(sp)
649         stfd    fr29,(29*8+offes_fltregs)(sp)
650         stfd    fr30,(30*8+offes_fltregs)(sp)
651         stfd    fr31,(31*8+offes_fltregs)(sp)
652         
653         /* calculate sp of method */
654         addi    itmp1,sp,(sizeexecutionstate_ALIGNED + REPLACEMENT_ROOM + 4*4)
655         stw     itmp1,(offes_sp)(sp)
656
657         /* store pv */
658         stw     pv,(offes_pv)(sp)
659
660         /* call replace_me */
661         lwz     a0,-(4*4)(itmp1)            /* arg0: rplpoint *                   */
662         mr      a1,sp                       /* arg1: execution state              */
663         addi    sp,sp,-(LA_SIZE_ALIGNED)
664         b       replace_me                  /* call C function replace_me         */
665
666 /* asm_replacement_in **********************************************************
667
668    This code writes the given execution state and jumps to the replacement
669    code.
670
671    This function never returns!
672
673    NOTE: itmp3 is not restored!
674
675    C prototype:
676       void asm_replacement_in(executionstate *es, replace_safestack_t *st);
677
678 *******************************************************************************/
679
680 asm_replacement_in:
681         /* a0 == executionstate *es      */
682         /* a1 == replace_safestack_t *st */
683
684         /* get arguments */
685         mr              s1,a1                       /* replace_safestack_t *st            */
686         mr              s2,a0                       /* executionstate *es == safe stack   */
687
688         /* switch to the safe stack */
689         mr              sp,s2
690
691         /* reserve linkage area */
692         addi    sp,sp,-(LA_SIZE_ALIGNED)
693
694         /* call replace_build_execution_state(st) */
695         mr              a0,s1
696         bl              replace_build_execution_state
697
698         /* set new sp */
699         lwz             sp,(offes_sp)(s2)
700
701         /* build stack frame */
702         addi    sp,sp,-(sizeexecutionstate_ALIGNED)
703
704         /* call replace_free_safestack(st,& of allocated executionstate_t) */
705         mr              a1,sp /* tmpes */
706         mr              a0,s1 /* st    */
707         addi    sp,sp,-(LA_SIZE_ALIGNED)  /* reserve linkage area */
708         bl              replace_free_safestack
709         addi    sp,sp,+(LA_SIZE_ALIGNED)  /* tear down linkage area */
710
711         /* set new pv */
712         lwz     pv,(offes_pv)(sp)
713         
714         /* copy registers from execution state */
715         lwz     r0 ,( 0*4+offes_intregs)(sp)
716         /* r1 is sp                       */
717         /* r2 is reserved                 */
718         lwz     a0 ,( 3*4+offes_intregs)(sp)
719         lwz     r4 ,( 4*4+offes_intregs)(sp)
720         lwz     r5 ,( 5*4+offes_intregs)(sp)
721         lwz     r6 ,( 6*4+offes_intregs)(sp)
722         lwz     r7 ,( 7*4+offes_intregs)(sp)
723         lwz     r8 ,( 8*4+offes_intregs)(sp)
724         lwz     r9 ,( 9*4+offes_intregs)(sp)
725         lwz     r10,(10*4+offes_intregs)(sp)
726         lwz     r11,(11*4+offes_intregs)(sp)
727         lwz     r12,(12*4+offes_intregs)(sp)
728         /* r13 is pv                      */
729         lwz     r14,(14*4+offes_intregs)(sp)
730         lwz     r15,(15*4+offes_intregs)(sp)
731         lwz     r16,(16*4+offes_intregs)(sp) /* itmp3, later to link register */
732         lwz     r17,(17*4+offes_intregs)(sp)
733         lwz     r18,(18*4+offes_intregs)(sp)
734         lwz     r19,(19*4+offes_intregs)(sp)
735         lwz     r20,(20*4+offes_intregs)(sp)
736         lwz     r21,(21*4+offes_intregs)(sp)
737         lwz     r22,(22*4+offes_intregs)(sp)
738         lwz     r23,(23*4+offes_intregs)(sp)
739         lwz     r24,(24*4+offes_intregs)(sp)
740         lwz     r25,(25*4+offes_intregs)(sp)
741         lwz     r26,(26*4+offes_intregs)(sp)
742         lwz     r27,(27*4+offes_intregs)(sp)
743         lwz     r28,(28*4+offes_intregs)(sp)
744         lwz     r29,(29*4+offes_intregs)(sp)
745         lwz     r30,(30*4+offes_intregs)(sp)
746         lwz     r31,(31*4+offes_intregs)(sp)
747         
748         lfd     fr0 ,( 0*8+offes_fltregs)(sp)
749         lfd     fr1 ,( 1*8+offes_fltregs)(sp)
750         lfd     fr2 ,( 2*8+offes_fltregs)(sp)
751         lfd     fr3 ,( 3*8+offes_fltregs)(sp)
752         lfd     fr4 ,( 4*8+offes_fltregs)(sp)
753         lfd     fr5 ,( 5*8+offes_fltregs)(sp)
754         lfd     fr6 ,( 6*8+offes_fltregs)(sp)
755         lfd     fr7 ,( 7*8+offes_fltregs)(sp)
756         lfd     fr8 ,( 8*8+offes_fltregs)(sp)
757         lfd     fr9 ,( 9*8+offes_fltregs)(sp)
758         lfd     fr10,(10*8+offes_fltregs)(sp)
759         lfd     fr11,(11*8+offes_fltregs)(sp)
760         lfd     fr12,(12*8+offes_fltregs)(sp)
761         lfd     fr13,(13*8+offes_fltregs)(sp)
762         lfd     fr14,(14*8+offes_fltregs)(sp)
763         lfd     fr15,(15*8+offes_fltregs)(sp)
764         lfd     fr16,(16*8+offes_fltregs)(sp)
765         lfd     fr17,(17*8+offes_fltregs)(sp)
766         lfd     fr18,(18*8+offes_fltregs)(sp)
767         lfd     fr19,(19*8+offes_fltregs)(sp)
768         lfd     fr20,(20*8+offes_fltregs)(sp)
769         lfd     fr21,(21*8+offes_fltregs)(sp)
770         lfd     fr22,(22*8+offes_fltregs)(sp)
771         lfd     fr23,(23*8+offes_fltregs)(sp)
772         lfd     fr24,(24*8+offes_fltregs)(sp)
773         lfd     fr25,(25*8+offes_fltregs)(sp)
774         lfd     fr26,(26*8+offes_fltregs)(sp)
775         lfd     fr27,(27*8+offes_fltregs)(sp)
776         lfd     fr28,(28*8+offes_fltregs)(sp)
777         lfd     fr29,(29*8+offes_fltregs)(sp)
778         lfd     fr30,(30*8+offes_fltregs)(sp)
779         lfd     fr31,(31*8+offes_fltregs)(sp)
780
781         /* restore link register */
782
783         mtlr    itmp3
784         
785         /* load new pc */
786
787         lwz     itmp3,offes_pc(sp)
788
789         /* remove stack frame */
790
791         addi    sp,sp,+(sizeexecutionstate_ALIGNED)
792
793         /* jump to new code */
794
795         mtctr   itmp3
796         bctr
797
798 #endif /* defined(ENABLE_REPLACEMENT) */
799
800 /*********************************************************************/
801
802 asm_cacheflush:
803         add     a1,a0,a1
804         rlwinm  a0,a0,0,0,26
805         addi    a1,a1,31
806         rlwinm  a1,a1,0,0,26
807         mr      a2,a0
808 1:
809         cmplw   a0,a1
810         bge     0f
811         dcbst   0,a0
812         addi    a0,a0,32
813         b       1b
814 0:
815         sync
816 1:
817         cmplw   a2,a1
818         bge     0f
819         icbi    0,a2
820         addi    a2,a2,32
821         b       1b
822 0:
823         sync
824         isync
825         blr
826
827
828 /* asm_compare_and_swap ********************************************************
829
830    XXX
831
832 *******************************************************************************/
833
834 asm_compare_and_swap:
835 1:
836         lwarx   a6,0,a0 
837         subf.   r0,a6,a1 
838         bne-    2f 
839         or      r0,a2,a2 
840         stwcx.  r0,0,a0 
841         bne-    1b 
842 2: 
843         mr      a0,a6
844         blr
845
846
847 /* asm_memory_barrier **********************************************************
848
849    XXX
850
851 *******************************************************************************/
852
853 asm_memory_barrier:
854         sync
855         blr
856
857
858 #if defined(__DARWIN__)
859
860 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
861         .align 2
862 L_builtin_throw_exception$stub:
863         .indirect_symbol _builtin_throw_exception
864         mflr r0
865         bcl 20,31,L00$_builtin_throw_exception
866 L00$_builtin_throw_exception:
867         mflr r11
868         addis r11,r11,ha16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)
869         mtlr r0
870         lwzu r12,lo16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)(r11)
871         mtctr r12
872         bctr
873 .data
874 .lazy_symbol_pointer
875 L_builtin_throw_exception$lazy_ptr:
876         .indirect_symbol _builtin_throw_exception
877         .long dyld_stub_binding_helper
878
879
880 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
881         .align 2
882 L_md_codegen_get_pv_from_pc$stub:
883         .indirect_symbol _md_codegen_get_pv_from_pc
884         mflr r0
885         bcl 20,31,L00$_md_codegen_get_pv_from_pc
886 L00$_md_codegen_get_pv_from_pc:
887         mflr r11
888         addis r11,r11,ha16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc)
889         mtlr r0
890         lwzu r12,lo16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc)(r11)
891         mtctr r12
892         bctr
893 .data
894 .lazy_symbol_pointer
895 L_md_codegen_get_pv_from_pc$lazy_ptr:
896         .indirect_symbol _md_codegen_get_pv_from_pc
897         .long dyld_stub_binding_helper
898
899
900 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
901         .align 2
902 L_exceptions_handle_exception$stub:
903         .indirect_symbol _exceptions_handle_exception
904         mflr r0
905         bcl 20,31,L00$_exceptions_handle_exception
906 L00$_exceptions_handle_exception:
907         mflr r11
908         addis r11,r11,ha16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)
909         mtlr r0
910         lwzu r12,lo16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)(r11)
911         mtctr r12
912         bctr
913 .data
914 .lazy_symbol_pointer
915 L_exceptions_handle_exception$lazy_ptr:
916         .indirect_symbol _exceptions_handle_exception
917         .long dyld_stub_binding_helper
918
919
920 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
921         .align 2
922 L_stacktrace_create_extern_stackframeinfo$stub:
923         .indirect_symbol _stacktrace_create_extern_stackframeinfo
924         mflr r0
925         bcl 20,31,L00$_stacktrace_create_extern_stackframeinfo
926 L00$_stacktrace_create_extern_stackframeinfo:
927         mflr r11
928         addis r11,r11,ha16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)
929         mtlr r0
930         lwzu r12,lo16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)(r11)
931         mtctr r12
932         bctr
933 .data
934 .lazy_symbol_pointer
935 L_stacktrace_create_extern_stackframeinfo$lazy_ptr:
936         .indirect_symbol _stacktrace_create_extern_stackframeinfo
937         .long dyld_stub_binding_helper
938
939
940 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
941         .align 2
942 L_jit_asm_compile$stub:
943         .indirect_symbol _jit_asm_compile
944         mflr r0
945         bcl 20,31,L00$_jit_asm_compile
946 L00$_jit_asm_compile:
947         mflr r11
948         addis r11,r11,ha16(L_jit_asm_compile$lazy_ptr - L00$_jit_asm_compile)
949         mtlr r0
950         lwzu r12,lo16(L_jit_asm_compile$lazy_ptr - L00$_jit_asm_compile)(r11)
951         mtctr r12
952         bctr
953 .data
954 .lazy_symbol_pointer
955 L_jit_asm_compile$lazy_ptr:
956         .indirect_symbol _jit_asm_compile
957         .long dyld_stub_binding_helper
958
959
960 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
961         .align 2
962 L_stacktrace_remove_stackframeinfo$stub:
963         .indirect_symbol _stacktrace_remove_stackframeinfo
964         mflr r0
965         bcl 20,31,L00$_stacktrace_remove_stackframeinfo
966 L00$_stacktrace_remove_stackframeinfo:
967         mflr r11
968         addis r11,r11,ha16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)
969         mtlr r0
970         lwzu r12,lo16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)(r11)
971         mtctr r12
972         bctr
973 .data
974 .lazy_symbol_pointer
975 L_stacktrace_remove_stackframeinfo$lazy_ptr:
976         .indirect_symbol _stacktrace_remove_stackframeinfo
977         .long dyld_stub_binding_helper
978
979
980 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
981         .align 2
982 L_exceptions_get_and_clear_exception$stub:
983         .indirect_symbol _exceptions_get_and_clear_exception
984         mflr r0
985         bcl 20,31,L00$_exceptions_get_and_clear_exception
986 L00$_exceptions_get_and_clear_exception:
987         mflr r11
988         addis r11,r11,ha16(L_exceptions_get_and_clear_exception$lazy_ptr - L00$_exceptions_get_and_clear_exception)
989         mtlr r0
990         lwzu r12,lo16(L_exceptions_get_and_clear_exception$lazy_ptr - L00$_exceptions_get_and_clear_exception)(r11)
991         mtctr r12
992         bctr
993 .data
994 .lazy_symbol_pointer
995 L_exceptions_get_and_clear_exception$lazy_ptr:
996         .indirect_symbol _exceptions_get_and_clear_exception
997         .long dyld_stub_binding_helper
998
999
1000 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1001         .align 2
1002 L_exceptions_asm_new_abstractmethoderror$stub:
1003         .indirect_symbol _exceptions_asm_new_abstractmethoderror
1004         mflr r0
1005         bcl 20,31,L00$_exceptions_asm_new_abstractmethoderror
1006 L00$_exceptions_asm_new_abstractmethoderror:
1007         mflr r11
1008         addis r11,r11,ha16(L_exceptions_asm_new_abstractmethoderror$lazy_ptr - L00$_exceptions_asm_new_abstractmethoderror)
1009         mtlr r0
1010         lwzu r12,lo16(L_exceptions_asm_new_abstractmethoderror$lazy_ptr - L00$_exceptions_asm_new_abstractmethoderror)(r11)
1011         mtctr r12
1012         bctr
1013 .data
1014 .lazy_symbol_pointer
1015 L_exceptions_asm_new_abstractmethoderror$lazy_ptr:
1016         .indirect_symbol _exceptions_asm_new_abstractmethoderror
1017         .long dyld_stub_binding_helper
1018
1019
1020 # if defined(ENABLE_REPLACEMENT)
1021
1022 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1023         .align 2
1024 L_replace_me$stub:
1025         .indirect_symbol _replace_me
1026         mflr r0
1027         bcl 20,31,L00$_replace_me
1028 L00$_replace_me:
1029         mflr r11
1030         addis r11,r11,ha16(L_replace_me$lazy_ptr - L00$_replace_me)
1031         mtlr r0
1032         lwzu r12,lo16(L_replace_me$lazy_ptr - L00$_replace_me)(r11)
1033         mtctr r12
1034         bctr
1035 .data
1036 .lazy_symbol_pointer
1037 L_replace_me$lazy_ptr:
1038         .indirect_symbol _replace_me
1039         .long dyld_stub_binding_helper
1040
1041
1042 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1043         .align 2
1044 L_replace_build_execution_state$stub:
1045         .indirect_symbol _replace_build_execution_state
1046         mflr r0
1047         bcl 20,31,L00$_replace_build_execution_state
1048 L00$_replace_build_execution_state:
1049         mflr r11
1050         addis r11,r11,ha16(L_replace_build_execution_state$lazy_ptr - L00$_replace_build_execution_state)
1051         mtlr r0
1052         lwzu r12,lo16(L_replace_build_execution_state$lazy_ptr - L00$_replace_build_execution_state)(r11)
1053         mtctr r12
1054         bctr
1055 .data
1056 .lazy_symbol_pointer
1057 L_replace_build_execution_state$lazy_ptr:
1058         .indirect_symbol _replace_build_execution_state
1059         .long dyld_stub_binding_helper
1060
1061
1062 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1063         .align 2
1064 L_replace_free_safestack$stub:
1065         .indirect_symbol _replace_free_safestack
1066         mflr r0
1067         bcl 20,31,L00$_replace_free_safestack
1068 L00$_replace_free_safestack:
1069         mflr r11
1070         addis r11,r11,ha16(L_replace_free_safestack$lazy_ptr - L00$_replace_free_safestack)
1071         mtlr r0
1072         lwzu r12,lo16(L_replace_free_safestack$lazy_ptr - L00$_replace_free_safestack)(r11)
1073         mtctr r12
1074         bctr
1075 .data
1076 .lazy_symbol_pointer
1077 L_replace_free_safestack$lazy_ptr:
1078         .indirect_symbol _replace_free_safestack
1079         .long dyld_stub_binding_helper
1080
1081 # endif /* ENABLE_REPLACEMENT */
1082
1083 #endif /* defined(__DARWIN__) */
1084
1085
1086 /* disable exec-stacks ********************************************************/
1087
1088 #if defined(__linux__) && defined(__ELF__)
1089         .section .note.GNU-stack,"",%progbits
1090 #endif
1091
1092
1093 /*
1094  * These are local overrides for various environment variables in Emacs.
1095  * Please do not remove this and leave it at the end of the file, where
1096  * Emacs will automagically detect them.
1097  * ---------------------------------------------------------------------
1098  * Local variables:
1099  * mode: asm
1100  * indent-tabs-mode: t
1101  * c-basic-offset: 4
1102  * tab-width: 4
1103  * End:
1104  * vim:noexpandtab:sw=4:ts=4:
1105  */