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