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