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