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