Stefan Ring
Changes: Christian Thalinger
+ Edwin Steiner
- $Id: asmpart.S 4497 2006-02-12 23:22:36Z twisti $
+ $Id: asmpart.S 4654 2006-03-19 19:46:11Z edwin $
*/
.align 2
- .globl asm_calljavafunction
- .globl asm_calljavafunction_int
- .globl asm_calljavafunction2
- .globl asm_calljavafunction2int
- .globl asm_calljavafunction2long
- .globl asm_calljavafunction2float
- .globl asm_calljavafunction2double
+/* exported functions and variables *******************************************/
+
+ .globl asm_vm_call_method
+ .globl asm_vm_call_method_int
+ .globl asm_vm_call_method_long
+ .globl asm_vm_call_method_float
+ .globl asm_vm_call_method_double
.globl asm_call_jit_compiler
.globl asm_wrapper_patcher
+ .globl asm_replacement_out
+ .globl asm_replacement_in
+
.globl asm_cacheflush
.globl asm_initialize_thread_stack
.globl asm_perform_threadswitch
.globl asm_getclassvalues_atomic
-/********************* function asm_calljavafunction ***************************
+/* asm_vm_call_method **********************************************************
* *
* This function calls a Java-method (which possibly needs compilation) *
* with up to 4 address parameters. *
* *
*******************************************************************************/
- .align 2
-
- .long 0 /* catch type all */
- .long calljava_xhandler /* handler pc */
- .long calljava_xhandler /* end pc */
- .long asm_calljavafunction /* start pc */
- .long 1 /* extable size */
- .long 0 /* line number table start */
- .long 0 /* line number table size */
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 0 /* frame size */
- .long 0 /* method pointer (pointer to name) */
-
-asm_calljavafunction:
-asm_calljavafunction_int:
- mflr r0
- stw r0,LA_LR_OFFSET(r1)
- stwu r1,-40*4(r1)
-
-#if defined(__DARWIN__)
- stw itmp1,10*4(sp) /* register r11 is callee saved */
-#endif
- stw pv,11*4(sp) /* save PV register */
-
- stw itmp3,12*4(sp) /* registers r14-r31 are callee saved */
- stfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
- stfd ftmp2,16*4(sp)
-
-#if defined(__DARWIN__)
- stw t1,18*4(r1)
- stw t2,19*4(r1)
- stw t3,20*4(r1)
- stw t4,21*4(r1)
- stw t5,22*4(r1)
- stw t6,23*4(r1)
- stw t7,24*4(r1)
-
- stfd ft0,26*4(r1)
- stfd ft1,28*4(r1)
- stfd ft2,30*4(r1)
- stfd ft3,32*4(r1)
- stfd ft4,34*4(r1)
- stfd ft5,36*4(r1)
-#else
- SAVE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
-#endif
-
- mr itmp1,a0 /* pass method pointer via tmp1 */
-
- mr a0,a1
- mr a1,a2
- mr a2,a3
- mr a3,a4
-
-#if defined(__DARWIN__)
- lis mptr,ha16(asm_call_jit_compiler)
- addi mptr,mptr,lo16(asm_call_jit_compiler)
-#else
- lis mptr,asm_call_jit_compiler@ha
- addi mptr,mptr,asm_call_jit_compiler@l
-#endif
- stw mptr,8*4(r1)
- addi mptr,r1,7*4
-
- lwz pv,1*4(mptr)
- mtctr pv
- bctrl
-
-1:
- mflr itmp1
-#if defined(__DARWIN__)
- addi pv,itmp1,lo16(asm_calljavafunction-1b)
-#else
- addi pv,itmp1,(asm_calljavafunction-1b)@l
-#endif
-
-L_asm_calljavafunction_return:
-#if defined(__DARWIN__)
- lwz itmp1,10*4(sp) /* register r11 is callee saved */
-#endif
- lwz pv,11*4(sp) /* save PV register */
-
- lwz itmp3,12*4(sp)
- lfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
- lfd ftmp2,16*4(sp)
-
-#if defined(__DARWIN__)
- lwz t1,18*4(r1)
- lwz t2,19*4(r1)
- lwz t3,20*4(r1)
- lwz t4,21*4(r1)
- lwz t5,22*4(r1)
- lwz t6,23*4(r1)
- lwz t7,24*4(r1)
-
- lfd ft0,26*4(r1)
- lfd ft1,28*4(r1)
- lfd ft2,30*4(r1)
- lfd ft3,32*4(r1)
- lfd ft4,34*4(r1)
- lfd ft5,36*4(r1)
-#else
- RESTORE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
-#endif
-
- lwz r0,40*4+LA_LR_OFFSET(r1)
- mtlr r0
- addi r1,r1,40*4
- blr
-
-calljava_xhandler:
- mr a0,itmp1
- bl builtin_throw_exception
- li v0,0 /* return NULL */
- b L_asm_calljavafunction_return
-
-
-
-
.align 2
.long 0 /* catch type all */
.long calljava_xhandler2 /* handler pc */
.long calljava_xhandler2 /* end pc */
- .long asm_calljavafunction2 /* start pc */
+ .long L_asm_vm_call_method /* start pc */
.long 1 /* extable size */
.long 0 /* line number table start */
.long 0 /* line number table size */
.long 0 /* frame size */
.long 0 /* method pointer (pointer to name) */
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
+asm_vm_call_method:
+asm_vm_call_method_int:
+asm_vm_call_method_long:
+asm_vm_call_method_float:
+asm_vm_call_method_double:
+L_asm_vm_call_method: /* required for PIC code */
mflr r0
stw r0,LA_LR_OFFSET(r1)
stwu r1,-40*4(r1)
stw a0,9*4(r1) /* save method pointer for compiler */
- mr itmp1,r6 /* pointer to arg block */
+ mr itmp1,r5 /* pointer to arg block */
mr itmp2,r4 /* arg count */
- addi itmp1,itmp1,-sizejniblock /* initialize pointer (smaller code) */
+ addi itmp1,itmp1,-sizevmarg /* initialize pointer (smaller code) */
addi itmp2,itmp2,1 /* initialize argument count */
li r17,0 /* initialize integer argument counter */
li r18,0 /* initialize float argument counter */
L_register_copy:
- addi itmp1,itmp1,sizejniblock /* goto next argument block */
+ addi itmp1,itmp1,sizevmarg /* goto next argument block */
addi itmp2,itmp2,-1 /* argument count - 1 */
mr. itmp2,itmp2
beq L_register_copy_done
- lwz itmp3,offjniitemtype+4(itmp1)
+#if WORDS_BIGENDIAN == 1
+ lwz itmp3,offvmargtype+4(itmp1)
+#else
+#error XXX
+#endif
andi. r0,itmp3,0x0002 /* is this a float/double type? */
bne L_register_handle_float
lwz itmp1,9*4(sp) /* pass method pointer via tmp1 */
#if defined(__DARWIN__)
- lis mptr,ha16(asm_call_jit_compiler)
- addi mptr,mptr,lo16(asm_call_jit_compiler)
+ lis mptr,ha16(L_asm_call_jit_compiler)
+ addi mptr,mptr,lo16(L_asm_call_jit_compiler)
#else
- lis mptr,asm_call_jit_compiler@ha
- addi mptr,mptr,asm_call_jit_compiler@l
+ lis mptr,L_asm_call_jit_compiler@ha
+ addi mptr,mptr,L_asm_call_jit_compiler@l
#endif
stw mptr,8*4(r1)
addi mptr,r1,7*4
1:
mflr itmp1
#if defined(__DARWIN__)
- addi pv,itmp1,lo16(asm_calljavafunction2-1b)
+ addi pv,itmp1,lo16(L_asm_vm_call_method-1b)
#else
- addi pv,itmp1,(asm_calljavafunction2-1b)@l
+ addi pv,itmp1,(L_asm_vm_call_method-1b)@l
#endif
-L_asm_calljavafunction2_return:
+L_asm_vm_call_method_return:
#if defined(__DARWIN__)
lwz itmp1,10*4(sp) /* register r11 is callee saved */
#endif
mr r3,itmp1
bl builtin_throw_exception
li v0,0 /* return NULL */
- b L_asm_calljavafunction2_return
+ b L_asm_vm_call_method_return
jumptable_int:
.long L_handle_a7
L_handle_a0:
- lwz a0,offjniitem+4(itmp1)
+ lwz a0,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a1:
- lwz a1,offjniitem+4(itmp1)
+ lwz a1,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a2:
- lwz a2,offjniitem+4(itmp1)
+ lwz a2,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a3:
- lwz a3,offjniitem+4(itmp1)
+ lwz a3,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a4:
- lwz a4,offjniitem+4(itmp1)
+ lwz a4,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a5:
- lwz a5,offjniitem+4(itmp1)
+ lwz a5,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a6:
- lwz a6,offjniitem+4(itmp1)
+ lwz a6,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a7:
- lwz a7,offjniitem+4(itmp1)
+ lwz a7,offvmargdata+4(itmp1)
b L_register_copy
#endif
L_handle_a0_a1:
- lwz a0,offjniitem+0(itmp1)
- lwz a1,offjniitem+4(itmp1)
+ lwz a0,offvmargdata+0(itmp1)
+ lwz a1,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a2_a3:
- lwz a2,offjniitem+0(itmp1)
- lwz a3,offjniitem+4(itmp1)
+ lwz a2,offvmargdata+0(itmp1)
+ lwz a3,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a4_a5:
- lwz a4,offjniitem+0(itmp1)
- lwz a5,offjniitem+4(itmp1)
+ lwz a4,offvmargdata+0(itmp1)
+ lwz a5,offvmargdata+4(itmp1)
b L_register_copy
L_handle_a6_a7:
- lwz a6,offjniitem+0(itmp1)
- lwz a7,offjniitem+4(itmp1)
+ lwz a6,offvmargdata+0(itmp1)
+ lwz a7,offvmargdata+4(itmp1)
b L_register_copy
*******************************************************************************/
asm_call_jit_compiler:
+L_asm_call_jit_compiler: /* required for PIC code */
mflr r0
stw r0,LA_LR_OFFSET(r1) /* save return address */
stwu r1,-((LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo)(r1)
mflr xpc
addi xpc,xpc,-4
- b asm_handle_nat_exception
+ b L_asm_handle_nat_exception
/********************* function asm_handle_exception ***************************
*******************************************************************************/
asm_handle_nat_exception:
+L_asm_handle_nat_exception: /* required for PIC code */
mflr r9
lwz itmp3,4(r9)
extsh itmp3,itmp3
lwz itmp3,8(r9)
srwi itmp3,itmp3,16
cmpwi itmp3,0x3dad
- bne asm_handle_exception
+ bne L_asm_handle_exception
lwz itmp3,8(r9)
slwi itmp3,itmp3,16
add pv,pv,itmp3
asm_handle_exception:
+L_asm_handle_exception: /* required for PIC code */
addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
#if defined(__DARWIN__)
lwz xptr,0(v0) /* get the exception pointer */
li itmp3,0
stw itmp3,0(v0) /* clear the exception pointer */
- b asm_handle_exception
+ b L_asm_handle_exception
+
+
+/* asm_replacement_out *********************************************************
+
+ This code is jumped to from the replacement-out stubs that are executed
+ when a thread reaches an activated replacement point.
+
+ The purpose of asm_replacement_out is to read out the parts of the
+ execution state that cannot be accessed from C code, store this state,
+ and then call the C function replace_me.
+
+ Stack layout:
+ 16 start of stack inside method to replace
+ 0 rplpoint * info on the replacement point that was reached
+
+ NOTE: itmp3 has been clobbered by the replacement-out stub!
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+ /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM 512
+
+asm_replacement_out:
+ /* create stack frame */
+ addi sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
+
+ /* save link register */
+ mflr r16
+
+ /* save registers in execution state */
+ stw r0 ,( 0*8+offes_intregs)(sp)
+ stw r1 ,( 1*8+offes_intregs)(sp)
+ stw r2 ,( 2*8+offes_intregs)(sp)
+ stw r3 ,( 3*8+offes_intregs)(sp)
+ stw r4 ,( 4*8+offes_intregs)(sp)
+ stw r5 ,( 5*8+offes_intregs)(sp)
+ stw r6 ,( 6*8+offes_intregs)(sp)
+ stw r7 ,( 7*8+offes_intregs)(sp)
+ stw r8 ,( 8*8+offes_intregs)(sp)
+ stw r9 ,( 9*8+offes_intregs)(sp)
+ stw r10,(10*8+offes_intregs)(sp)
+ stw r11,(11*8+offes_intregs)(sp)
+ stw r12,(12*8+offes_intregs)(sp)
+ stw r13,(13*8+offes_intregs)(sp)
+ stw r14,(14*8+offes_intregs)(sp)
+ stw r15,(15*8+offes_intregs)(sp)
+ stw r16,(16*8+offes_intregs)(sp) /* link register */
+ stw r17,(17*8+offes_intregs)(sp)
+ stw r18,(18*8+offes_intregs)(sp)
+ stw r19,(19*8+offes_intregs)(sp)
+ stw r20,(20*8+offes_intregs)(sp)
+ stw r21,(21*8+offes_intregs)(sp)
+ stw r22,(22*8+offes_intregs)(sp)
+ stw r23,(23*8+offes_intregs)(sp)
+ stw r24,(24*8+offes_intregs)(sp)
+ stw r25,(25*8+offes_intregs)(sp)
+ stw r26,(26*8+offes_intregs)(sp)
+ stw r27,(27*8+offes_intregs)(sp)
+ stw r28,(28*8+offes_intregs)(sp)
+ stw r29,(29*8+offes_intregs)(sp)
+ stw r30,(30*8+offes_intregs)(sp)
+ stw r31,(31*8+offes_intregs)(sp)
+
+ stfd fr0 ,( 0*8+offes_fltregs)(sp)
+ stfd fr1 ,( 1*8+offes_fltregs)(sp)
+ stfd fr2 ,( 2*8+offes_fltregs)(sp)
+ stfd fr3 ,( 3*8+offes_fltregs)(sp)
+ stfd fr4 ,( 4*8+offes_fltregs)(sp)
+ stfd fr5 ,( 5*8+offes_fltregs)(sp)
+ stfd fr6 ,( 6*8+offes_fltregs)(sp)
+ stfd fr7 ,( 7*8+offes_fltregs)(sp)
+ stfd fr8 ,( 8*8+offes_fltregs)(sp)
+ stfd fr9 ,( 9*8+offes_fltregs)(sp)
+ stfd fr10,(10*8+offes_fltregs)(sp)
+ stfd fr11,(11*8+offes_fltregs)(sp)
+ stfd fr12,(12*8+offes_fltregs)(sp)
+ stfd fr13,(13*8+offes_fltregs)(sp)
+ stfd fr14,(14*8+offes_fltregs)(sp)
+ stfd fr15,(15*8+offes_fltregs)(sp)
+ stfd fr16,(16*8+offes_fltregs)(sp)
+ stfd fr17,(17*8+offes_fltregs)(sp)
+ stfd fr18,(18*8+offes_fltregs)(sp)
+ stfd fr19,(19*8+offes_fltregs)(sp)
+ stfd fr20,(20*8+offes_fltregs)(sp)
+ stfd fr21,(21*8+offes_fltregs)(sp)
+ stfd fr22,(22*8+offes_fltregs)(sp)
+ stfd fr23,(23*8+offes_fltregs)(sp)
+ stfd fr24,(24*8+offes_fltregs)(sp)
+ stfd fr25,(25*8+offes_fltregs)(sp)
+ stfd fr26,(26*8+offes_fltregs)(sp)
+ stfd fr27,(27*8+offes_fltregs)(sp)
+ stfd fr28,(28*8+offes_fltregs)(sp)
+ stfd fr29,(29*8+offes_fltregs)(sp)
+ stfd fr30,(30*8+offes_fltregs)(sp)
+ stfd fr31,(31*8+offes_fltregs)(sp)
+
+ /* calculate sp of method */
+ addi itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
+ stw itmp1,(offes_sp)(sp)
+
+ /* store pv */
+ stw pv,(offes_pv)(sp)
+
+ /* call replace_me */
+ lwz a0,-(4*4)(itmp1) /* arg0: rplpoint * */
+ mr a1,sp /* arg1: execution state */
+ addi sp,sp,-(LA_SIZE_ALIGNED)
+ b replace_me /* call C function replace_me */
+
+/* asm_replacement_in **********************************************************
+
+ This code writes the given execution state and jumps to the replacement
+ code.
+
+ This function never returns!
+
+ NOTE: itmp3 is not restored!
+
+ C prototype:
+ void asm_replacement_in(executionstate *es);
+
+*******************************************************************************/
+
+asm_replacement_in:
+ /* a0 == executionstate *es */
+
+ /* set new sp and pv */
+ lwz sp,(offes_sp)(a0)
+ lwz pv,(offes_pv)(a0)
+
+ /* copy registers from execution state */
+ lwz r0 ,( 0*8+offes_intregs)(a0)
+ /* r1 is sp */
+ /* r2 is reserved */
+ /* a0 is loaded below */
+ lwz r4 ,( 4*8+offes_intregs)(a0)
+ lwz r5 ,( 5*8+offes_intregs)(a0)
+ lwz r6 ,( 6*8+offes_intregs)(a0)
+ lwz r7 ,( 7*8+offes_intregs)(a0)
+ lwz r8 ,( 8*8+offes_intregs)(a0)
+ lwz r9 ,( 9*8+offes_intregs)(a0)
+ lwz r10,(10*8+offes_intregs)(a0)
+ lwz r11,(11*8+offes_intregs)(a0)
+ lwz r12,(12*8+offes_intregs)(a0)
+ /* r13 is pv */
+ lwz r14,(14*8+offes_intregs)(a0)
+ lwz r15,(15*8+offes_intregs)(a0)
+ lwz r16,(16*8+offes_intregs)(a0) /* link register */
+ lwz r17,(17*8+offes_intregs)(a0)
+ lwz r18,(18*8+offes_intregs)(a0)
+ lwz r19,(19*8+offes_intregs)(a0)
+ lwz r20,(20*8+offes_intregs)(a0)
+ lwz r21,(21*8+offes_intregs)(a0)
+ lwz r22,(22*8+offes_intregs)(a0)
+ lwz r23,(23*8+offes_intregs)(a0)
+ lwz r24,(24*8+offes_intregs)(a0)
+ lwz r25,(25*8+offes_intregs)(a0)
+ lwz r26,(26*8+offes_intregs)(a0)
+ lwz r27,(27*8+offes_intregs)(a0)
+ lwz r28,(28*8+offes_intregs)(a0)
+ lwz r29,(29*8+offes_intregs)(a0)
+ lwz r30,(30*8+offes_intregs)(a0)
+ lwz r31,(31*8+offes_intregs)(a0)
+
+ lfd fr0 ,( 0*8+offes_fltregs)(a0)
+ lfd fr1 ,( 1*8+offes_fltregs)(a0)
+ lfd fr2 ,( 2*8+offes_fltregs)(a0)
+ lfd fr3 ,( 3*8+offes_fltregs)(a0)
+ lfd fr4 ,( 4*8+offes_fltregs)(a0)
+ lfd fr5 ,( 5*8+offes_fltregs)(a0)
+ lfd fr6 ,( 6*8+offes_fltregs)(a0)
+ lfd fr7 ,( 7*8+offes_fltregs)(a0)
+ lfd fr8 ,( 8*8+offes_fltregs)(a0)
+ lfd fr9 ,( 9*8+offes_fltregs)(a0)
+ lfd fr10,(10*8+offes_fltregs)(a0)
+ lfd fr11,(11*8+offes_fltregs)(a0)
+ lfd fr12,(12*8+offes_fltregs)(a0)
+ lfd fr13,(13*8+offes_fltregs)(a0)
+ lfd fr14,(14*8+offes_fltregs)(a0)
+ lfd fr15,(15*8+offes_fltregs)(a0)
+ lfd fr16,(16*8+offes_fltregs)(a0)
+ lfd fr17,(17*8+offes_fltregs)(a0)
+ lfd fr18,(18*8+offes_fltregs)(a0)
+ lfd fr19,(19*8+offes_fltregs)(a0)
+ lfd fr20,(20*8+offes_fltregs)(a0)
+ lfd fr21,(21*8+offes_fltregs)(a0)
+ lfd fr22,(22*8+offes_fltregs)(a0)
+ lfd fr23,(23*8+offes_fltregs)(a0)
+ lfd fr24,(24*8+offes_fltregs)(a0)
+ lfd fr25,(25*8+offes_fltregs)(a0)
+ lfd fr26,(26*8+offes_fltregs)(a0)
+ lfd fr27,(27*8+offes_fltregs)(a0)
+ lfd fr28,(28*8+offes_fltregs)(a0)
+ lfd fr29,(29*8+offes_fltregs)(a0)
+ lfd fr30,(30*8+offes_fltregs)(a0)
+ lfd fr31,(31*8+offes_fltregs)(a0)
+
+ /* restore link register */
+
+ mtlr r16
+
+ /* load new pc */
+
+ lwz itmp3,offes_pc(a0)
+
+ /* load a0 */
+
+ lwz a0,(3*8+offes_intregs)(a0)
+
+ /* jump to new code */
+
+ mtctr itmp3
+ bctr
+/*********************************************************************/
asm_cacheflush:
add r4,r3,r4
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/