Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: asmpart.S 7596 2007-03-28 21:05:53Z twisti $
-
*/
#include "vm/jit/alpha/md-abi.h"
#include "vm/jit/alpha/md-asm.h"
-#include "vm/jit/alpha/offsets.h"
#include "vm/jit/abi-asm.h"
#include "vm/jit/methodheader.h"
.globl asm_abstractmethoderror
- .globl asm_patcher_wrapper
-
-#if defined(ENABLE_REPLACEMENT)
- .globl asm_replacement_out
- .globl asm_replacement_in
-#endif
-
.globl asm_compare_and_swap
.globl asm_memory_barrier
- .globl asm_criticalsections
- .globl asm_getclassvalues_atomic
-
.globl asm_md_init
.globl asm_cacheflush
asm_vm_call_method_float:
asm_vm_call_method_double:
ldgp gp,0(pv)
- lda sp,-5*8(sp) /* allocate stack space */
- stq ra,0*8(sp) /* save return address */
- stq gp,1*8(sp) /* save global pointer */
- stq s6,3*8(sp)
-
- stq a0,4*8(sp) /* save method pointer for compiler */
-
- mov a2,t0 /* pointer to arg block */
- mov a1,s6 /* arg count */
-
- ble s6,calljava_argsloaded
- lda s6,-1(s6)
- ldq a0,offvmargdata(t0)
- ldt $f16,offvmargdata(t0)
- ble s6,calljava_argsloaded
-
- lda s6,-1(s6)
- ldq a1,offvmargdata+sizevmarg*1(t0)
- ldt $f17,offvmargdata+sizevmarg*1(t0)
- ble s6,calljava_argsloaded
-
- lda s6,-1(s6)
- ldq a2,offvmargdata+sizevmarg*2(t0)
- ldt $f18,offvmargdata+sizevmarg*2(t0)
- ble s6,calljava_argsloaded
-
- lda s6,-1(s6)
- ldq a3,offvmargdata+sizevmarg*3(t0)
- ldt $f19,offvmargdata+sizevmarg*3(t0)
- ble s6,calljava_argsloaded
-
- lda s6,-1(s6)
- ldq a4,offvmargdata+sizevmarg*4(t0)
- ldt $f20,offvmargdata+sizevmarg*4(t0)
- ble s6,calljava_argsloaded
-
- lda s6,-1(s6)
- ldq a5,offvmargdata+sizevmarg*5(t0)
- ldt $f21,offvmargdata+sizevmarg*5(t0)
-calljava_argsloaded:
- mov sp,t4
- ble s6,calljava_nocopy
- negq s6,t1
- s8addq t1,sp,sp
- s8addq t1,t4,t2
-
-calljava_copyloop:
- ldq t3,offvmargdata+sizevmarg*6(t0)
- stq t3,0(t2)
- lda t1,1(t1)
- lda t0,sizevmarg(t0)
- lda t2,8(t2)
- bne t1,calljava_copyloop
-
-calljava_nocopy:
- ldq itmp1,4*8(t4) /* pass method pointer via itmp1 */
-
- lda mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
- stq mptr,2*8(t4) /* store function address */
- lda mptr,1*8(t4) /* set method pointer */
-
- ldq pv,1*8(mptr) /* method call as in Java */
- jmp ra,(pv) /* call JIT compiler */
-calljava_jit2:
- lda pv,(asm_vm_call_method - calljava_jit2)(ra)
-
- s8addq s6,sp,sp
-calljava_return2:
- ldq ra,0*8(sp) /* restore return address */
- ldq gp,1*8(sp) /* restore global pointer */
- ldq s6,3*8(sp)
- lda sp,5*8(sp) /* free stack space */
-
-calljava_ret2:
+ lda sp,-5*8(sp) /* allocate stack space */
+ stq ra,0*8(sp) /* save return address */
+ stq gp,1*8(sp) /* save global pointer */
+
+ stq s0,3*8(sp)
+ stq a0,4*8(sp) /* save method PV */
+
+ mov a1,t0 /* address of argument array */
+ mov a2,t1 /* stack argument count */
+ mov sp,s0 /* save stack pointer */
+
+ ldq a0,0*8(t0)
+ ldq a1,1*8(t0)
+ ldq a2,2*8(t0)
+ ldq a3,3*8(t0)
+ ldq a4,4*8(t0)
+ ldq a5,5*8(t0)
+
+ ldt fa0,6*8(t0)
+ ldt fa1,7*8(t0)
+ ldt fa2,8*8(t0)
+ ldt fa3,9*8(t0)
+ ldt fa4,10*8(t0)
+ ldt fa5,11*8(t0)
+
+ beq t1,L_asm_vm_call_method_stack_copy_done
+
+ negq t1,t2 /* calculate stackframe size (* 8) */
+ s8addq t2,sp,sp /* create stackframe */
+ mov sp,t2 /* temporary stack pointer */
+
+L_asm_vm_call_method_stack_copy_loop:
+ ldq t3,12*8(t0) /* load argument */
+ stq t3,0(t2) /* store argument on stack */
+
+ subq t1,1,t1 /* subtract 1 argument */
+ addq t0,8,t0 /* load address of next argument */
+ addq t2,8,t2 /* increase stack pointer */
+
+ bgt t1,L_asm_vm_call_method_stack_copy_loop
+
+L_asm_vm_call_method_stack_copy_done:
+ lda mptr,4*8(s0) /* get address of PV */
+ ldq pv,0*8(mptr) /* load PV */
+ jmp ra,(pv)
+L_asm_vm_call_method_recompute_pv:
+ lda pv,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)(ra)
+
+ mov s0,sp /* restore stack pointer */
+
+L_asm_vm_call_method_recompute_return:
+ ldq ra,0*8(sp) /* restore RA */
+ ldq gp,1*8(sp) /* restore global pointer */
+ ldq s0,3*8(sp)
+
+ lda sp,5*8(sp) /* free stack space */
jmp zero,(ra)
asm_vm_call_method_exception_handler:
- s8addq s6,sp,sp
- ldq gp,1*8(sp) /* restore global pointer */
+ mov s0,sp /* restore stack pointer */
+ ldq gp,1*8(sp) /* restore global pointer */
mov itmp1,a0
jsr ra,builtin_throw_exception
- ldq ra,0*8(sp) /* restore return address */
- ldq s6,3*8(sp)
- lda sp,5*8(sp) /* free stack space */
+
asm_vm_call_method_end:
- jmp zero,(ra)
+ br L_asm_vm_call_method_recompute_return
.end asm_vm_call_method
.end asm_abstractmethoderror
-/* asm_patcher_wrapper *********************************************************
-
- XXX
-
- Stack layout:
- 40 return address into JIT code (patch position)
- 32 pointer to virtual java_objectheader
- 24 machine code (which is patched back later)
- 16 unresolved class/method/field reference
- 8 data segment displacement from load instructions
- 0 patcher function pointer to call (pv afterwards)
-
- ATTENTION: itmp3 == gp! But we don't need gp do call the patcher function.
-
-*******************************************************************************/
-
- .ent asm_patcher_wrapper
-
-asm_patcher_wrapper:
- lda sp,-((2+12+27+4)*8)(sp) /* create stack frame */
-
- SAVE_RETURN_REGISTERS(0) /* save 1 int/1 float return registers */
- SAVE_ARGUMENT_REGISTERS(2) /* save 6 int/6 float argument registers */
- SAVE_TEMPORARY_REGISTERS(14) /* save 11 int/16 float temporary registers */
-
- stq itmp1,(2+12+27+0)*8(sp) /* save itmp1 */
- stq itmp2,(2+12+27+1)*8(sp) /* save itmp2 */
- stq ra,(2+12+27+2)*8(sp) /* save method return address (for leafs) */
- stq pv,(2+12+27+3)*8(sp) /* save pv of calling java function */
-
- br ra,L_asm_patcher_wrapper_load_gp
-L_asm_patcher_wrapper_load_gp:
- ldgp gp,0(ra) /* load gp (it's not set correctly in jit) */
-
- lda a0,(2+12+27+4)*8(sp) /* pass SP of patcher stub */
- mov pv,a1 /* pass PV */
- ldq a2,(2+12+27+2)*8(sp) /* pass RA (correct for leafs) */
- jsr ra,patcher_wrapper
- ldgp gp,0(ra)
- stq v0,(0+2+12+27+4)*8(sp) /* save return value */
-
- RESTORE_RETURN_REGISTERS(0) /* restore 1 int/1 float return registers */
- RESTORE_ARGUMENT_REGISTERS(2) /* restore 6 int/6 float argument registers */
- RESTORE_TEMPORARY_REGISTERS(14) /* restore 11 integer temporary registers */
-
- ldq itmp1,(2+12+27+0)*8(sp) /* restore itmp1 */
- ldq itmp2,(2+12+27+1)*8(sp) /* restore itmp2 */
- ldq ra,(2+12+27+2)*8(sp) /* restore method return address (for leafs)*/
- ldq pv,(2+12+27+3)*8(sp) /* restore pv of calling java function */
-
- ldq itmp3,(0+2+12+27+4)*8(sp) /* get return value */
- bne itmp3,L_asm_patcher_wrapper_exception
-
- ldq itmp3,(5+2+12+27+4)*8(sp) /* get RA to JIT */
- lda sp,(6+2+12+27+4)*8(sp) /* remove stack frame */
-
- jmp zero,(itmp3) /* jump to new patched code */
-
-L_asm_patcher_wrapper_exception:
- mov itmp3,xptr /* get exception */
- ldq xpc,(5+2+12+27+4)*8(sp) /* RA is xpc */
- lda sp,(6+2+12+27+4)*8(sp) /* remove stack frame */
- br L_asm_handle_exception
-
- .end asm_patcher_wrapper
-
-
-#if defined(ENABLE_REPLACEMENT)
-
-/* 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
-
-#define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
-
- .ent asm_replacement_out
-
-asm_replacement_out:
- /* create stack frame */
- lda sp,-(REPLACEMENT_STACK_OFFSET)(sp)
-
- /* save registers in execution state */
- stq $0 ,( 0*8+offes_intregs)(sp)
- stq $1 ,( 1*8+offes_intregs)(sp)
- stq $2 ,( 2*8+offes_intregs)(sp)
- stq $3 ,( 3*8+offes_intregs)(sp)
- stq $4 ,( 4*8+offes_intregs)(sp)
- stq $5 ,( 5*8+offes_intregs)(sp)
- stq $6 ,( 6*8+offes_intregs)(sp)
- stq $7 ,( 7*8+offes_intregs)(sp)
- stq $8 ,( 8*8+offes_intregs)(sp)
- stq $9 ,( 9*8+offes_intregs)(sp)
- stq $10,(10*8+offes_intregs)(sp)
- stq $11,(11*8+offes_intregs)(sp)
- stq $12,(12*8+offes_intregs)(sp)
- stq $13,(13*8+offes_intregs)(sp)
- stq $14,(14*8+offes_intregs)(sp)
- stq $15,(15*8+offes_intregs)(sp)
- stq $16,(16*8+offes_intregs)(sp)
- stq $17,(17*8+offes_intregs)(sp)
- stq $18,(18*8+offes_intregs)(sp)
- stq $19,(19*8+offes_intregs)(sp)
- stq $20,(20*8+offes_intregs)(sp)
- stq $21,(21*8+offes_intregs)(sp)
- stq $22,(22*8+offes_intregs)(sp)
- stq $23,(23*8+offes_intregs)(sp)
- stq $24,(24*8+offes_intregs)(sp)
- stq $25,(25*8+offes_intregs)(sp)
- stq $26,(26*8+offes_intregs)(sp)
- stq $27,(27*8+offes_intregs)(sp)
- stq $28,(28*8+offes_intregs)(sp)
- stq $29,(29*8+offes_intregs)(sp)
- stq $30,(30*8+offes_intregs)(sp)
- stq $31,(31*8+offes_intregs)(sp)
-
- stt $f0 ,( 0*8+offes_fltregs)(sp)
- stt $f1 ,( 1*8+offes_fltregs)(sp)
- stt $f2 ,( 2*8+offes_fltregs)(sp)
- stt $f3 ,( 3*8+offes_fltregs)(sp)
- stt $f4 ,( 4*8+offes_fltregs)(sp)
- stt $f5 ,( 5*8+offes_fltregs)(sp)
- stt $f6 ,( 6*8+offes_fltregs)(sp)
- stt $f7 ,( 7*8+offes_fltregs)(sp)
- stt $f8 ,( 8*8+offes_fltregs)(sp)
- stt $f9 ,( 9*8+offes_fltregs)(sp)
- stt $f10,(10*8+offes_fltregs)(sp)
- stt $f11,(11*8+offes_fltregs)(sp)
- stt $f12,(12*8+offes_fltregs)(sp)
- stt $f13,(13*8+offes_fltregs)(sp)
- stt $f14,(14*8+offes_fltregs)(sp)
- stt $f15,(15*8+offes_fltregs)(sp)
- stt $f16,(16*8+offes_fltregs)(sp)
- stt $f17,(17*8+offes_fltregs)(sp)
- stt $f18,(18*8+offes_fltregs)(sp)
- stt $f19,(19*8+offes_fltregs)(sp)
- stt $f20,(20*8+offes_fltregs)(sp)
- stt $f21,(21*8+offes_fltregs)(sp)
- stt $f22,(22*8+offes_fltregs)(sp)
- stt $f23,(23*8+offes_fltregs)(sp)
- stt $f24,(24*8+offes_fltregs)(sp)
- stt $f25,(25*8+offes_fltregs)(sp)
- stt $f26,(26*8+offes_fltregs)(sp)
- stt $f27,(27*8+offes_fltregs)(sp)
- stt $f28,(28*8+offes_fltregs)(sp)
- stt $f29,(29*8+offes_fltregs)(sp)
- stt $f30,(30*8+offes_fltregs)(sp)
- stt $f31,(31*8+offes_fltregs)(sp)
-
- /* calculate sp of method */
- lda itmp1,(REPLACEMENT_STACK_OFFSET + 2*8)(sp)
- stq itmp1,(offes_sp)(sp)
-
- br ra,L_asm_replacement_out_load_gp
-L_asm_replacement_out_load_gp:
- ldgp gp,0(ra) /* load gp */
-
- /* store pv */
- stq pv,(offes_pv)(sp)
-
- /* call replace_me */
- ldq a0,-(2*8)(itmp1) /* arg0: rplpoint * */
- mov sp,a1 /* arg1: execution state */
- jmp zero,replace_me /* call C function replace_me */
- jmp zero,abort /* NEVER REACHED */
-
- .end asm_replacement_out
-
-/* 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, replace_safestack_t *st);
-
-*******************************************************************************/
-
- .ent asm_replacement_in
-
-asm_replacement_in:
- /* a0 == executionstate *es */
-
- /* get arguments */
- mov a1,s1 /* replace_safestack_t *st */
- mov a0,s2 /* executionstate *es == safe stack */
-
- /* switch to the safe stack */
- mov s2,sp
-
- /* call replace_build_execution_state(st) */
- mov s1,a0
- jsr ra,replace_build_execution_state
-
- /* set new sp */
- ldq sp,(offes_sp)(s2)
-
- /* build stack frame */
- lda sp,(-sizeexecutionstate)(sp)
-
- /* call replace_free_safestack(st,& of allocated executionstate_t) */
- mov sp,a1 /* tmpes */
- mov s1,a0 /* st */
- jsr ra,replace_free_safestack
-
- /* set new pv */
- ldq pv,(offes_pv)(sp)
-
- /* copy registers from execution state */
- ldq $0 ,( 0*8+offes_intregs)(sp)
- ldq $1 ,( 1*8+offes_intregs)(sp)
- ldq $2 ,( 2*8+offes_intregs)(sp)
- ldq $3 ,( 3*8+offes_intregs)(sp)
- ldq $4 ,( 4*8+offes_intregs)(sp)
- ldq $5 ,( 5*8+offes_intregs)(sp)
- ldq $6 ,( 6*8+offes_intregs)(sp)
- ldq $7 ,( 7*8+offes_intregs)(sp)
- ldq $8 ,( 8*8+offes_intregs)(sp)
- ldq $9 ,( 9*8+offes_intregs)(sp)
- ldq $10,(10*8+offes_intregs)(sp)
- ldq $11,(11*8+offes_intregs)(sp)
- ldq $12,(12*8+offes_intregs)(sp)
- ldq $13,(13*8+offes_intregs)(sp)
- ldq $14,(14*8+offes_intregs)(sp)
- ldq $15,(15*8+offes_intregs)(sp)
- ldq a0, (16*8+offes_intregs)(sp)
- ldq $17,(17*8+offes_intregs)(sp)
- ldq $18,(18*8+offes_intregs)(sp)
- ldq $19,(19*8+offes_intregs)(sp)
- ldq $20,(20*8+offes_intregs)(sp)
- ldq $21,(21*8+offes_intregs)(sp)
- ldq $22,(22*8+offes_intregs)(sp)
- ldq $23,(23*8+offes_intregs)(sp)
- ldq $24,(24*8+offes_intregs)(sp)
- ldq $25,(25*8+offes_intregs)(sp)
- ldq $26,(26*8+offes_intregs)(sp)
- /* $27 is pv */
- ldq $28,(28*8+offes_intregs)(sp)
- ldq $29,(29*8+offes_intregs)(sp)
- /* $30 is sp */
- /* $31 is zero */
-
- ldt $f0 ,( 0*8+offes_fltregs)(sp)
- ldt $f1 ,( 1*8+offes_fltregs)(sp)
- ldt $f2 ,( 2*8+offes_fltregs)(sp)
- ldt $f3 ,( 3*8+offes_fltregs)(sp)
- ldt $f4 ,( 4*8+offes_fltregs)(sp)
- ldt $f5 ,( 5*8+offes_fltregs)(sp)
- ldt $f6 ,( 6*8+offes_fltregs)(sp)
- ldt $f7 ,( 7*8+offes_fltregs)(sp)
- ldt $f8 ,( 8*8+offes_fltregs)(sp)
- ldt $f9 ,( 9*8+offes_fltregs)(sp)
- ldt $f10,(10*8+offes_fltregs)(sp)
- ldt $f11,(11*8+offes_fltregs)(sp)
- ldt $f12,(12*8+offes_fltregs)(sp)
- ldt $f13,(13*8+offes_fltregs)(sp)
- ldt $f14,(14*8+offes_fltregs)(sp)
- ldt $f15,(15*8+offes_fltregs)(sp)
- ldt $f16,(16*8+offes_fltregs)(sp)
- ldt $f17,(17*8+offes_fltregs)(sp)
- ldt $f18,(18*8+offes_fltregs)(sp)
- ldt $f19,(19*8+offes_fltregs)(sp)
- ldt $f20,(20*8+offes_fltregs)(sp)
- ldt $f21,(21*8+offes_fltregs)(sp)
- ldt $f22,(22*8+offes_fltregs)(sp)
- ldt $f23,(23*8+offes_fltregs)(sp)
- ldt $f24,(24*8+offes_fltregs)(sp)
- ldt $f25,(25*8+offes_fltregs)(sp)
- ldt $f26,(26*8+offes_fltregs)(sp)
- ldt $f27,(27*8+offes_fltregs)(sp)
- ldt $f28,(28*8+offes_fltregs)(sp)
- ldt $f29,(29*8+offes_fltregs)(sp)
- ldt $f30,(30*8+offes_fltregs)(sp)
- ldt $f31,(31*8+offes_fltregs)(sp)
-
- /* load new pc */
-
- ldq itmp3,offes_pc(sp)
-
- /* remove stack frame */
-
- lda sp,(sizeexecutionstate)(sp)
-
- /* jump to new code */
-
- jmp zero,(itmp3)
-
- .end asm_replacement_in
-
-#endif /* defined(ENABLE_REPLACEMENT) */
-
-
/* asm_compare_and_swap ********************************************************
Does an atomic compare and swap. Required for the lock
.end asm_memory_barrier
- .ent asm_getclassvalues_atomic
-
-asm_getclassvalues_atomic:
-_crit_restart:
-_crit_begin:
- ldl t0,offbaseval(a0)
- ldl t1,offdiffval(a0)
- ldl t2,offbaseval(a1)
-_crit_end:
- stl t0,offcast_super_baseval(a2)
- stl t1,offcast_super_diffval(a2)
- stl t2,offcast_sub_baseval(a2)
- jmp zero,(ra)
-
- .end asm_getclassvalues_atomic
-
-
- .data
-
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
- .quad _crit_begin
- .quad _crit_end
- .quad _crit_restart
-#endif
- .quad 0
-
-
/* asm_md_init *****************************************************************
Initialize machine dependent stuff.
.end asm_cacheflush
-/* Disable exec-stacks, required for Gentoo ***********************************/
+/* disable exec-stacks ********************************************************/
-#if defined(__GCC__) && defined(__ELF__)
- .section .note.GNU-stack,"",@progbits
+#if defined(__linux__) && defined(__ELF__)
+ .section .note.GNU-stack,"",%progbits
#endif