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