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