1 /* src/vm/jit/powerpc64/asmpart.S - Java-C interface functions for PowerPC64
3 Copyright (C) 1996-2005, 2006, 2007 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
8 This file is part of CACAO.
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.
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.
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
25 $Id: asmpart.S 7909 2007-05-15 10:32:16Z tbfg $
37 #include "vm/jit/abi-asm.h"
38 #include "vm/jit/methodheader.h"
39 #include "vm/jit/powerpc64/offsets.h"
47 /* export functions ***********************************************************/
49 .globl asm_vm_call_method_exception_handler
50 .globl asm_vm_call_method_end
52 .globl asm_call_jit_compiler
54 .globl asm_handle_nat_exception
55 .globl asm_handle_exception
57 .globl asm_abstractmethoderror
59 .globl asm_patcher_wrapper
61 #if defined(ENABLE_REPLACEMENT)
62 .globl asm_replacement_out
63 .globl .asm_replacement_in
67 .globl asm_criticalsections
68 .globl asm_getclassvalues_atomic
71 /* asm_vm_call_method **********************************************************
73 * This function calls a Java-method (which possibly needs compilation) *
74 * with up to 4 address parameters. *
76 * This functions calls the JIT-compiler which eventually translates the *
77 * method into machine code. *
80 * javaobject_header *asm_calljavamethod (methodinfo *m, *
81 * void *arg1, void *arg2, void *arg3, void *arg4); *
83 *******************************************************************************/
84 /* this is the method header see src/vm/jit/methodheader.h */
88 .quad 0 /* catch type all */
89 .quad 0 /* handler pc */
91 .quad 0 /* start pc */
92 .long 1 /* extable size */
93 .long 0 /* ALIGNMENT PADDING */
94 .quad 0 /* line number table start */
95 .quad 0 /* line number table size */
96 .long 0 /* ALIGNMENT PADDING */
101 .long 0 /* frame size */
102 .quad 0 /* codeinfo pointer */
106 .globl asm_vm_call_method
107 .globl asm_vm_call_method_int
108 .globl asm_vm_call_method_long
109 .globl asm_vm_call_method_float
110 .globl asm_vm_call_method_double
115 asm_vm_call_method_int:
116 asm_vm_call_method_long:
117 asm_vm_call_method_float:
118 asm_vm_call_method_double:
119 .quad .asm_vm_call_method,.TOC.@tocbase,0
121 .size asm_vm_call_method, 24
122 .type .asm_vm_call_method,@function
123 .globl .asm_vm_call_method
126 .globl asm_vm_call_method
127 asm_vm_call_method_int:
128 .globl asm_vm_call_method_int
129 asm_vm_call_method_long:
130 .globl asm_vm_call_method_long
131 asm_vm_call_method_float:
132 .globl asm_vm_call_method_float
133 asm_vm_call_method_double:
134 .globl asm_vm_call_method_double
138 .asm_vm_call_method_int:
139 .asm_vm_call_method_long:
140 .asm_vm_call_method_float:
141 .asm_vm_call_method_double:
143 std r0,LA_LR_OFFSET(sp)
146 std s0,8*8(sp) /* save used callee saved registers */
147 std a0,9*8(sp) /* save method pointer for compiler */
149 std pv,11*8(sp) /* save PV register */
151 std itmp3,12*8(sp) /* registers r14-r31 are callee saved */
152 stfd ftmp1,13*8(sp) /* registers f14-f31 are callee saved */
155 SAVE_TEMPORARY_REGISTERS(15)
157 mr itmp2,a1 /* arg count */
158 mr itmp1,a2 /* pointer to arg block */
160 mr t4,itmp2 /* save argument count */
161 mr t5,itmp1 /* save argument block pointer */
163 mr s0,sp /* save current sp to s0 */
165 addi itmp1,itmp1,-sizevmarg /* initialize pointer (smaller code) */
166 addi itmp2,itmp2,1 /* initialize argument count */
167 li t0,0 /* initialize integer argument counter */
168 li t1,0 /* initialize float argument counter */
169 li t6,0 /* initialize integer register counter */
170 li t3,8 /* initialize PA counter*/
173 addi itmp1,itmp1,sizevmarg /* goto next argument block */
174 addi itmp2,itmp2,-1 /* argument count - 1 */
176 beq L_register_copy_done
178 addi t3,t3,-1 /* uses a PA slot */
179 lwz itmp3,offvmargtype+4(itmp1)
180 andi. r0,itmp3,0x0002 /* is this a float/double type? */
181 bne L_register_handle_float
183 L_register_handle_int:
184 cmpwi t6,INT_ARG_CNT /* are we out of integer argument */
185 beq L_register_copy /* registers? yes, next loop */
187 cmpwi itmp3,0x0004 /* is it TYPE_ADR? */
188 beq L_register_handle_long
190 andi. r0,itmp3,0x0001 /* is this a 2-word type? */
191 bne L_register_handle_long
193 lis itmp3,L_jumptable_int@highest /* load 64bit address */
194 ori itmp3,itmp3,L_jumptable_int@higher
195 rldicr itmp3,itmp3,32,31
196 oris itmp3,itmp3,L_jumptable_int@h
197 ori itmp3,itmp3,L_jumptable_int@l
198 b L_register_do_copy_longint
200 L_register_handle_long:
202 lis itmp3,L_jumptable_long@highest /* load 64bit address */
203 ori itmp3,itmp3,L_jumptable_long@higher
204 rldicr itmp3,itmp3,32,31
205 oris itmp3,itmp3,L_jumptable_long@h
206 ori itmp3,itmp3,L_jumptable_long@l
208 L_register_do_copy_longint:
209 slwi t2,t6,3 /* multiple of 8-bytes */
210 add itmp3,itmp3,t2 /* calculate address of jumptable */
211 ld itmp3,0(itmp3) /* load function address */
213 addi t0,t0,1 /* integer argument counter */
214 addi t6,t6,1 /* integer argument register counter */
217 L_register_handle_float:
218 cmpwi t1,FLT_ARG_CNT /* are we out of float argument */
219 beq L_register_copy /* registers? yes, next loop */
221 andi. r0,itmp3,0x0001 /* is this a 2-word type? */
222 bne L_register_handle_double
224 lis itmp3,L_jumptable_float@highest /* load 64bit address */
225 ori itmp3,itmp3,L_jumptable_float@higher
226 rldicr itmp3,itmp3,32,31
227 oris itmp3,itmp3,L_jumptable_float@h
228 ori itmp3,itmp3,L_jumptable_float@l
229 b L_register_do_copy_floatdouble
231 L_register_handle_double:
233 lis itmp3,L_jumptable_double@highest /* load 64bit address */
234 ori itmp3,itmp3,L_jumptable_double@higher
235 rldicr itmp3,itmp3,32,31
236 oris itmp3,itmp3,L_jumptable_double@h
237 ori itmp3,itmp3,L_jumptable_double@l
240 L_register_do_copy_floatdouble:
242 slwi t2,t1,3 /* multiple of 8-bytes */
243 add itmp3,itmp3,t2 /* calculate address of jumptable */
244 ld itmp3,0(itmp3) /* load function address */
246 addi t1,t1,1 /* float argument counter */
247 mr. t3,t3 /* are we still in PA ? */
248 blt L_float_not_uses_PA
249 addi t6,t6,1 /* if so it uses an interger arg reg */
254 L_register_copy_done:
255 subi sp,sp,PA_SIZE /* PA_SIZE are used by definition */
256 /* calculate remaining arguments */
257 sub itmp3,t4,t0 /* - integer arguments in registers */
258 sub itmp3,itmp3,t1 /* - float arguments in registers */
260 beq L_stack_copy_done
262 mr itmp2,t4 /* restore argument count */
263 mr itmp1,t5 /* restore argument block pointer */
265 slwi t4,itmp3,3 /* XXX use 8-bytes slots for now */
266 addi t4,t4,LA_SIZE /* add size of linkage area */
269 mr t6,sp /* use t6 as temporary sp */
270 addi t6,t6,LA_SIZE /* skip linkage area */
272 addi itmp1,itmp1,-sizevmarg /* initialize pointer (smaller code) */
273 addi itmp2,itmp2,1 /* initialize argument count */
274 li t3,8 /* initialize PA counter */
275 addi t6,t6,-8 /* make code simpler */
278 addi itmp1,itmp1,sizevmarg /* goto next argument block */
279 addi itmp2,itmp2,-1 /* argument count - 1 */
281 beq L_stack_copy_done
282 addi t6,t6,8 /* increase stack */
285 lwz itmp3,offvmargtype+4(itmp1)
286 andi. r0,itmp3,0x0002 /* is this a float/double type? */
287 bne L_stack_handle_float
290 addi t0,t0,-1 /* arguments assigned to registers */
292 bge L_stack_copy_loop
294 andi. r0,itmp3,0x0001 /* is this a 2-word type? */
295 bne L_stack_handle_long
297 lwa itmp3,offvmargdata+4(itmp1) /* get integer argument */
298 std itmp3,0(t6) /* and store it on the stack */
302 ld itmp3,offvmargdata+0(itmp1) /* get long argument */
303 std itmp3,0(t6) /* and store it on the stack */
306 L_stack_handle_float:
307 addi t1,t1,-1 /* arguments assigned to registers */
309 bge L_stack_copy_loop
311 andi. r0,itmp3,0x0001 /* is this a 2-word type? */
312 bne L_stack_handle_double
314 lfs ftmp3,offvmargdata(itmp1) /* get float argument */
315 stfd ftmp3,0(t6) /* and store it on the stack */
318 L_stack_handle_double:
319 lfd ftmp3,offvmargdata(itmp1) /* get double argument */
320 stfd ftmp3,0(t6) /* and store it on the stack */
324 ld itmp1,9*8(s0) /* pass method pointer via tmp1 */
326 lis mptr,L_asm_call_jit_compiler@highest /* load 64bit address */
327 ori mptr,mptr,L_asm_call_jit_compiler@higher
328 rldicr mptr,mptr,32,31
329 oris mptr,mptr,L_asm_call_jit_compiler@h
330 ori mptr,mptr,L_asm_call_jit_compiler@l
340 addi pv,itmp1,(.asm_vm_call_method - 1b)@l
342 L_asm_vm_call_method_return:
343 mr sp,s0 /* restore the function's sp */
345 ld s0,8*8(sp) /* restore used callee saved registers */
347 ld pv,11*8(sp) /* save PV register */
350 lfd ftmp1,13*8(sp) /* registers f14-f31 are callee saved */
353 RESTORE_TEMPORARY_REGISTERS(15)
355 ld r0,40*8+LA_LR_OFFSET(r1)
360 asm_vm_call_method_exception_handler:
362 bl builtin_throw_exception
363 b L_asm_vm_call_method_return
383 lwa a0,offvmargdata+4(itmp1)
386 lwa a1,offvmargdata+4(itmp1)
389 lwa a2,offvmargdata+4(itmp1)
392 lwa a3,offvmargdata+4(itmp1)
395 lwa a4,offvmargdata+4(itmp1)
398 lwa a5,offvmargdata+4(itmp1)
401 lwa a6,offvmargdata+4(itmp1)
404 lwa a7,offvmargdata+4(itmp1)
425 ld a0,offvmargdata(itmp1)
428 ld a1,offvmargdata(itmp1)
431 ld a2,offvmargdata(itmp1)
434 ld a3,offvmargdata(itmp1)
437 ld a4,offvmargdata(itmp1)
440 ld a5,offvmargdata(itmp1)
443 ld a6,offvmargdata(itmp1)
446 ld a7,offvmargdata(itmp1)
471 lfs fa0,offvmargdata(itmp1)
474 lfs fa1,offvmargdata(itmp1)
477 lfs fa2,offvmargdata(itmp1)
480 lfs fa3,offvmargdata(itmp1)
483 lfs fa4,offvmargdata(itmp1)
486 lfs fa5,offvmargdata(itmp1)
489 lfs fa6,offvmargdata(itmp1)
492 lfs fa7,offvmargdata(itmp1)
495 lfs fa8,offvmargdata(itmp1)
498 lfs fa9,offvmargdata(itmp1)
501 lfs fa10,offvmargdata(itmp1)
504 lfs fa11,offvmargdata(itmp1)
507 lfs fa12,offvmargdata(itmp1)
532 lfd fa0,offvmargdata(itmp1)
535 lfd fa1,offvmargdata(itmp1)
538 lfd fa2,offvmargdata(itmp1)
541 lfd fa3,offvmargdata(itmp1)
544 lfd fa4,offvmargdata(itmp1)
547 lfd fa5,offvmargdata(itmp1)
550 lfd fa6,offvmargdata(itmp1)
553 lfd fa7,offvmargdata(itmp1)
556 lfd fa8,offvmargdata(itmp1)
559 lfd fa9,offvmargdata(itmp1)
562 lfd fa10,offvmargdata(itmp1)
565 lfd fa11,offvmargdata(itmp1)
568 lfd fa12,offvmargdata(itmp1)
571 asm_vm_call_method_end:
574 /* asm_call_jit_compiler *******************************************************
576 Invokes the compiler for untranslated JavaVM methods.
578 *******************************************************************************/
580 asm_call_jit_compiler:
581 L_asm_call_jit_compiler: /* required for PIC code */
583 std r0,LA_LR_OFFSET(sp) /* save return address */
584 stdu r1,-(LA_SIZE+PA_SIZE+ARG_CNT*8)(sp)
586 SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS)
590 addi a2,sp,(LA_SIZE + PA_SIZE+ ARG_CNT*8)
591 ld a3,(LA_SIZE + PA_SIZE + ARG_CNT*8)+LA_LR_OFFSET(sp)
593 ori r0,r0,0 /* nop needed after jump to function desc. */
594 mr pv,v0 /* move address to pv register */
596 RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS)
598 ld itmp1,(LA_SIZE + PA_SIZE + ARG_CNT*8)+LA_LR_OFFSET(sp)
601 addi sp,sp,(LA_SIZE + PA_SIZE + ARG_CNT*8)
603 mr. pv,pv /* test for exception */
604 beq L_asm_call_jit_compiler_exception
606 mtctr pv /* move method address to control reg */
607 bctr /* and call the Java method */
609 L_asm_call_jit_compiler_exception:
611 std r0,LA_LR_OFFSET(sp)
612 stdu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
613 bl exceptions_get_and_clear_exception
614 ld xpc,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
616 addi sp,sp,LA_SIZE_ALIGNED
618 mr xptr,v0 /* get exception */
619 addi xpc,xpc,-4 /* exception address is ra - 4 */
620 b L_asm_handle_nat_exception
623 /********************* function asm_handle_exception ***************************
625 * This function handles an exception. It does not use the usual calling *
626 * conventions. The exception pointer is passed in REG_ITMP1 and the *
627 * pc from the exception raising position is passed in REG_ITMP2. It searches *
628 * the local exception table for a handler. If no one is found, it unwinds *
629 * stacks and continues searching the callers. *
631 * void asm_handle_exception (exceptionptr, exceptionpc); *
633 *******************************************************************************/
635 asm_handle_nat_exception:
636 L_asm_handle_nat_exception: /* required for PIC code */
637 L_asm_handle_exception_stack_loop:
639 addi sp,sp,-(LA_SIZE+PA_SIZE+((4+6)*8)) /* allocate stack (+4 for darwin) */
640 std xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* save exception pointer */
641 std xpc,LA_SIZE+PA_SIZE+(4+1)*8(sp) /* save exception pc */
642 std r0,LA_SIZE+PA_SIZE+(4+3)*8(sp) /* save return address */
644 std itmp3,LA_SIZE+PA_SIZE+(4+4)*8(sp) /* save maybe-leaf flag (cleared) */
646 mr a0,r0 /* pass return address */
647 bl md_codegen_get_pv_from_pc /* get PV from RA */
648 std v0,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* save data segment pointer */
650 ld a0,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* pass xptr */
651 ld a1,LA_SIZE+PA_SIZE+(4+1)*8(sp) /* pass xpc */
652 ld a2,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* pass PV (v0 == a0) */
653 addi a3,sp,LA_SIZE+PA_SIZE+((4+6)*8) /* pass Java SP */
655 b L_asm_handle_exception_continue
658 asm_handle_exception:
659 L_asm_handle_exception: /* required for PIC code */
660 addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
662 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
663 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
665 addi sp,sp,-(LA_SIZE+PA_SIZE+(4+6)*8) /* allocate stack */
666 std xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* save exception pointer */
667 std pv,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* save data segment pointer */
668 mflr r0 /* save return address */
669 std r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)
671 std t0, LA_SIZE+PA_SIZE+(4+4)*8(sp) /* maybe-leaf flag */
673 mr a0,xptr /* pass exception pointer */
674 mr a1,xpc /* pass exception pc */
675 mr a2,pv /* pass data segment pointer */
676 addi a3,sp,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+(4+6)*8
679 L_asm_handle_exception_continue:
680 bl exceptions_handle_exception
683 beq L_asm_handle_exception_not_catched
685 mr xpc,v0 /* move handlerpc into xpc */
686 ld xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* restore exception pointer */
687 ld pv,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* restore data segment pointer */
688 ld r0,LA_SIZE+PA_SIZE+(4+3)*8(sp) /* restore return address */
690 ld t0,LA_SIZE+PA_SIZE+(4+4)*8(sp) /* get maybe-leaf flag */
691 addi sp,sp,LA_SIZE+PA_SIZE+(4+6)*8 /* free stack frame */
694 beq L_asm_handle_exception_no_leaf
696 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
697 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
699 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
701 L_asm_handle_exception_no_leaf:
702 mtctr xpc /* jump to the handler */
705 L_asm_handle_exception_not_catched:
706 ld xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* restore exception pointer */
707 ld pv,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* restore data segment pointer */
708 ld r0,LA_SIZE+PA_SIZE+(4+3)*8(sp) /* restore return address */
710 ld t0,LA_SIZE+PA_SIZE+(4+4)*8(sp) /* get maybe-leaf flag */
711 addi sp,sp,LA_SIZE+PA_SIZE+(4+6)*8 /* free stack frame */
714 beq L_asm_handle_exception_no_leaf_stack
716 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
717 li t0,0 /* clear the maybe-leaf flag */
719 L_asm_handle_exception_no_leaf_stack:
720 lwz t1,FrameSize(pv) /* get frame size */
721 add t1,sp,t1 /* pointer to save area */
723 lwz t2,IsLeaf(pv) /* is leaf procedure */
725 bne L_asm_handle_exception_no_ra_restore
727 ld r0,LA_LR_OFFSET(t1) /* restore ra */
730 L_asm_handle_exception_no_ra_restore:
731 mflr xpc /* the new xpc is ra */
732 mr t4,xpc /* save RA */
733 lwz t2,IntSave(pv) /* t1 = saved int register count */
736 mflr t3 /* t3 = current pc */
737 addi t3,t3,(ex_int2-ex_int1)@l
738 slwi t2,t2,2 /* t2 = register count * 4 */
739 subf t3,t2,t3 /* t3 = IntSave - t2 */
754 subf t1,t2,t1 /* t1 = t1 - register count * 4 */
759 addi t3,t3,(ex_flt2-ex_flt1)@l
760 slwi t2,t2,2 /* t2 = register count * 4 */
761 subf t3,t2,t3 /* t3 = FltSave - t2 */
777 mtlr t4 /* restore RA */
779 add sp,sp,t1 /* unwind stack */
780 b L_asm_handle_exception_stack_loop
783 /* asm_abstractmethoderror *****************************************************
785 Creates and throws an AbstractMethodError.
787 *******************************************************************************/
789 asm_abstractmethoderror:
791 std r0,LA_LR_OFFSET(sp)
792 stdu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
793 addi a0,sp,LA_SIZE_ALIGNED /* pass java sp */
794 mr a1,r0 /* pass exception address */
795 bl exceptions_asm_new_abstractmethoderror
796 ld r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
797 mtlr r0 /* restore return address */
798 addi sp,sp,LA_SIZE_ALIGNED
800 mr xptr,v0 /* get exception pointer */
801 mr xpc,r0 /* we can't use r0 directly in addi */
802 addi xpc,xpc,-4 /* exception address is ra - 4 */
803 b L_asm_handle_nat_exception
806 /* asm_patcher_wrapper *********************************************************
811 40 return address into JIT code (patch position)
812 32 pointer to virtual java_objectheader
813 24 machine code (which is patched back later)
814 16 unresolved class/method/field reference
815 8 data segment displacement from load instructions
816 0 patcher function pointer to call (pv is saved here afterwards)
818 *******************************************************************************/
821 mflr r0 /* get Java return address (leaf) */
822 std r0,6*8(sp) /* store it in the stub stackframe */
823 /* keep stack 16-bytes aligned: 6+1+37 = 44 */
824 stdu sp,-(LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8)(sp)
826 SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS) /* save 8 int/8 float arguments */
827 SAVE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS+ARG_CNT)
829 std itmp1,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+1*8(sp)
830 std itmp2,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+2*8(sp)
831 std pv,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+3*8(sp)
833 addi a0,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8 /* pass SP of patcher stub */
834 mr a1,pv /* pass PV */
835 mr a2,r0 /* pass RA (correct for leafs) */
837 std v0,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+4*8(sp) /* save return value */
840 RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS) /* restore 8 int/8 float args */
841 RESTORE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+PA_SIZE_IN_POINTERS+ARG_CNT)
843 ld itmp1,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+1*8(sp)
844 ld itmp2,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+2*8(sp)
845 ld pv,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+3*8(sp)
846 ld itmp3,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+4*8(sp)
848 ld r0,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+6*8(sp) /* restore RA */
851 mr. itmp3,itmp3 /* check for an exception */
852 bne L_asm_patcher_wrapper_exception
854 /* get return address (into JIT code) */
855 ld itmp3,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+5*8(sp)
857 /* remove stack frame + patcher stub stack */
858 addi sp,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+8*8
861 bctr /* jump to new patched code */
863 L_asm_patcher_wrapper_exception:
864 mr xptr,itmp3 /* get exception */
865 ld xpc,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+5*8(sp)
866 addi sp,sp,LA_SIZE+PA_SIZE+ARG_CNT*8+TMP_CNT*8+4*8+8*8
867 b L_asm_handle_exception
869 #if defined(ENABLE_REPLACEMENT)
871 /* asm_replacement_out *********************************************************
873 This code is jumped to from the replacement-out stubs that are executed
874 when a thread reaches an activated replacement point.
876 The purpose of asm_replacement_out is to read out the parts of the
877 execution state that cannot be accessed from C code, store this state,
878 and then call the C function replace_me.
881 16 start of stack inside method to replace
882 0 rplpoint * info on the replacement point that was reached
884 NOTE: itmp3 has been clobbered by the replacement-out stub!
886 *******************************************************************************/
888 /* some room to accomodate changes of the stack frame size during replacement */
889 /* XXX we should find a cleaner solution here */
890 #define REPLACEMENT_ROOM 512
893 /* create stack frame */
894 addi sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
896 /* save link register */
899 /* save registers in execution state */
900 std r0 ,( 0*8+offes_intregs)(sp)
901 std r1 ,( 1*8+offes_intregs)(sp)
902 std r2 ,( 2*8+offes_intregs)(sp)
903 std r3 ,( 3*8+offes_intregs)(sp)
904 std r4 ,( 4*8+offes_intregs)(sp)
905 std r5 ,( 5*8+offes_intregs)(sp)
906 std r6 ,( 6*8+offes_intregs)(sp)
907 std r7 ,( 7*8+offes_intregs)(sp)
908 std r8 ,( 8*8+offes_intregs)(sp)
909 std r9 ,( 9*8+offes_intregs)(sp)
910 std r10,(10*8+offes_intregs)(sp)
911 std r11,(11*8+offes_intregs)(sp)
912 std r12,(12*8+offes_intregs)(sp)
913 std r13,(13*8+offes_intregs)(sp)
914 std r14,(14*8+offes_intregs)(sp)
915 std r15,(15*8+offes_intregs)(sp)
916 std r16,(16*8+offes_intregs)(sp) /* link register */
917 std r17,(17*8+offes_intregs)(sp)
918 std r18,(18*8+offes_intregs)(sp)
919 std r19,(19*8+offes_intregs)(sp)
920 std r20,(20*8+offes_intregs)(sp)
921 std r21,(21*8+offes_intregs)(sp)
922 std r22,(22*8+offes_intregs)(sp)
923 std r23,(23*8+offes_intregs)(sp)
924 std r24,(24*8+offes_intregs)(sp)
925 std r25,(25*8+offes_intregs)(sp)
926 std r26,(26*8+offes_intregs)(sp)
927 std r27,(27*8+offes_intregs)(sp)
928 std r28,(28*8+offes_intregs)(sp)
929 std r29,(29*8+offes_intregs)(sp)
930 std r30,(30*8+offes_intregs)(sp)
931 std r31,(31*8+offes_intregs)(sp)
933 stfd fr0 ,( 0*8+offes_fltregs)(sp)
934 stfd fr1 ,( 1*8+offes_fltregs)(sp)
935 stfd fr2 ,( 2*8+offes_fltregs)(sp)
936 stfd fr3 ,( 3*8+offes_fltregs)(sp)
937 stfd fr4 ,( 4*8+offes_fltregs)(sp)
938 stfd fr5 ,( 5*8+offes_fltregs)(sp)
939 stfd fr6 ,( 6*8+offes_fltregs)(sp)
940 stfd fr7 ,( 7*8+offes_fltregs)(sp)
941 stfd fr8 ,( 8*8+offes_fltregs)(sp)
942 stfd fr9 ,( 9*8+offes_fltregs)(sp)
943 stfd fr10,(10*8+offes_fltregs)(sp)
944 stfd fr11,(11*8+offes_fltregs)(sp)
945 stfd fr12,(12*8+offes_fltregs)(sp)
946 stfd fr13,(13*8+offes_fltregs)(sp)
947 stfd fr14,(14*8+offes_fltregs)(sp)
948 stfd fr15,(15*8+offes_fltregs)(sp)
949 stfd fr16,(16*8+offes_fltregs)(sp)
950 stfd fr17,(17*8+offes_fltregs)(sp)
951 stfd fr18,(18*8+offes_fltregs)(sp)
952 stfd fr19,(19*8+offes_fltregs)(sp)
953 stfd fr20,(20*8+offes_fltregs)(sp)
954 stfd fr21,(21*8+offes_fltregs)(sp)
955 stfd fr22,(22*8+offes_fltregs)(sp)
956 stfd fr23,(23*8+offes_fltregs)(sp)
957 stfd fr24,(24*8+offes_fltregs)(sp)
958 stfd fr25,(25*8+offes_fltregs)(sp)
959 stfd fr26,(26*8+offes_fltregs)(sp)
960 stfd fr27,(27*8+offes_fltregs)(sp)
961 stfd fr28,(28*8+offes_fltregs)(sp)
962 stfd fr29,(29*8+offes_fltregs)(sp)
963 stfd fr30,(30*8+offes_fltregs)(sp)
964 stfd fr31,(31*8+offes_fltregs)(sp)
966 /* calculate sp of method */
967 addi itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
968 stw itmp1,(offes_sp)(sp)
971 stw pv,(offes_pv)(sp)
973 /* call replace_me */
974 lwz a0,-(4*4)(itmp1) /* arg0: rplpoint * */
975 mr a1,sp /* arg1: execution state */
976 addi sp,sp,-(LA_SIZE_ALIGNED)
977 b replace_me /* call C function replace_me */
979 /* asm_replacement_in **********************************************************
981 This code writes the given execution state and jumps to the replacement
984 This function never returns!
986 NOTE: itmp3 is not restored!
989 void asm_replacement_in(executionstate *es);
991 *******************************************************************************/
994 /* a0 == executionstate *es */
996 /* set new sp and pv */
1000 /* copy registers from execution state */
1001 ld r0 ,( 0*8+offes_intregs)(a0)
1003 /* r2 is reserved */
1004 /* a0 is loaded below */
1005 ld r4 ,( 4*8+offes_intregs)(a0)
1006 ld r5 ,( 5*8+offes_intregs)(a0)
1007 ld r6 ,( 6*8+offes_intregs)(a0)
1008 ld r7 ,( 7*8+offes_intregs)(a0)
1009 ld r8 ,( 8*8+offes_intregs)(a0)
1010 ld r9 ,( 9*8+offes_intregs)(a0)
1011 ld r10,(10*8+offes_intregs)(a0)
1012 ld r11,(11*8+offes_intregs)(a0)
1013 ld r12,(12*8+offes_intregs)(a0)
1015 ld r14,(14*8+offes_intregs)(a0)
1016 ld r15,(15*8+offes_intregs)(a0)
1017 ld r16,(16*8+offes_intregs)(a0) /* link register */
1018 ld r17,(17*8+offes_intregs)(a0)
1019 ld r18,(18*8+offes_intregs)(a0)
1020 ld r19,(19*8+offes_intregs)(a0)
1021 ld r20,(20*8+offes_intregs)(a0)
1022 ld r21,(21*8+offes_intregs)(a0)
1023 ld r22,(22*8+offes_intregs)(a0)
1024 ld r23,(23*8+offes_intregs)(a0)
1025 ld r24,(24*8+offes_intregs)(a0)
1026 ld r25,(25*8+offes_intregs)(a0)
1027 ld r26,(26*8+offes_intregs)(a0)
1028 ld r27,(27*8+offes_intregs)(a0)
1029 ld r28,(28*8+offes_intregs)(a0)
1030 ld r29,(29*8+offes_intregs)(a0)
1031 ld r30,(30*8+offes_intregs)(a0)
1032 ld r31,(31*8+offes_intregs)(a0)
1034 lfd fr0 ,( 0*8+offes_fltregs)(a0)
1035 lfd fr1 ,( 1*8+offes_fltregs)(a0)
1036 lfd fr2 ,( 2*8+offes_fltregs)(a0)
1037 lfd fr3 ,( 3*8+offes_fltregs)(a0)
1038 lfd fr4 ,( 4*8+offes_fltregs)(a0)
1039 lfd fr5 ,( 5*8+offes_fltregs)(a0)
1040 lfd fr6 ,( 6*8+offes_fltregs)(a0)
1041 lfd fr7 ,( 7*8+offes_fltregs)(a0)
1042 lfd fr8 ,( 8*8+offes_fltregs)(a0)
1043 lfd fr9 ,( 9*8+offes_fltregs)(a0)
1044 lfd fr10,(10*8+offes_fltregs)(a0)
1045 lfd fr11,(11*8+offes_fltregs)(a0)
1046 lfd fr12,(12*8+offes_fltregs)(a0)
1047 lfd fr13,(13*8+offes_fltregs)(a0)
1048 lfd fr14,(14*8+offes_fltregs)(a0)
1049 lfd fr15,(15*8+offes_fltregs)(a0)
1050 lfd fr16,(16*8+offes_fltregs)(a0)
1051 lfd fr17,(17*8+offes_fltregs)(a0)
1052 lfd fr18,(18*8+offes_fltregs)(a0)
1053 lfd fr19,(19*8+offes_fltregs)(a0)
1054 lfd fr20,(20*8+offes_fltregs)(a0)
1055 lfd fr21,(21*8+offes_fltregs)(a0)
1056 lfd fr22,(22*8+offes_fltregs)(a0)
1057 lfd fr23,(23*8+offes_fltregs)(a0)
1058 lfd fr24,(24*8+offes_fltregs)(a0)
1059 lfd fr25,(25*8+offes_fltregs)(a0)
1060 lfd fr26,(26*8+offes_fltregs)(a0)
1061 lfd fr27,(27*8+offes_fltregs)(a0)
1062 lfd fr28,(28*8+offes_fltregs)(a0)
1063 lfd fr29,(29*8+offes_fltregs)(a0)
1064 lfd fr30,(30*8+offes_fltregs)(a0)
1065 lfd fr31,(31*8+offes_fltregs)(a0)
1067 /* restore link register */
1073 ld itmp3,offes_pc(a0)
1077 ld a0,(3*8+offes_intregs)(a0)
1079 /* jump to new code */
1084 #endif /* defined(ENABLE_REPLACEMENT) */
1086 /* asm_cacheflush **************************************************************
1087 copied from linux/arch/ppc64/kernel/vdso64/cacheflush.S
1088 assumes 128 byte cache line size.
1089 All registers used may be trashed for fun and profit.
1090 *******************************************************************************/
1092 .section ".opd","aw"
1095 .quad .asm_cacheflush,.TOC.@tocbase,0
1097 .size asm_cacheflush, 24
1098 .type .asm_cacheflush,@function
1099 .globl .asm_cacheflush
1101 /* construct the AND mask */
1102 li r6, 0xffffffffffff8000
1103 ori r6,r6,0x000000000000ff80
1130 asm_getclassvalues_atomic
1132 .section ".opd","aw"
1134 asm_getclassvalues_atomic:
1135 .quad .asm_getclassvalues_atomic,.TOC.@tocbase,0
1137 .size asm_getclassvalues_atomic, 24
1138 .type .asm_getclassvalues_atomic,@function
1139 .globl .asm_getclassvalues_atomic
1140 .asm_getclassvalues_atomic:
1144 lwz r6,offbaseval(r3)
1145 lwz r7,offdiffval(r3)
1146 lwz r8,offbaseval(r4)
1148 stw r6,offcast_super_baseval(r5)
1149 stw r7,offcast_super_diffval(r5)
1150 stw r8,offcast_sub_baseval(r5)
1155 asm_criticalsections:
1156 #if defined(ENABLE_THREADS)
1163 /* disable exec-stacks ********************************************************/
1165 #if defined(__linux__) && defined(__ELF__)
1166 .section .note.GNU-stack,"",%progbits
1171 * These are local overrides for various environment variables in Emacs.
1172 * Please do not remove this and leave it at the end of the file, where
1173 * Emacs will automagically detect them.
1174 * ---------------------------------------------------------------------
1177 * indent-tabs-mode: t
1181 * vim:noexpandtab:sw=4:ts=4: