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