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