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