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