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