-/* src/vm/jit/mips/asmpart.S - Java-C interface functions for mips
+/* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
- Copyright (C) 1996-2005 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
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Andreas Krall
-
- Changes: Christian Thalinger
-
- $Id: asmpart.S 3185 2005-09-16 07:48:52Z twisti $
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
*/
#include "config.h"
-#include "vm/jit/mips/offsets.h"
-#include "vm/jit/mips/asmoffsets.h"
+#include "vm/jit/mips/md-abi.h"
#include "vm/jit/mips/md-asm.h"
+#include "vm/jit/abi-asm.h"
+#include "vm/jit/methodheader.h"
+
.text
.set noat
-/* exported functions and variables *******************************************/
-
- .globl asm_calljavafunction
- .globl asm_calljavafunction_int
+/* export functions ***********************************************************/
- .globl asm_calljavafunction2
- .globl asm_calljavafunction2int
- .globl asm_calljavafunction2long
- .globl asm_calljavafunction2float
- .globl asm_calljavafunction2double
+ .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_vm_call_method_exception_handler
+ .globl asm_vm_call_method_end
- .globl asm_call_jit_compiler
.globl asm_handle_exception
.globl asm_handle_nat_exception
- .globl asm_wrapper_patcher
-
- .globl asm_perform_threadswitch
- .globl asm_initialize_thread_stack
- .globl asm_switchstackandcall
- .globl asm_getclassvalues_atomic
- .globl asm_criticalsections
-
- .globl compare_and_swap
+ .globl asm_abstractmethoderror
-/********************* function asm_calljavafunction ***************************
+/* asm_vm_call_method **********************************************************
* *
* This function calls a Java-method (which possibly needs compilation) *
* with up to 4 address parameters. *
* *
*******************************************************************************/
- .ent asm_calljavafunction
+ .ent asm_vm_call_method
.align 3
- .dword 0 /* catch type all */
- .dword calljava_xhandler /* handler pc */
- .dword calljava_xhandler /* end pc */
- .dword asm_calljavafunction /* start pc */
- .word 1 /* extable size */
- .word 0 /* 4-byte ALIGNMENT PADDING */
- .dword 0 /* line number table start */
- .dword 0 /* line number table size */
- .word 0 /* 4-byte ALIGNMENT PADDING */
- .word 0 /* fltsave */
- .word 0 /* intsave */
- .word 0 /* isleaf */
- .word 0 /* IsSync */
- .word 10*8 /* frame size */
- .dword 0 /* method pointer (pointer to name) */
-
-asm_calljavafunction:
-asm_calljavafunction_int:
- aaddiu sp,sp,-10*8 /* allocate stack space */
- ast ra,0(sp) /* save return address */
-
- .set noreorder
-
- bal call_java_pc
- ast pv,3*8(sp) /* procedure vector (delay slot) */
-call_java_pc:
- aaddiu pv,ra,-4*4
-
- .set reorder
-
- sdc1 fss0,4*8(sp) /* save non JavaABI saved flt registers */
- sdc1 fss1,5*8(sp)
- sdc1 fss2,6*8(sp)
- sdc1 fss3,7*8(sp)
- sdc1 fss4,8*8(sp)
- sdc1 fss5,9*8(sp)
+#if SIZEOF_VOID_P == 8
- move itmp1,a0 /* pass method pointer via tmp1 */
+ .word 0 /* fltsave */
+ .word 0 /* intsave */
+ .word 0 /* isleaf */
+ .word 0 /* frame size */
+ .dword 0 /* codeinfo pointer */
- move a0,a1 /* pass the remaining parameters */
- move a1,a2
- move a2,a3
- move a3,a4
+#else /* SIZEOF_VOID_P == 8 */
- ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
- ast mptr,1*8(sp) /* store function address */
- move mptr,sp /* set method pointer */
+ .word 0 /* fltsave */
+ .word 0 /* intsave */
+ .word 0 /* isleaf */
+ .word 0 /* frame size */
+ .word 0 /* method pointer (pointer to name) */
- .set noreorder
+#endif /* SIZEOF_VOID_P == 8 */
- ald pv,1*8(mptr) /* method call as in Java */
- jalr pv /* call JIT compiler */
- nop
- aaddiu pv,ra,-22*4 /* recompute procedure vector */
+asm_vm_call_method:
+asm_vm_call_method_int:
+asm_vm_call_method_long:
+asm_vm_call_method_float:
+asm_vm_call_method_double:
+ .set noreorder /* XXX we need to recompute pv */
- .set reorder
-
-calljava_return:
- ald ra,0(sp) /* restore return address */
- ald pv,3*8(sp) /* restore procedure vector */
-
- ldc1 fss0,4*8(sp) /* restore non JavaABI saved flt regs */
- ldc1 fss1,5*8(sp)
- ldc1 fss2,6*8(sp)
- ldc1 fss3,7*8(sp)
- ldc1 fss4,8*8(sp)
- ldc1 fss5,9*8(sp)
+ aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
+ ast ra,0*8(sp) /* save return address */
- aaddiu sp,sp,10*8 /* free stack space */
- j ra /* return */
+ bal L_asm_vm_call_method_compute_pv
+ ast pv,1*8(sp) /* procedure vector */
+L_asm_vm_call_method_compute_pv:
+ aaddiu pv,ra,-4*4
-calljava_xhandler:
- move a0,itmp1
- jal builtin_throw_exception
- move v0,zero /* clear return value for exception */
- b calljava_return
+ ast s0,3*8(sp) /* save callee saved register */
+ ast a0,4*8(sp) /* save method PV */
- .end asm_calljavafunction
+#if SIZEOF_VOID_P == 8
+ s.d fss0,5*8(sp) /* save non JavaABI saved flt registers */
+ s.d fss1,6*8(sp)
+ s.d fss2,7*8(sp)
+ s.d fss3,8*8(sp)
+ s.d fss4,9*8(sp)
+ s.d fss5,10*8(sp)
+#endif
+ move t0,a1 /* address of data structure */
+ move t1,a2 /* stack argument count */
+ move s0,sp /* save stack pointer */
+
+#if SIZEOF_VOID_P == 8
+
+ ld a0,0*8(t0)
+ ld a1,1*8(t0)
+ ld a2,2*8(t0)
+ ld a3,3*8(t0)
+ ld a4,4*8(t0)
+ ld a5,5*8(t0)
+ ld a6,6*8(t0)
+ ld a7,7*8(t0)
+
+ l.d fa0,8*8(t0)
+ l.d fa1,9*8(t0)
+ l.d fa2,10*8(t0)
+ l.d fa3,11*8(t0)
+ l.d fa4,12*8(t0)
+ l.d fa5,13*8(t0)
+ l.d fa6,14*8(t0)
+ l.d fa7,15*8(t0)
+
+#else /* SIZEOF_VOID_P == 8 */
+
+# if WORDS_BIGENDIAN == 1
+ lw a0,0*8+4(t0)
+ lw a1,1*8+4(t0)
+ lw a2,2*8+4(t0)
+ lw a3,3*8+4(t0)
+# else
+ lw a0,0*8(t0)
+ lw a1,1*8(t0)
+ lw a2,2*8(t0)
+ lw a3,3*8(t0)
+# endif
+
+# if !defined(ENABLE_SOFT_FLOAT)
+ l.d fa0,4*8(t0)
+ l.d fa1,5*8(t0)
+# endif
+
+#endif /* SIZEOF_VOID_P == 8 */
+
+ beqz t1,L_asm_vm_call_method_stack_copy_done
+ nop
- .ent asm_calljavafunction2
+ sll t2,t1,3 /* calculate stackframe size (* 8) */
+ asubu sp,sp,t2 /* create stackframe */
+ move t2,sp /* temporary stack pointer */
- .align 3
+L_asm_vm_call_method_stack_copy_loop:
+#if SIZEOF_VOID_P == 8
+ ld t3,16*8(t0) /* load argument */
+ sd t3,0(t2) /* store argument on stack */
+#else
+# if !defined(ENABLE_SOFT_FLOAT)
+ lw t3,6*8+0(t0) /* load argument */
+ lw t4,6*8+4(t0)
+ sw t3,0(t2) /* store argument on stack */
+ sw t4,4(t2)
+# else
+# error implement me
+# endif
+#endif
- .dword 0 /* catch type all */
- .dword calljava_xhandler2 /* handler pc */
- .dword calljava_xhandler2 /* end pc */
- .dword asm_calljavafunction2 /* start pc */
- .word 1 /* extable size */
- .word 0 /* 4-byte ALIGNMENT PADDING */
- .dword 0 /* line number table start */
- .dword 0 /* line number table size */
- .word 0 /* 4-byte ALIGNMENT PADDING */
- .word 0 /* fltsave */
- .word 1 /* intsave */
- .word 0 /* isleaf */
- .word 0 /* IsSync */
- .word 12*8 /* frame size */
- .dword 0 /* method pointer (pointer to name) */
-
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
- aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
- ast ra,0(sp) /* save return address */
+ aaddi t1,t1,-1 /* subtract 1 argument */
+ aaddi t0,t0,8 /* load address of next argument */
+ aaddi t2,t2,8 /* increase stack pointer */
- .set noreorder
- bal call_java_pc2
- ast pv,1*8(sp) /* procedure vector */
-call_java_pc2:
- aaddiu pv,ra,-4*4
- ast s7,3*8(sp)
+ bgtz t1,L_asm_vm_call_method_stack_copy_loop
+ nop
- .set reorder
-
- sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
- sdc1 fss1,6*8(sp)
- sdc1 fss2,7*8(sp)
- sdc1 fss3,8*8(sp)
- sdc1 fss4,9*8(sp)
- sdc1 fss5,10*8(sp)
-
- ast a0,4*8(sp) /* save method pointer for compiler */
-
- move t0,a3
- move s7,a1
- blez s7,calljava_argsloaded
-
- ald a0,offjniitem(t0)
- ldc1 fa0,offjniitem(t0)
- daddi s7,s7,-1
- blez s7,calljava_argsloaded
-
- ald a1,offjniitem+sizejniblock*1(t0)
- ldc1 fa1,offjniitem+sizejniblock*1(t0)
- daddi s7,s7,-1
- blez s7,calljava_argsloaded
-
- ald a2,offjniitem+sizejniblock*2(t0)
- ldc1 fa2,offjniitem+sizejniblock*2(t0)
- daddi s7,s7,-1
- blez s7,calljava_argsloaded
-
- ald a3,offjniitem+sizejniblock*3(t0)
- ldc1 fa3,offjniitem+sizejniblock*3(t0)
- daddi s7,s7,-1
- blez s7,calljava_argsloaded
-
- ald a4,offjniitem+sizejniblock*4(t0)
- ldc1 fa4,offjniitem+sizejniblock*4(t0)
- daddi s7,s7,-1
- blez s7,calljava_argsloaded
-
- ald a5,offjniitem+sizejniblock*5(t0)
- ldc1 fa5,offjniitem+sizejniblock*5(t0)
- daddi s7,s7,-1
- blez s7,calljava_argsloaded
-
- ald a6,offjniitem+sizejniblock*6(t0)
- ldc1 fa6,offjniitem+sizejniblock*6(t0)
- daddi s7,s7,-1
- blez s7,calljava_argsloaded
-
- ald a7,offjniitem+sizejniblock*7(t0)
- ldc1 fa7,offjniitem+sizejniblock*7(t0)
- daddi s7,s7,-1
-
-calljava_argsloaded:
- move t8,sp /* save stack pointer */
- blez s7,calljava_nocopy
- subu t1,zero,s7
- sll t2,t1,3
- aaddu sp,sp,t2
- aaddu t2,t2,t8
-
-calljava_copyloop:
- ald t3,offjniitem+sizejniblock*8(t0)
- ast t3,0(t2)
- ala t1,1(t1)
- ala t0,sizejniblock(t0)
- ala t2,8(t2)
- bnez t1,calljava_copyloop
-
-calljava_nocopy:
- ald itmp1,4*8(t8) /* pass method pointer via itmp1 */
-
- ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
- ast mptr,2*8(t8) /* store function address */
- ala mptr,1*8(t8) /* set method pointer */
-
- .set noreorder
-
- ald pv,1*8(mptr) /* method call as in Java */
- jalr pv /* call JIT compiler */
+L_asm_vm_call_method_stack_copy_done:
+ ala mptr,4*8(s0) /* get address of PV */
+ ald pv,0*8(mptr) /* load PV */
+ jalr pv
nop
+L_asm_vm_call_method_recompute_pv:
+#if SIZEOF_VOID_P == 8
aaddiu pv,ra,-76*4 /* recompute procedure vector */
+#else
+ aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
+#endif
- .set reorder
+ .set reorder /* XXX we need to recompute pv */
calljava_return2:
- ald ra,0(sp) /* restore return address */
- ald pv,8(sp) /* restore procedure vector */
- ald s7,3*8(sp)
-
- ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
- ldc1 fss1,6*8(sp)
- ldc1 fss2,7*8(sp)
- ldc1 fss3,8*8(sp)
- ldc1 fss4,9*8(sp)
- ldc1 fss5,10*8(sp)
+ move sp,s0 /* restore stack pointer */
+
+ ald ra,0*8(sp) /* restore return address */
+ ald pv,1*8(sp) /* restore procedure vector */
+ ald s0,3*8(sp)
+
+#if SIZEOF_VOID_P == 8
+ l.d fss0,5*8(sp) /* restore non JavaABI saved flt regs */
+ l.d fss1,6*8(sp)
+ l.d fss2,7*8(sp)
+ l.d fss3,8*8(sp)
+ l.d fss4,9*8(sp)
+ l.d fss5,10*8(sp)
+#endif
aaddiu sp,sp,12*8 /* free stack space */
j ra /* return */
-calljava_xhandler2:
- asll s7,s7,3
- aaddu sp,s7,sp
+asm_vm_call_method_exception_handler:
+ move sp,s0 /* restore stack pointer */
+#if SIZEOF_VOID_P == 4
+ aaddiu sp,sp,-4*4 /* reserve space for 1 argument */
+#endif
+
move a0,itmp1
jal builtin_throw_exception
+#if SIZEOF_VOID_P == 4
+ aaddiu sp,sp,4*4
+#endif
+asm_vm_call_method_end:
b calljava_return2
- .end asm_calljavafunction2
-
-
-/****************** function asm_call_jit_compiler *****************************
-* *
-* invokes the compiler for untranslated JavaVM methods. *
-* *
-* Register REG_ITEMP1 contains a pointer to the method info structure *
-* (prepared by createcompilerstub). Using the return address in R31 and the *
-* offset in the LDA instruction or using the value in methodptr R25 the *
-* patching address for storing the method address can be computed: *
-* *
-* method address was either loaded using *
-* M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
-* M_JSR (REG_RA, REG_PV); *
-* M_NOP *
-* M_LDA (REG_PV, REG_RA, val) *
-* or *
-* M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
-* M_JSR (REG_RA, REG_PV); *
-* M_NOP *
-* in the static case the method pointer can be computed using the *
-* return address and the lda function following the jmp instruction *
-* *
-*******************************************************************************/
+ .end asm_vm_call_method
- .ent asm_call_jit_compiler
+/* asm_handle_exception ********************************************************
-asm_call_jit_compiler:
- lw t0,-12(ra) /* load instruction LD PV,xxx($y) */
- srl t0,t0,21 /* shift right register number $y */
- and t0,t0,31 /* isolate register number */
- addiu t0,t0,-mptrreg /* test for REG_METHODPTR */
- beqz t0,noregchange
+ This function handles an exception. It does not use the usual calling
+ conventions. The exception pointer is passed in REG_ITMP1 and the
+ pc from the exception raising position is passed in REG_ITMP2. It searches
+ the local exception table for a handler. If no one is found, it unwinds
+ stacks and continues searching the callers.
- lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
- aaddu mptr,t0,ra /* compute update address */
-
-noregchange:
- aaddiu sp,sp,-(20*8+sizestackframeinfo) /* allocate stack space */
-
- SAVE_ARGUMENT_REGISTERS(0)
-
- ast mptr,16*8(sp) /* save method pointer */
- ast ra,17*8(sp) /* save return address */
- ast itmp1,18*8(sp) /* save methodinfo pointer */
-
- aaddiu a0,sp,20*8 /* create stackframe info */
- move a1,zero /* we don't have pv handy */
- aaddiu a2,sp,(20*8+sizestackframeinfo) /* pass java sp */
- move a3,ra /* pass java ra */
- move a4,a3 /* xpc is equal to ra */
- jal stacktrace_create_extern_stackframeinfo
-
- ald a0,18*8(sp) /* pass methodinfo pointer */
- jal jit_compile /* jit compiler */
- ast v0,18*8(sp) /* save return value */
-
- aaddiu a0,sp,20*8 /* remove stackframe info */
- jal stacktrace_remove_stackframeinfo
-
- RESTORE_ARGUMENT_REGISTERS(0)
-
- ald mptr,16*8(sp) /* restore method pointer */
- ald ra,17*8(sp) /* restore return address */
- ald v0,18*8(sp) /* restore return value */
- aaddiu sp,sp,20*8+sizestackframeinfo /* deallocate stack area */
-
- beqz v0,L_asm_call_jit_compiler_exception
-
- lw t0,-12(ra) /* load instruction LDQ PV,xxx($yy) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
-
- aaddu t0,t0,mptr /* compute update address via method pointer*/
- ast v0,0(t0) /* save new method address there */
-
- move pv,v0 /* move method address into pv */
+*******************************************************************************/
- jr pv /* and call method. The method returns */
- /* directly to the caller (ra). */
+ .ent asm_handle_nat_exception
-L_asm_call_jit_compiler_exception:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- aaddiu sp,sp,-2*8
- ast ra,0*8(sp)
- jal builtin_asm_get_exceptionptrptr
- ald ra,0*8(sp)
- aaddiu sp,sp,2*8
+asm_handle_nat_exception:
+L_asm_handle_exception_stack_loop:
+#if SIZEOF_VOID_P == 8
+ aaddiu sp,sp,-6*8 /* keep stack 16-byte aligned */
+ ast xptr,0*8(sp) /* save exception pointer */
+ ast xpc,1*8(sp) /* save exception pc */
+ ast ra,3*8(sp) /* save RA */
+ ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
#else
- la v0,_exceptionptr
+ aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
+ ast xptr,4*4+0*8(sp) /* save exception pointer */
+ ast xpc,4*4+1*8(sp) /* save exception pc */
+ ast ra,4*4+3*8(sp) /* save return address */
+ ast zero,4*4+4*8(sp) /* save maybe-leaf flag (cleared) */
#endif
- ald xptr,0(v0) /* get the exception pointer */
- ast zero,0(v0) /* clear the exception pointer */
-
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4 */
- b asm_handle_nat_exception
- .end asm_call_jit_compiler
+ move a0,ra /* pass RA */
+ jal md_asm_codegen_get_pv_from_pc /* get PV from RA */
+#if SIZEOF_VOID_P == 8
+ ast v0,2*8(sp) /* save PV */
-/********************* function asm_handle_exception ***************************
-* *
-* This function handles an exception. It does not use the usual calling *
-* conventions. The exception pointer is passed in REG_ITMP1 and the *
-* pc from the exception raising position is passed in REG_ITMP2. It searches *
-* the local exception table for a handler. If no one is found, it unwinds *
-* stacks and continues searching the callers. *
-* *
-* void asm_handle_exception (exceptionptr, exceptionpc); *
-* *
-*******************************************************************************/
+ ald a0,0*8(sp) /* pass xptr */
+ ald a1,1*8(sp) /* pass xpc */
+ move a2,v0 /* pass PV */
+ aaddiu a3,sp,6*8 /* pass Java SP */
+#else
+ ast v0,4*4+2*8(sp) /* save data segment pointer */
- .ent asm_handle_nat_exception
+ ald a0,4*4+0*8(sp) /* pass exception pointer */
+ ald a1,4*4+1*8(sp) /* pass exception pc */
+ move a2,v0 /* pass data segment pointer */
+ aaddiu a3,sp,(4*4+6*8) /* pass Java stack pointer */
+#endif
-asm_handle_nat_exception:
- lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
- aaddu pv,t0,ra /* compute update address */
+ b L_asm_handle_exception_continue
.aent asm_handle_exception
asm_handle_exception:
- aaddiu sp,sp,-14*8 /* allocate stack */
-
- sd v0,0*8(sp) /* save possible used registers */
- sd t0,1*8(sp) /* also registers used by trace_exception */
- sd t1,2*8(sp)
- sd t2,3*8(sp)
- sd t3,4*8(sp)
- sd t8,5*8(sp)
- sd a0,6*8(sp)
- sd a1,7*8(sp)
- sd a2,8*8(sp)
- sd a3,9*8(sp)
- sd a4,10*8(sp)
- sd a5,11*8(sp)
- sd a6,12*8(sp)
- sd a7,13*8(sp)
-
- addu t3,zero,1 /* set no unwind flag */
-ex_stack_loop:
- aaddiu sp,sp,-6*8 /* allocate stack */
- sd xptr,0*8(sp) /* save used registers */
- sd xpc,1*8(sp)
- sd pv,2*8(sp)
- sd ra,3*8(sp)
- sd t3,4*8(sp)
-
- move a0,xptr
- ald a1,MethodPointer(pv)
- move a2,xpc
-/* move a3,t3 */
- move a3,zero
- addu a4,zero,1
- jal builtin_trace_exception /* trace_exception(xptr,methodptr) */
-
- ld xptr,0*8(sp) /* restore used register */
- ld xpc,1*8(sp)
- ld pv,2*8(sp)
- ld ra,3*8(sp)
- ld t3,4*8(sp)
- aaddiu sp,sp,6*8 /* deallocate stack */
-
- lw t0,ExTableSize(pv) /* t0 = exception table size */
- beqz t0,empty_table /* if empty table skip */
- aaddiu t1,pv,ExTableStart /* t1 = start of exception table */
-
-ex_table_loop:
- ald t2,ExStartPC(t1) /* t2 = exception start pc */
- sle t2,t2,xpc /* t2 = (startpc <= xpc) */
- beqz t2,ex_table_cont /* if (false) continue */
- ald t2,ExEndPC(t1) /* t2 = exception end pc */
- slt t2,xpc,t2 /* t2 = (xpc < endpc) */
- beqz t2,ex_table_cont /* if (false) continue */
- ald a1,ExCatchType(t1) /* arg1 = exception catch type */
- beqz a1,ex_handle_it /* NULL catches everything */
-
- lw itmp3,offclassloaded(a1)
- bnez itmp3,L_class_loaded
-
- aaddiu sp,sp,-8*8 /* allocate stack */
- sd t0,0*8(sp) /* save used register */
- sd t1,1*8(sp)
- sd t3,2*8(sp)
- sd xptr,3*8(sp)
- sd xpc,4*8(sp)
- sd pv,5*8(sp)
- sd ra,6*8(sp)
- sd a1,7*8(sp)
-
- move a0,a1
- jal load_class_bootstrap
-
- ld t0,0*8(sp) /* restore used register */
- ld t1,1*8(sp)
- ld t3,2*8(sp)
- ld xptr,3*8(sp)
- ld xpc,4*8(sp)
- ld pv,5*8(sp)
- ld ra,6*8(sp)
- ld a1,7*8(sp)
- aaddiu sp,sp,8*8 /* deallocate stack */
-
-L_class_loaded:
- lw itmp3,offclasslinked(a1)
- aaddiu sp,sp,-8*8 /* allocate stack */
- sd a1,7*8(sp)
- bnez itmp3,L_class_linked
-
- sd t0,0*8(sp) /* save used register */
- sd t1,1*8(sp)
- sd t3,2*8(sp)
- sd xptr,3*8(sp)
- sd xpc,4*8(sp)
- sd pv,5*8(sp)
- sd ra,6*8(sp)
-
- move a0,a1
- jal link_class
-
- ld t0,0*8(sp) /* restore used register */
- ld t1,1*8(sp)
- ld t3,2*8(sp)
- ld xptr,3*8(sp)
- ld xpc,4*8(sp)
- ld pv,5*8(sp)
- ld ra,6*8(sp)
-
-L_class_linked:
-_crit_restart1:
- ld a1,7*8(sp)
-_crit_begin1:
- ald a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
- ald a1,offclassvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
- lw a0,offbaseval(a0) /* a0 = baseval(xptr) */
- lw v0,offbaseval(a1) /* a2 = baseval(catchtype) */
- lw a1,offdiffval(a1) /* a1 = diffval(catchtype) */
-_crit_end1:
- subu a0,a0,v0 /* a0 = baseval(xptr) - baseval(catchtype) */
- sltu v0,a1,a0 /* v0 = xptr is instanceof catchtype */
- aaddiu sp,sp,8*8 /* deallocate stack */
- bnez v0,ex_table_cont /* if (false) continue */
-
-ex_handle_it:
- ald xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
-
- beqz t3,ex_jump /* if (!(no stack unwinding) skip */
-
- ld v0,0*8(sp) /* restore possible used registers */
- ld t0,1*8(sp) /* also registers used by trace_exception */
- ld t1,2*8(sp)
- ld t2,3*8(sp)
- ld t3,4*8(sp)
- ld t8,5*8(sp)
- ld a0,6*8(sp)
- ld a1,7*8(sp)
- ld a2,8*8(sp)
- ld a3,9*8(sp)
- ld a4,10*8(sp)
- ld a5,11*8(sp)
- ld a6,12*8(sp)
- ld a7,13*8(sp)
-
- aaddiu sp,sp,14*8 /* deallocate stack */
-
-ex_jump:
- jr xpc /* jump to the handler */
-
-ex_table_cont:
- aaddiu t1,t1,ExEntrySize /* next exception table entry */
- addiu t0,t0,-1 /* decrement entry counter */
- bgtz t0,ex_table_loop /* if (t0 > 0) next entry */
-
-empty_table:
- beqz t3,ex_already_cleared /* if here the first time, then */
- aaddiu sp,sp,14*8 /* deallocate stack and */
- move t3,zero /* clear the no unwind flag */
-ex_already_cleared:
- lw t0,IsSync(pv) /* t0 = SyncOffset */
- beqz t0,no_monitor_exit /* if zero no monitorexit */
-
-#if defined(USE_THREADS)
- aaddu t0,sp,t0 /* add stackptr to Offset */
- ald a0,-8(t0) /* load monitorexit pointer */
-
- aaddiu sp,sp,-8*8 /* allocate stack */
- sd t0,0*8(sp) /* save used register */
- sd t1,1*8(sp)
- sd t3,2*8(sp)
- sd xptr,3*8(sp)
- sd xpc,4*8(sp)
- sd pv,5*8(sp)
- sd ra,6*8(sp)
-
- jal builtin_monitorexit /* builtin_monitorexit(objectptr) */
-
- ld t0,0*8(sp) /* restore used register */
- ld t1,1*8(sp)
- ld t3,2*8(sp)
- ld xptr,3*8(sp)
- ld xpc,4*8(sp)
- ld pv,5*8(sp)
- ld ra,6*8(sp)
- aaddiu sp,sp,8*8 /* deallocate stack */
+ aaddiu sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
+
+ SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
+ SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
+
+#if SIZEOF_VOID_P == 8
+ aaddiu sp,sp,-6*8 /* allocate stack */
+ ast xptr,0*8(sp) /* save exception pointer */
+ ast pv,2*8(sp) /* save PV */
+ ast ra,3*8(sp) /* save RA */
+ addu t0,zero,1 /* set maybe-leaf flag */
+ ast t0,4*8(sp) /* save maybe-leaf flag */
+#else
+ aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
+ ast xptr,4*4+0*8(sp) /* save exception pointer */
+ ast xpc,4*4+1*8(sp) /* save exception pc */
+ ast pv,4*4+2*8(sp) /* save data segment pointer */
+ ast ra,4*4+3*8(sp) /* save return address */
+ addu t0,zero,1 /* set maybe-leaf flag */
+ ast t0,4*4+4*8(sp) /* save maybe-leaf flag */
#endif
-no_monitor_exit:
- lw t0,FrameSize(pv) /* t0 = frame size */
- aaddu sp,sp,t0 /* unwind stack */
- move t0,sp /* t0 = pointer to save area */
- lw t1,IsLeaf(pv) /* t1 = is leaf procedure */
- bnez t1,ex_no_restore /* if (leaf) skip */
- ld ra,-8(t0) /* restore ra */
- aaddiu t0,t0,-8 /* t0-- */
-ex_no_restore:
- move xpc,ra /* the new xpc is ra */
- lw t1,IntSave(pv) /* t1 = saved int register count */
- ala t2,ex_int2 /* t2 = current pc */
- sll t1,t1,2 /* t1 = register count * 4 */
- asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
- jr t2 /* jump to save position */
- ld s0,-8*8(t0)
- ld s1,-7*8(t0)
- ld s2,-6*8(t0)
- ld s3,-5*8(t0)
- ld s4,-4*8(t0)
- ld s5,-3*8(t0)
- ld s6,-2*8(t0)
- ld s7,-1*8(t0)
-ex_int2:
- sll t1,t1,1 /* t1 = register count * 4 * 2 */
- asubu t0,t0,t1 /* t0 = t0 - 8 * register count */
-
- lw t1,FltSave(pv) /* t1 = saved flt register count */
- ala t2,ex_flt2 /* t2 = current pc */
- sll t1,t1,2 /* t1 = register count * 4 */
- asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
- jr t2 /* jump to save position */
- ldc1 fs0,-4*8(t0)
- ldc1 fs1,-3*8(t0)
- ldc1 fs2,-2*8(t0)
- ldc1 fs3,-1*8(t0)
-ex_flt2:
- lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
- aaddu pv,t0,ra /* compute update address */
- b ex_stack_loop
-
- .end asm_handle_nat_exception
-
+ move a0,xptr /* pass xptr */
+ move a1,xpc /* pass xpc */
+ move a2,pv /* pass PV */
-/* asm_wrapper_patcher *********************************************************
-
- 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
-
-*******************************************************************************/
-
- .ent asm_wrapper_patcher
-
-asm_wrapper_patcher:
- aaddiu sp,sp,-((16+21+4)*8+sizestackframeinfo) /* create stack frame */
-
- SAVE_ARGUMENT_REGISTERS(0) /* save 8 int/8 float argument registers */
- SAVE_TEMPORARY_REGISTERS(16) /* save 5 int/16 float temporary registers */
-
- ast itmp1,(16+21+0)*8(sp) /* save itmp1 */
- ast itmp2,(16+21+1)*8(sp) /* save itmp2 */
- ast ra,(16+21+2)*8(sp) /* save method return address (for leafs) */
- ast pv,(16+21+3)*8(sp) /* save pv of calling java function */
-
- aaddiu a0,sp,(16+21+4)*8 /* create stackframe info */
- move a1,pv /* pass java pv */
- aaddiu a2,sp,((6+16+21+4)*8+sizestackframeinfo) /* pass java sp */
- move a3,ra /* this is correct for leafs */
- ald a4,((5+16+21+4)*8+sizestackframeinfo)(sp) /* pass xpc */
- jal stacktrace_create_extern_stackframeinfo
-
- aaddiu a0,sp,((0+16+21+4)*8+sizestackframeinfo) /* pass sp */
- ald itmp3,((0+16+21+4)*8+sizestackframeinfo)(sp) /* get function */
- ald itmp1,(16+21+3)*8(sp) /* save pv to the position of fp */
- ast itmp1,((0+16+21+4)*8+sizestackframeinfo)(sp)
- jalr itmp3
- ast v0,((0+16+21+4)*8+sizestackframeinfo)(sp) /* save return value */
-
- aaddiu a0,sp,(16+21+4)*8 /* remove stackframe info */
- jal stacktrace_remove_stackframeinfo
-
- RESTORE_ARGUMENT_REGISTERS(0) /* restore 8 int/8 float argument registers */
- RESTORE_TEMPORARY_REGISTERS(16) /* restore 5 int/16 float temporary reg. */
-
- ald itmp1,(16+21+0)*8(sp) /* restore itmp1 */
- ald itmp2,(16+21+1)*8(sp) /* restore itmp2 */
- ald ra,(16+21+2)*8(sp) /* restore method return address (for leafs)*/
- ald pv,(16+21+3)*8(sp) /* restore pv of calling java function */
-
- ald v0,((0+16+21+4)*8+sizestackframeinfo)(sp) /* restore return value */
-
- ald itmp3,((5+16+21+4)*8+sizestackframeinfo)(sp) /* get ra to jit code*/
- aaddiu sp,sp,((6+16+21+4)*8+sizestackframeinfo) /* remove stack frame */
-
- beqz v0,L_asm_wrapper_patcher_exception
-
- jr itmp3 /* jump to new patched code */
-
-L_asm_wrapper_patcher_exception:
- move xpc,itmp3 /* return address into JIT code is xpc */
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- daddiu sp,sp,-4*8
- sd xpc,0*8(sp)
- sd ra,1*8(sp)
- sd pv,2*8(sp)
- jal builtin_asm_get_exceptionptrptr
- ld xpc,0*8(sp)
- ld ra,1*8(sp)
- ld pv,2*8(sp)
- daddiu sp,sp,4*8
+#if SIZEOF_VOID_P == 8
+ aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP */
#else
- la v0,_exceptionptr
+ aaddiu a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
#endif
- ld xptr,0(v0) /* get the exception pointer */
- sd zero,0(v0) /* clear the exception pointer */
- b asm_handle_exception
- .end asm_wrapper_patcher
-
-
-/******************* function asm_initialize_thread_stack **********************
-* *
-* u1* asm_initialize_thread_stack (void *func, u1 *stack); *
-* *
-* initialize a thread stack *
-* *
-*******************************************************************************/
-
- .ent asm_initialize_thread_stack
-
-asm_initialize_thread_stack:
- aaddiu a1,a1,-14*8 /* allocate save area */
- sd zero, 0*8(a1) /* s0 initalize thread area */
- sd zero, 1*8(a1) /* s1 */
- sd zero, 2*8(a1) /* s2 */
- sd zero, 3*8(a1) /* s3 */
- sd zero, 4*8(a1) /* s4 */
- sd zero, 5*8(a1) /* s5 */
- sd zero, 6*8(a1) /* s6 */
- sd zero, 7*8(a1) /* s7 */
- sd zero, 8*8(a1) /* s8 */
- sd zero, 9*8(a1) /* fs0 */
- sd zero,10*8(a1) /* fs1 */
- sd zero,11*8(a1) /* fs2 */
- sd zero,12*8(a1) /* fs3 */
- sd a0, 13*8(a1)
- move v0,a1
- j ra /* return */
-
- .end asm_initialize_thread_stack
-
-
-/******************* function asm_perform_threadswitch *************************
-* *
-* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
-* *
-* performs a threadswitch *
-* *
-*******************************************************************************/
+L_asm_handle_exception_continue:
+ jal exceptions_handle_exception
+
+ beqz v0,L_asm_handle_exception_not_catched
- .ent asm_perform_threadswitch
-
-asm_perform_threadswitch:
- aaddiu sp,sp,-14*8 /* allocate new stack */
- sd s0, 0*8(sp) /* save saved registers of old thread */
- sd s1, 1*8(sp)
- sd s2, 2*8(sp)
- sd s3, 3*8(sp)
- sd s4, 4*8(sp)
- sd s5, 5*8(sp)
- sd s6, 6*8(sp)
- sd s7, 7*8(sp)
- sd s8, 8*8(sp)
- sdc1 fs0, 9*8(sp)
- sdc1 fs1,10*8(sp)
- sdc1 fs2,11*8(sp)
- sdc1 fs3,12*8(sp)
- sd ra, 13*8(sp)
- ast sp,0(a0) /* save old stack pointer */
- ast sp,0(a2) /* stackTop = old stack pointer */
- ald sp,0(a1) /* load new stack pointer */
- ld s0, 0*8(sp) /* load saved registers of new thread */
- ld s1, 1*8(sp)
- ld s2, 2*8(sp)
- ld s3, 3*8(sp)
- ld s4, 4*8(sp)
- ld s5, 5*8(sp)
- ld s6, 6*8(sp)
- ld s7, 7*8(sp)
- ld s8, 8*8(sp)
- ldc1 fs0, 9*8(sp)
- ldc1 fs1,10*8(sp)
- ldc1 fs2,11*8(sp)
- ldc1 fs3,12*8(sp)
- ld ra, 13*8(sp)
- aaddiu sp,sp,14*8 /* deallocate new stack */
- move itmp3, ra
- j ra /* return */
-
- .end asm_perform_threadswitch
-
-
-/********************* function asm_switchstackandcall *************************
-* *
-* void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
-* *
-* Switches to a new stack, calls a function and switches back. *
-* a0 new stack pointer *
-* a1 function pointer *
-* a2 pointer to variable where stack top should be stored *
-* *
-*******************************************************************************/
+ move xpc,v0 /* move handlerpc into xpc */
- .ent asm_switchstackandcall
+#if SIZEOF_VOID_P == 8
+ ald xptr,0*8(sp) /* restore exception pointer */
+ ald pv,2*8(sp) /* restore PV */
+ ald ra,3*8(sp) /* restore RA */
+ ald t0,4*8(sp) /* get maybe-leaf flag */
+ aaddiu sp,sp,6*8 /* free stackframe */
+#else
+ ald xptr,4*4+0*8(sp) /* restore exception pointer */
+ ald pv,4*4+2*8(sp) /* restore data segment pointer */
+ ald ra,4*4+3*8(sp) /* restore return address */
+ ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
+ aaddiu sp,sp,4*4+6*8 /* free stackframe */
+#endif
+
+ beqz t0,L_asm_handle_exception_no_leaf
-asm_switchstackandcall:
- aaddiu a0,a0,-16 /* allocate new stack */
- sd ra,0(a0) /* save return address on new stack */
- sd sp,8(a0) /* save old stack pointer on new stack */
- sd sp,0(a2) /* save old stack pointer to variable */
- move sp,a0 /* switch to new stack */
+ RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
+ RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
+
+ aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
+
+L_asm_handle_exception_no_leaf:
+ jr xpc /* jump to the handler */
+
+L_asm_handle_exception_not_catched:
+#if SIZEOF_VOID_P == 8
+ ald xptr,0*8(sp) /* restore xptr */
+ ald pv,2*8(sp) /* restore PV */
+ ald ra,3*8(sp) /* restore RA */
+ ald t0,4*8(sp) /* get maybe-leaf flag */
+ aaddiu sp,sp,6*8 /* free stackframe */
+#else
+ ald xptr,4*4+0*8(sp) /* restore xptr */
+ ald pv,4*4+2*8(sp) /* restore PV */
+ ald ra,4*4+3*8(sp) /* restore RA */
+ ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
+ aaddiu sp,sp,4*4+6*8 /* free stackframe */
+#endif
- move itmp3,a1
- move a0,a3
- jalr itmp3 /* and call function */
+ beqz t0,L_asm_handle_exception_no_leaf_stack
+
+ aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
+ move t0,zero /* clear the maybe-leaf flag */
+
+L_asm_handle_exception_no_leaf_stack:
+ lw t1,FrameSize(pv) /* get frame size */
+ aaddu t1,sp,t1 /* pointer to save area */
+
+ lw t2,IsLeaf(pv) /* is leaf procedure */
+ bnez t2,L_asm_handle_exception_no_ra_restore
+
+ ald ra,-1*8(t1) /* restore ra */
+ aaddiu t1,t1,-8 /* t1-- */
+
+L_asm_handle_exception_no_ra_restore:
+ move xpc,ra /* the new xpc is ra */
+ lw t2,IntSave(pv) /* t1 = saved int register count */
+ ala t3,ex_int2 /* t3 = current pc */
+ sll t2,t2,2 /* t2 = register count * 4 */
+ asubu t3,t3,t2 /* t3 = IntSave - 4 * register count */
+ jr t3 /* jump to save position */
+
+ ald s0,-8*8(t1)
+ ald s1,-7*8(t1)
+ ald s2,-6*8(t1)
+ ald s3,-5*8(t1)
+ ald s4,-4*8(t1)
+ ald s5,-3*8(t1)
+ ald s6,-2*8(t1)
+ ald s7,-1*8(t1)
- ld ra,0(sp) /* load return address */
- ld sp,8(sp) /* switch to old stack */
+ex_int2:
+ sll t2,t2,1 /* t2 = register count * 4 * 2 */
+ asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
+
+ lw t2,FltSave(pv) /* t2 = saved flt register count */
+ ala t3,ex_flt2 /* t3 = current pc */
+ sll t2,t2,2 /* t2 = register count * 4 */
+ asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
+ jr t3 /* jump to save position */
+
+#if SIZEOF_VOID_P == 8
+ l.d fs0,-4*8(t1)
+ l.d fs1,-3*8(t1)
+ l.d fs2,-2*8(t1)
+ l.d fs3,-1*8(t1)
+#else
+# if !defined(ENABLE_SOFT_FLOAT)
+ l.d fs0,-6*8(t1)
+ l.d fs1,-5*8(t1)
+ l.d fs2,-4*8(t1)
+ l.d fs3,-3*8(t1)
+ l.d fs4,-2*8(t1)
+ l.d fs5,-1*8(t1)
+# endif
+#endif
- j ra /* return */
+ex_flt2:
+ lw t1,FrameSize(pv) /* get frame size */
+ aaddu sp,sp,t1 /* unwind stack */
+ b L_asm_handle_exception_stack_loop
- .end asm_switchstackandcall
+ .end asm_handle_nat_exception
- .ent asm_getclassvalues_atomic
+/* asm_abstractmethoderror *****************************************************
-asm_getclassvalues_atomic:
-_crit_restart2:
-_crit_begin2:
- lw t0,offbaseval(a0)
- lw t1,offdiffval(a0)
- lw t2,offbaseval(a1)
-_crit_end2:
- sw t0,offcast_super_baseval(a2)
- sw t1,offcast_super_diffval(a2)
- sw t2,offcast_sub_baseval(a2)
- j ra
+ Creates and throws an AbstractMethodError.
- .end asm_getclassvalues_atomic
+*******************************************************************************/
- .data
+ .ent asm_abstractmethoderror
-asm_criticalsections:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- .dword _crit_begin1
- .dword _crit_end1
- .dword _crit_restart1
- .dword _crit_begin2
- .dword _crit_end2
- .dword _crit_restart2
-#endif
- .dword 0
+asm_abstractmethoderror:
+ aaddiu sp,sp,-2*8 /* create stackframe */
+ ast ra,0*8(sp) /* save return address */
+ aaddiu a0,sp,2*8 /* pass java sp */
+ move a1,ra /* pass exception address */
+ jal exceptions_asm_new_abstractmethoderror
+ ald ra,0*8(sp) /* restore return address */
+ aaddiu sp,sp,2*8 /* remove stackframe */
+ move xptr,v0 /* get exception pointer */
+ aaddiu xpc,ra,-4 /* exception address is ra - 4 */
+ b asm_handle_nat_exception
- .text
+ .end asm_abstractmethoderror
- .ent compare_and_swap
-compare_and_swap:
-1:
- all v0,0(a0)
- bne v0,a1,2f
- move t0,a2
- asc t0,0(a0)
- beqz t0,1b
-2:
- sync
- j ra
+/* disable exec-stacks ********************************************************/
- .end compare_and_swap
+#if defined(__linux__) && defined(__ELF__)
+ .section .note.GNU-stack,"",%progbits
+#endif
/*
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/