-/* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc
+/* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc64
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
J. Wenninger, Institut f. Computersprachen - TU Wien
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Andreas Krall
- Reinhard Grafl
- Alexander Jordan
-
- Changes:
-
- $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
-
*/
#include "config.h"
-#include "vm/jit/sparc64/md-abi.h"
-#include "offsets.h"
#include "md-asm.h"
+#include "vm/jit/sparc64/md-abi.h"
+
+
.register %g2,#scratch /* define as scratch */
.register %g3,#scratch /* XXX reserve for application */
.text
.global asm_vm_call_method_float
.global asm_vm_call_method_double
.global asm_vm_call_method_exception_handler
+ .global asm_vm_call_method_end
.global asm_call_jit_compiler
.global asm_abstractmethoderror
- .global asm_criticalsections
- .global asm_getclassvalues_atomic
+ .global asm_store_fp_state_reg
+ .global asm_load_fp_state_reg
/* asm_vm_call_method ******************************************************
* *
* This function calls a Java-method (which possibly needs compilation) *
*
+ * If the java method is throwing an exception, NULL will be returned.
+ *
* C-prototype:
* java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,
* vm_arg *vmargs);
asm_vm_call_method_float:
asm_vm_call_method_double:
- save %sp, -144, %sp /* 16 reg-save + 2 */
-
-
- /* todo: copy fp registers */
-
- brlez %i1, calljava_argsloaded
- dec %i1
- ldx [%i2 + offvmargdata], %o0
- brlez %i1, calljava_argsloaded
-
- dec %i1
- ldx [%i2 + (offvmargdata+sizevmarg*1)], %o1
- brlez %i1, calljava_argsloaded
-
- dec %i1
- ldx [%i2 + (offvmargdata+sizevmarg*2)], %o2
- brlez %i1, calljava_argsloaded
-
- dec %i1
- ldx [%i2 + (offvmargdata+sizevmarg*3)], %o3
- brlez %i1, calljava_argsloaded
-
- dec %i1
- ldx [%i2 + (offvmargdata+sizevmarg*4)], %o4
-
- /* todo: use more out registers ? */
-
-calljava_argsloaded:
- /* todo: stack frame layout!! */
+ save %sp,-((JITSTACK_CNT+2)*8),%sp
+ add %sp,JITSTACK,%l1 /* pointer to usable stack */
+
+ /* i0: PV */
+ /* i1: ptr to arg array */
+ /* i2: num stackargs */
+
+ ldx [%i1+0*8],%o0
+ ldx [%i1+1*8],%o1
+ ldx [%i1+2*8],%o2
+ ldx [%i1+3*8],%o3
+ ldx [%i1+4*8],%o4
+
+ ldd [%i1+5*8],fa0
+ ldd [%i1+6*8],fa1
+ ldd [%i1+7*8],fa2
+ ldd [%i1+8*8],fa3
+ ldd [%i1+9*8],fa4
+
+ brlez %i2, calljava_nocopy
+ nop /* delay: fill me! */
- brlez %i1, calljava_nocopy
- sllx %i1, 3, %l0 /* remaining args * 8 */
- mov %sp, %l1 /* right above window save area */
- sub %sp, %l0, %sp /* allocate more stack space */
+ sllx %i2,3,%l0 /* remaining args * 8 */
+ sub %sp,%l0,%sp /* allocate more stack space */
+ add %sp,JITSTACK,%l1 /* adjust stack begin pointer */
-calljava_copyloop:
- ldx [%i2 + (offvmargdata+sizevmarg*5)], %l0
- stx %l0, [%l1]
- inc sizevmarg, %i2 /* src++ */
- inc 8, %l1 /* dst++ */
- dec %i1 /* arg_count-- */
- bnz %xcc, calljava_copyloop
+asm_vm_call_copyloop:
+ ldx [%i1+10*8],%l0 /* load argument from array */
+ stx %l0,[%l1] /* store argument to stack */
+
+ inc 8,%i1 /* src++ */
+ subcc %i2,1,%i2 /* arg_count-- */
+ bnz %xcc, asm_vm_call_copyloop /* use cc from previous instr */
+ inc 8,%l1 /* dst++ (delay) */
-calljava_nocopy:
- mov %i0,itmp1 /* pass method info pointer via itmp1 */
+calljava_nocopy:
+ /* set pv, like a java method does */
+ setx asm_vm_call_method,%l0,pv_callee
- setx asm_call_jit_compiler,%l0,mptr_itmp2 /* fake virtual function call (2 instr) */
- stx mptr_itmp2,[%sp + 2047 + 17*8] /* store function address */
- add %sp,2047 + 16*8,mptr_itmp2 /* set method pointer */
+ stx %i0,[%l1 + 1*8] /* store PV on stack */
+ mov %l1,mptr_itmp2 /* set address of PV (-1*8) */
- ldx [1*8 + mptr_itmp2], pv_caller /* method call as in Java */
- jmpl pv_caller,ra_caller /* call JIT compiler */
+ ldx [1*8 + mptr_itmp2], pv_caller /* load PV from stack */
+ jmpl pv_caller,ra_caller /* method call as in Java */
nop
+
calljava_jit2:
/* pretend to restore pv */
- add ra_caller,(asm_vm_call_method - calljava_jit2 + 8),pv_callee
+ add ra_caller,(asm_vm_call_method - calljava_jit2 + 8),zero
calljava_return:
mov %o0, %i0 /* pass on the return value */
asm_vm_call_method_exception_handler:
- mov itmp1,%o0
+ /* so far this function did not call any c functions */
+ /* but now we need ABI compliant argslots on the stack */
+ sub %sp,6*8,%sp
+
+ mov xptr_itmp2,%o0
call builtin_throw_exception
nop
return %i7 + 8 /* implicit window restore */
- nop
+asm_vm_call_method_end:
+ mov zero,%o0 /* delay: return NULL */
asm_call_jit_compiler:
- save %sp,-208,%sp /* regsave(16) + argslots(6) + 4 float args */
+ /* stacksave for regsave(16) + argslots(6) + float args */
+ /* Note: +1 to keep stack 16-byte aligned */
+ save %sp,-((16+6+FLT_ARG_CNT+1)*8),%sp
SAVE_FLOAT_ARGUMENT_REGISTERS(22)
nop
RESTORE_FLOAT_ARGUMENT_REGISTERS(22)
+
+ brz %o0,L_asm_call_jit_compiler_exception
+ nop
restore %o0,%g0,pv_caller /* restore the callers window */
/* the source o0 references the old window */
/* pv_caller references the new window */
-
- brz pv_caller,L_asm_call_jit_compiler_exception
- nop
-
/* synchronise instruction cache moved somewhere else */
jmpl pv_caller,zero /* and call method, the method returns */
- /* directly to the caller (ra). */
+ /* directly to the caller (ra). */
+ nop
L_asm_call_jit_compiler_exception:
- /* no need to do a save, only ra needs to be preserved */
+ /* window still open, ra_callee valid, pv_callee undefined */
- /* we save ra in one of the application globals */
- mov ra_caller,xpc_itmp3 /* save return address (xpc) */
-
call exceptions_get_and_clear_exception
nop
- mov xpc_itmp3,ra_caller /* restore return address (xpc) */
-
mov %o0,xptr_itmp2 /* get exception */
- sub ra_caller,4,xpc_itmp3 /* exception address is ra - 4 */
- ba L_asm_handle_nat_exception
+ mov ra_callee,xpc_itmp3 /* exception address is address of call */
+
+ /* restore the window of the calling function */
+ restore
+
+ b L_asm_handle_nat_exception
nop
L_asm_handle_nat_exception: /* required for PIC code */
L_asm_handle_exception_stack_loop:
/* exception handling assumes that the current java method saved */
- /* the caller's window */
+ /* the caller's window, and has a valid pv */
/* get ra and pv before saving the window */
mov ra_callee,itmp1
mov %g4,%o2 /* pass PV */
mov %fp,%o3 /* pass Java SP */
+ b L_asm_handle_exception_continue
+ nop
+
asm_handle_exception:
mov pv_callee,%g4
/* save bigger stack frame for float args and temps */
- save %sp,(FLT_ARG_CNT+FLT_TMP_CNT+ABICALL_OFF)*8,%sp
+ save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT)*8),%sp
- SAVE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
- SAVE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+ SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
+ SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
mov xptr_itmp2,%l0 /* save exception pointer */
add zero,1,%l2 /* set maybe-leaf flag */
L_asm_handle_exception_continue:
call exceptions_handle_exception
+ nop
brz %o0,L_asm_handle_exception_not_caught
+ nop
mov %o0,xpc_itmp3 /* move handlerpc into xpc */
mov %l0,xptr_itmp2 /* restore exception pointer */
brz %l2,L_asm_handle_exception_no_leaf
+ nop
- RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
- RESTORE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+ RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
+ RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
L_asm_handle_exception_no_leaf:
/* restore java window and stackframe (ra and pv are in there) */
restore
jmpl xpc_itmp3, zero /* jump to the handler */
+ nop
L_asm_handle_exception_not_caught:
mov %l0,xptr_itmp2 /* restore xptr */
restore /* unwind stack and window */
ba L_asm_handle_exception_stack_loop
- mov xpc_itmp3,ra_caller /* the new xpc is ra (delay) */
+ mov ra_caller,xpc_itmp3 /* the new xpc is ra (delay) */
mov %fp,%o0 /* pass java sp(==fp) */
mov ra_callee,%o1 /* pass exception address */
call exceptions_asm_new_abstractmethoderror
+ nop
mov %o0,xptr_itmp2 /* get exception pointer */
sub ra_callee,4,xpc_itmp3 /* exception address is ra - 4 */
ba L_asm_handle_nat_exception
+ nop
/* XXX: leave the register window open for handle_exception ??? */
mov pv_callee,pv_caller
/* create window and stack frame */
- save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+ABICALL_OFF+4)*8),%sp
+ save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT+6)*8),%sp
- SAVE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
- SAVE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+ SAVE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
+ SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
+ SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
mov itmp1,%l0 /* save itmp1 */
mov itmp2,%l1 /* save itmp2 */
- add %fp,USESTACK,%o0 /* pass pseudo SP */
+ add %fp,JITSTACK,%o0 /* pass pseudo SP */
mov pv_callee,%o1 /* pass PV */
mov ra_callee,%o2 /* pass RA (correct for leafs) */
call patcher_wrapper
nop
- RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
- RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+ RESTORE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
+ RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
+ RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
mov %l0,itmp1 /* restore itmp1 */
mov %l1,itmp2 /* restore itmp2 */
brnz %o0,L_asm_patcher_wrapper_exception
+ nop
/* load RA (patch position from patcher data on the stack */
- ldx [%fp+USESTACK+5*8],itmp3
+ ldx [%fp+JITSTACK+5*8],itmp3
/* remove window and stack frame (and stack space allocated in the stub code */
restore %fp,6*8,%sp /* (source regs refer to old window, rd to new window) */
jmpl itmp3,zero /* jump to newly patched code */
+ nop
L_asm_patcher_wrapper_exception:
- mov itmp3,xptr_itmp2 /* get exception */
- ldx [%fp+USESTACK+5*8],xpc_itmp3 /* xpc is RA */
+ mov %o0,xptr_itmp2 /* get exception */
+ ldx [%fp+JITSTACK+5*8],xpc_itmp3 /* xpc is RA */
restore %fp,6*8,%sp /* remove stack frame */
ba asm_handle_exception
nop
-asm_getclassvalues_atomic:
-_crit_restart:
-_crit_begin:
-/* not doing a window save, using the global temporary registers */
- ldsw [offbaseval+%o0],itmp1
- ldsw [offdiffval+%o0],itmp2
- ldsw [offbaseval+%o1],itmp3
-_crit_end:
- stw itmp1,[offcast_super_baseval+%o2]
- stw itmp2,[offcast_super_diffval+%o2]
- stw itmp3,[offcast_sub_baseval+%o2]
- jmpl ra_caller,zero /* caller's ra, b/c no window save */
-
- .end asm_getclassvalues_atomic
+
+/* asm_store_fp_state_reg **************************************************
+ * *
+ * This function stores the 64-bit floating point state register to a *
+ * memory location. (which needs to be 8-byte aligned) *
+ * *
+ * C-prototype: *
+ * void asm_store_fp_state_reg(u8 *mem); *
+ * *
+ **************************************************************************/
+
+asm_store_fp_state_reg:
+ stx %fsr,[%o0]
+ retl /* return from leaf */
+ nop
+
+/* asm_load_fp_state_reg ***************************************************
+ * *
+ * This function loades the 64-bit floating point state register from a *
+ * memory location. (which needs to be 8-byte aligned) *
+ * *
+ * C-prototype: *
+ * void asm_load_fp_state_reg(u8 *mem); *
+ * *
+ **************************************************************************/
+
+asm_load_fp_state_reg:
+ ldx [%o0],%fsr
+ retl /* return from leaf */
+ nop
- .data
+/* disable exec-stacks ********************************************************/
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
- .xword _crit_begin
- .xword _crit_end
- .xword _crit_restart
+#if defined(__linux__) && defined(__ELF__)
+ .section .note.GNU-stack,"",%progbits
#endif
- .xword 0
-
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: asm
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */