X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Fasmpart.S;h=20d546af36324ba274bb4d1f7afc63f3db04b67d;hb=0902c5271401a01d4f4a80bf5841c6ba77b28f46;hp=866a9d821faa5e7eb72b71921a5900b417b857ef;hpb=a07c7f1d727b1c8b40e5bfe20912d91808325fbd;p=cacao.git diff --git a/src/vm/jit/mips/asmpart.S b/src/vm/jit/mips/asmpart.S index 866a9d821..20d546af3 100644 --- a/src/vm/jit/mips/asmpart.S +++ b/src/vm/jit/mips/asmpart.S @@ -1,9 +1,9 @@ -/* 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 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 This file is part of CACAO. @@ -19,158 +19,55 @@ 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. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. - Contact: cacao@complang.tuwien.ac.at + Contact: cacao@cacaojvm.org Authors: Andreas Krall - $Id: asmpart.S 1861 2005-01-04 16:40:12Z twisti $ + Changes: Christian Thalinger + Edwin Steiner + + $Id: asmpart.S 4654 2006-03-19 19:46:11Z edwin $ */ #include "config.h" + +#include "vm/jit/mips/md-abi.h" +#include "vm/jit/mips/md-asm.h" #include "vm/jit/mips/offsets.h" -#include "vm/jit/mips/asmoffsets.h" - - -#define zero $0 -#define itmp1 $1 -#define v0 $2 -#define itmp2 $3 -#define a0 $4 -#define a1 $5 -#define a2 $6 -#define a3 $7 - -#define a4 $8 -#define a5 $9 -#define a6 $10 -#define a7 $11 -#define t0 $12 -#define t1 $13 -#define t2 $14 -#define t3 $15 - -#define s0 $16 -#define s1 $17 -#define s2 $18 -#define s3 $19 -#define s4 $20 -#define s5 $21 -#define s6 $22 -#define s7 $23 - -#define t8 $24 -#define itmp3 $25 -#define k0 $26 -#define k1 $27 - -#define gp $28 -#define sp $29 -#define s8 $30 -#define ra $31 - -#define pv s8 -#define t9 itmp3 - -#define xptr itmp1 -#define xpc itmp2 -#define mptr itmp3 -#define mptrreg 25 - -#define fv0 $f0 -#define ft0 $f1 -#define ft1 $f2 -#define ft2 $f3 -#define ft3 $f4 -#define ft4 $f5 -#define ft5 $f6 -#define ft6 $f7 - -#define ft7 $f8 -#define ft8 $f9 -#define ft9 $f10 -#define ft10 $f11 -#define fa0 $f12 -#define fa1 $f13 -#define fa2 $f14 -#define fa3 $f15 - -#define fa4 $f16 -#define fa5 $f17 -#define fa6 $f18 -#define fa7 $f19 -#define ft11 $f20 -#define ft12 $f21 -#define ft13 $f22 -#define ft14 $f23 - -#define fs0 $f24 -#define ft15 $f25 -#define fs1 $f26 -#define ft16 $f27 -#define fs2 $f28 -#define ft17 $f29 -#define fs3 $f30 -#define ft18 $f31 - -#define fss0 $f20 -#define fss1 $f22 -#define fss2 $f25 -#define fss3 $f27 -#define fss4 $f29 -#define fss5 $f31 - -#define aaddu daddu -#define asubu dsubu -#define aaddiu daddiu -#define ald ld -#define ast sd -#define ala dla -#define asll dsll -#define ashift 3 + +#include "vm/jit/abi.h" +#include "vm/jit/methodheader.h" .text .set noat -/********************* exported functions and variables ***********************/ +/* export functions ***********************************************************/ - .globl asm_calljavafunction - - .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_call_jit_compiler - .globl asm_dumpregistersandcall .globl asm_handle_exception .globl asm_handle_nat_exception - .globl asm_check_clinit - .globl asm_builtin_checkarraycast - .globl asm_builtin_checkcast - .globl asm_builtin_aastore - -#if defined(USE_THREADS) - .globl asm_builtin_monitorenter - .globl asm_builtin_monitorexit -#endif - .globl asm_builtin_idiv - .globl asm_builtin_irem - .globl asm_builtin_ldiv - .globl asm_builtin_lrem + .globl asm_wrapper_patcher + + .globl asm_replacement_out + .globl asm_replacement_in + .globl asm_perform_threadswitch .globl asm_initialize_thread_stack .globl asm_switchstackandcall - .globl asm_builtin_trace - .globl asm_builtin_exittrace .globl asm_getclassvalues_atomic .globl asm_criticalsections @@ -196,206 +93,140 @@ * * *******************************************************************************/ - .ent asm_calljavafunction + .ent asm_vm_call_method -call_name: .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 /* fltsave */ - .word 0 /* intsave */ - .word 0 /* isleaf */ - .word 0 /* IsSync */ - .word 10*8 /* frame size */ - .dword 0 /* method pointer (pointer to name) */ - -asm_calljavafunction: - aaddiu sp,sp,-10*8 /* allocate stack space */ - sd ra,0(sp) /* save return address */ - - .set noreorder - bal call_java_pc - sd pv,3*8(sp) /* procedure vector */ -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) - sd a0,2*8(sp) /* save method pointer for compiler */ - aaddiu itmp1,sp,16 /* pass pointer to methodptr via itmp1 */ - - move a0,a1 /* pass the remaining parameters */ - move a1,a2 - move a2,a3 - move a3,a4 - - 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 */ - - .set noreorder - - ald pv,1*8(mptr) /* method call as in Java */ - jalr pv /* call JIT compiler */ - nop - aaddiu pv,ra,-23*4 /* recompute procedure vector */ -#if 0 - move v0,zero /* clear return value (exception ptr) */ -#else - nop -#endif - -calljava_return: - ld ra,0(sp) /* restore return address */ - ld 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) - j ra /* return */ - aaddiu sp,sp,10*8 /* free stack space */ - - .set reorder - -calljava_xhandler: - move a0,itmp1 - jal builtin_throw_exception - b calljava_return - - .end asm_calljavafunction - - - .ent asm_calljavafunction2 + .dword 0 /* catch type all */ + .dword calljava_xhandler2 /* handler pc */ + .dword calljava_xhandler2 /* end pc */ + .dword asm_vm_call_method /* 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 0 /* frame size */ + .dword 0 /* method pointer (pointer to name) */ + +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 */ -call_name2: - .align 3 - - .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 /* 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)*/ - sd ra,0(sp) /* save return address */ + ast ra,0(sp) /* save return address */ - .set noreorder - bal call_java_pc2 - sd pv,1*8(sp) /* procedure vector */ -call_java_pc2: + 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 - sd s7,3*8(sp) + ast s7,3*8(sp) - .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) - sd a0,4*8(sp) /* save method pointer for compiler */ - move t0,a3 - move s7,a1 + ast a0,4*8(sp) /* save method pointer for compiler */ + + move t0,a2 + move s7,a1 blez s7,calljava_argsloaded - ald a0,offjniitem(t0) - ldc1 fa0,offjniitem(t0) + nop + + ald a0,offvmargdata(t0) + ldc1 fa0,offvmargdata(t0) daddi s7,s7,-1 blez s7,calljava_argsloaded + nop - ald a1,offjniitem+sizejniblock*1(t0) - ldc1 fa1,offjniitem+sizejniblock*1(t0) + ald a1,offvmargdata+sizevmarg*1(t0) + ldc1 fa1,offvmargdata+sizevmarg*1(t0) daddi s7,s7,-1 blez s7,calljava_argsloaded + nop - ald a2,offjniitem+sizejniblock*2(t0) - ldc1 fa2,offjniitem+sizejniblock*2(t0) + ald a2,offvmargdata+sizevmarg*2(t0) + ldc1 fa2,offvmargdata+sizevmarg*2(t0) daddi s7,s7,-1 blez s7,calljava_argsloaded + nop - ald a3,offjniitem+sizejniblock*3(t0) - ldc1 fa3,offjniitem+sizejniblock*3(t0) + ald a3,offvmargdata+sizevmarg*3(t0) + ldc1 fa3,offvmargdata+sizevmarg*3(t0) daddi s7,s7,-1 blez s7,calljava_argsloaded + nop - ald a4,offjniitem+sizejniblock*4(t0) - ldc1 fa4,offjniitem+sizejniblock*4(t0) + ald a4,offvmargdata+sizevmarg*4(t0) + ldc1 fa4,offvmargdata+sizevmarg*4(t0) daddi s7,s7,-1 blez s7,calljava_argsloaded + nop - ald a5,offjniitem+sizejniblock*5(t0) - ldc1 fa5,offjniitem+sizejniblock*5(t0) + ald a5,offvmargdata+sizevmarg*5(t0) + ldc1 fa5,offvmargdata+sizevmarg*5(t0) daddi s7,s7,-1 blez s7,calljava_argsloaded + nop - ald a6,offjniitem+sizejniblock*6(t0) - ldc1 fa6,offjniitem+sizejniblock*6(t0) + ald a6,offvmargdata+sizevmarg*6(t0) + ldc1 fa6,offvmargdata+sizevmarg*6(t0) daddi s7,s7,-1 blez s7,calljava_argsloaded + nop - ald a7,offjniitem+sizejniblock*7(t0) - ldc1 fa7,offjniitem+sizejniblock*7(t0) + ald a7,offvmargdata+sizevmarg*7(t0) + ldc1 fa7,offvmargdata+sizevmarg*7(t0) daddi s7,s7,-1 calljava_argsloaded: - move t8,sp + move t8,sp /* save stack pointer */ blez s7,calljava_nocopy + nop subu t1,zero,s7 sll t2,t1,3 - daddu sp,sp,t2 - daddu t2,t2,t8 + aaddu sp,sp,t2 + aaddu t2,t2,t8 calljava_copyloop: - ald t3,offjniitem+sizejniblock*8(t0) + ald t3,offvmargdata+sizevmarg*8(t0) ast t3,0(t2) ala t1,1(t1) - ala t0,sizejniblock(t0) + ala t0,sizevmarg(t0) ala t2,8(t2) bnez t1,calljava_copyloop + nop calljava_nocopy: - ala itmp1,32(t8) /* pass pointer to methodptr via itmp1 */ + ald itmp1,4*8(t8) /* pass method pointer via itmp1 */ ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */ - ast mptr,16(sp) /* store function address */ - ala mptr,8(t8) /* set method pointer */ + ast mptr,2*8(t8) /* store function address */ + ala mptr,1*8(t8) /* set method pointer */ - .set noreorder - - ald pv,8(mptr) /* method call as in Java */ + ald pv,1*8(mptr) /* method call as in Java */ jalr pv /* call JIT compiler */ nop +L_asm_vm_call_method_recompute_pv: +/* aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)*/ aaddiu pv,ra,-76*4 /* recompute procedure vector */ + .set reorder /* XXX we need to recompute pv */ + calljava_return2: - ld ra,0(sp) /* restore return address */ - ld pv,8(sp) /* restore procedure vector */ - ld s7,24(sp) + 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) @@ -403,19 +234,18 @@ calljava_return2: ldc1 fss3,8*8(sp) ldc1 fss4,9*8(sp) ldc1 fss5,10*8(sp) - j ra /* return */ + aaddiu sp,sp,12*8 /* free stack space */ + j ra /* return */ - .set reorder - calljava_xhandler2: - sll s7,s7,3 + asll s7,s7,3 aaddu sp,s7,sp move a0,itmp1 jal builtin_throw_exception b calljava_return2 - .end asm_calljavafunction2 + .end asm_vm_call_method /****************** function asm_call_jit_compiler ***************************** @@ -445,759 +275,501 @@ calljava_xhandler2: .ent asm_call_jit_compiler 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 - - 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,-18*8 /* allocate stack space */ - sd a0,0*8(sp) /* save all argument registers */ - sd a1,1*8(sp) /* they could be used by method */ - sd a2,2*8(sp) - sd a3,3*8(sp) - sd a4,4*8(sp) - sd a5,5*8(sp) - sd a6,6*8(sp) - sd a7,7*8(sp) - sdc1 fa0,8*8(sp) - sdc1 fa1,9*8(sp) - sdc1 fa2,10*8(sp) - sdc1 fa3,11*8(sp) - sdc1 fa4,12*8(sp) - sdc1 fa5,13*8(sp) - sdc1 fa6,14*8(sp) - sdc1 fa7,15*8(sp) - sd mptr,16*8(sp) /* save method pointer */ - sd ra,17*8(sp) /* save return address */ - - ald a0,0(itmp1) /* pass 'methodinfo' pointer to */ - jal jit_compile /* jit compiler */ - - ld a0,0*8(sp) /* restore argument registers */ - ld a1,1*8(sp) /* they could be used by method */ - ld a2,2*8(sp) - ld a3,3*8(sp) - ld a4,4*8(sp) - ld a5,5*8(sp) - ld a6,6*8(sp) - ld a7,7*8(sp) - ldc1 fa0,8*8(sp) - ldc1 fa1,9*8(sp) - ldc1 fa2,10*8(sp) - ldc1 fa3,11*8(sp) - ldc1 fa4,12*8(sp) - ldc1 fa5,13*8(sp) - ldc1 fa6,14*8(sp) - ldc1 fa7,15*8(sp) - ld mptr,16*8(sp) /* restore method pointer */ - ld ra,17*8(sp) /* restore return address */ - aaddiu sp,sp,18*8 /* deallocate stack area */ - - 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). */ - - .end asm_call_jit_compiler - - -/********************* 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); * -* * -*******************************************************************************/ + aaddiu sp,sp,-(20*8+sizestackframeinfo) /* allocate stack space */ - .ent asm_handle_nat_exception + SAVE_ARGUMENT_REGISTERS(0) -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 */ + ast mptr,16*8(sp) /* save method pointer */ + ast ra,17*8(sp) /* save return address */ + ast itmp1,18*8(sp) /* save methodinfo pointer */ - .aent asm_handle_exception + 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 */ + ald a3,17*8(sp) /* pass java ra */ + move a4,a3 /* xpc is equal to ra */ + jal stacktrace_create_extern_stackframeinfo -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 class_load - - 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 class_link - - 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 */ -#endif + ald a0,18*8(sp) /* pass methodinfo pointer */ + jal jit_compile /* jit compiler */ + ast v0,18*8(sp) /* save return value */ -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 + aaddiu a0,sp,20*8 /* remove stackframe info */ + jal stacktrace_remove_stackframeinfo - .end asm_handle_nat_exception + ald a0,17*8(sp) /* pass return address */ + aaddiu a1,sp,20*8 /* pass stackframeinfo (for PV) */ + ald a2,16*8(sp) /* pass method pointer */ + jal md_assembler_get_patch_address /* get address of patch position */ + move t0,v0 /* move offset to t0 for later use */ + RESTORE_ARGUMENT_REGISTERS(0) -/********************* asm_check_clinit **************************************** -* * -* Checks if class is initialized. If not, do it right now. * -* * -*******************************************************************************/ - - .ent asm_check_clinit - -asm_check_clinit: - daddiu sp,sp,-24*8 - - sd ra,0*8(sp) /* save return address */ - - sd a0,1*8(sp) /* save argument registers for leaf funcs */ - sd a1,2*8(sp) - sd a2,3*8(sp) - sd a3,4*8(sp) - sd a4,5*8(sp) - sd a5,6*8(sp) - sd a6,7*8(sp) - sd a7,8*8(sp) - - sd t0,9*8(sp) - sd t1,10*8(sp) - sd t2,11*8(sp) - sd t3,12*8(sp) - sd t8,13*8(sp) - - sdc1 fa0,14*8(sp) - sdc1 fa1,15*8(sp) - sdc1 fa2,16*8(sp) - sdc1 fa3,17*8(sp) - sdc1 fa4,18*8(sp) - sdc1 fa5,19*8(sp) - sdc1 fa6,20*8(sp) - sdc1 fa7,21*8(sp) - - sd itmp2,22*8(sp) /* save machine code */ - - /* check if class is initialized */ - lw itmp3,offclassinit(itmp1) - bnez itmp3,L_is_initialized - - move a0,itmp1 /* move class pointer to a0 */ - jal class_init - - beqz v0,L_initializererror + 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 */ -L_is_initialized: - ld ra,0*8(sp) /* get return address */ - ld itmp1,22*8(sp) /* get machine code */ + beqz v0,L_asm_call_jit_compiler_exception - daddiu ra,ra,-2*4 /* go back 2 instructions (jal + nop delay) */ - sw itmp1,0(ra) /* patch first instruction */ - dsrl32 itmp1,itmp1,0 /* get high 32 bit */ - sw itmp1,4(ra) /* patch second instruction */ + ast v0,0(t0) /* store new method address */ + move pv,v0 /* move method address into pv */ + jr pv /* and call method. The method returns */ + /* directly to the caller (ra). */ - move a0,ra /* start of flush area */ - addiu a1,zero,2*4 /* 2 instruction words long */ - jal docacheflush /* flush! */ - - ld ra,0*8(sp) /* restore return address */ - - ld a0,1*8(sp) /* restore argument registers */ - ld a1,2*8(sp) - ld a2,3*8(sp) - ld a3,4*8(sp) - ld a4,5*8(sp) - ld a5,6*8(sp) - ld a6,7*8(sp) - ld a7,8*8(sp) - - ld t0,9*8(sp) - ld t1,10*8(sp) - ld t2,11*8(sp) - ld t3,12*8(sp) - ld t8,13*8(sp) - - ldc1 fa0,14*8(sp) - ldc1 fa1,15*8(sp) - ldc1 fa2,16*8(sp) - ldc1 fa3,17*8(sp) - ldc1 fa4,18*8(sp) - ldc1 fa5,19*8(sp) - ldc1 fa6,20*8(sp) - ldc1 fa7,21*8(sp) - - daddiu sp,sp,24*8 - - daddiu ra,ra,-2*4 /* go back 2 instructions (jal + nop delay) */ - jr ra - -L_initializererror: +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 #else la v0,_exceptionptr #endif - ld xptr,0(v0) /* get the exception pointer */ - sd zero,0(v0) /* clear the exception pointer */ - - ld ra,0*8(sp) /* restore return address */ - - ld a0,1*8(sp) /* restore argument registers */ - ld a1,2*8(sp) - ld a2,3*8(sp) - ld a3,4*8(sp) - ld a4,5*8(sp) - ld a5,6*8(sp) - ld a6,7*8(sp) - ld a7,8*8(sp) - - ld t0,9*8(sp) - ld t1,10*8(sp) - ld t2,11*8(sp) - ld t3,12*8(sp) - ld t8,13*8(sp) - - ldc1 fa0,14*8(sp) - ldc1 fa1,15*8(sp) - ldc1 fa2,16*8(sp) - ldc1 fa3,17*8(sp) - ldc1 fa4,18*8(sp) - ldc1 fa5,19*8(sp) - ldc1 fa6,20*8(sp) - ldc1 fa7,21*8(sp) - - daddiu sp,sp,24*8 + 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_exception + b asm_handle_nat_exception - .end asm_check_clinit + .end asm_call_jit_compiler - -/********************* function asm_builtin_monitorenter *********************** -* * -* Does null check and calls monitorenter or throws an exception * -* * -*******************************************************************************/ -#if defined(USE_THREADS) - .ent asm_builtin_monitorenter +/* asm_handle_exception ******************************************************** -asm_builtin_monitorenter: - beqz a0,nb_monitorenter /* if (null) throw exception */ - ala t9,builtin_monitorenter /* else call builtin_monitorenter */ - j t9 + 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. -nb_monitorenter: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - ald a0,string_java_lang_NullPointerException - jal new_exception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 +*******************************************************************************/ - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception + .ent asm_handle_nat_exception - .end asm_builtin_monitorenter -#endif +asm_handle_nat_exception: +L_asm_handle_exception_stack_loop: + aaddiu sp,sp,-6*8 /* allocate stack */ + ast xptr,0*8(sp) /* save exception pointer */ + ast xpc,1*8(sp) /* save exception pc */ + ast ra,3*8(sp) /* save return address */ + ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */ + move a0,ra /* pass return address */ + jal md_codegen_findmethod /* get PV from RA */ + ast v0,2*8(sp) /* save data segment pointer */ -/********************* function asm_builtin_monitorexit ************************ -* * -* Does null check and calls monitorexit or throws an exception * -* * -*******************************************************************************/ + ald a0,0*8(sp) /* pass exception pointer */ + ald a1,1*8(sp) /* pass exception pc */ + move a2,v0 /* pass data segment pointer */ + aaddiu a3,sp,6*8 /* pass Java stack pointer */ + + b L_asm_handle_exception_continue -#if defined(USE_THREADS) - .ent asm_builtin_monitorexit + .aent asm_handle_exception -asm_builtin_monitorexit: - beqz a0,nb_monitorexit /* if (null) throw exception */ - ala t9,builtin_monitorexit /* else call builtin_monitorexit */ - j t9 +asm_handle_exception: + 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 */ + + aaddiu sp,sp,-6*8 /* allocate stack */ + ast xptr,0*8(sp) /* save exception pointer */ + ast xpc,1*8(sp) /* save exception pc */ + ast pv,2*8(sp) /* save data segment pointer */ + ast ra,3*8(sp) /* save return address */ + addu t0,zero,1 /* set maybe-leaf flag */ + ast t0,4*8(sp) /* save maybe-leaf flag */ + + move a0,xptr /* pass exception pointer */ + move a1,xpc /* pass exception pc */ + move a2,pv /* pass data segment pointer */ + aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */ + +L_asm_handle_exception_continue: + jal exceptions_handle_exception + + beqz v0,L_asm_handle_exception_not_catched + + move xpc,v0 /* move handlerpc into xpc */ + ald xptr,0*8(sp) /* restore exception pointer */ + ald pv,2*8(sp) /* restore data segment pointer */ + ald ra,3*8(sp) /* restore return address */ + ald t0,4*8(sp) /* get maybe-leaf flag */ + aaddiu sp,sp,6*8 /* free stackframe */ + + beqz t0,L_asm_handle_exception_no_leaf -nb_monitorexit: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - jal new_nullpointerexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 + 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 */ - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception +L_asm_handle_exception_no_leaf: + jr xpc /* jump to the handler */ - .end asm_builtin_monitorexit -#endif +L_asm_handle_exception_not_catched: + ald xptr,0*8(sp) /* restore exception pointer */ + ald pv,2*8(sp) /* restore data segment pointer */ + ald ra,3*8(sp) /* restore return address */ + ald t0,4*8(sp) /* get maybe-leaf flag */ + aaddiu sp,sp,6*8 /* free stackframe */ + + 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) +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 */ -/************************ function asm_builtin_idiv **************************** -* * -* Does null check and calls idiv or throws an exception * -* * -*******************************************************************************/ + ldc1 fs0,-4*8(t1) + ldc1 fs1,-3*8(t1) + ldc1 fs2,-2*8(t1) + ldc1 fs3,-1*8(t1) - .ent asm_builtin_idiv +ex_flt2: + lw t1,FrameSize(pv) /* get frame size */ + aaddu sp,sp,t1 /* unwind stack */ + b L_asm_handle_exception_stack_loop -asm_builtin_idiv: - beqz a1,nb_idiv /* if (null) throw exception */ - ala itmp3,builtin_idiv /* else call builtin_idiv */ - j itmp3 + .end asm_handle_nat_exception -nb_idiv: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - jal new_arithmeticexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception +/* asm_wrapper_patcher ********************************************************* - .end asm_builtin_idiv + 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 -/************************ function asm_builtin_ldiv **************************** -* * -* Does null check and calls ldiv or throws an exception * -* * *******************************************************************************/ + + .ent asm_wrapper_patcher - .ent asm_builtin_ldiv - -asm_builtin_ldiv: - beqz a1,nb_ldiv /* if (null) throw exception */ - ala itmp3,builtin_ldiv /* else call builtin_ldiv */ - j itmp3 +asm_wrapper_patcher: + aaddiu sp,sp,-((2+16+22+4)*8+sizestackframeinfo) /* create stack frame */ -nb_ldiv: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - jal new_arithmeticexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 + SAVE_RETURN_REGISTERS(0) /* save 1 int/1 float return registers */ + SAVE_ARGUMENT_REGISTERS(2) /* save 8 int/8 float argument registers */ + SAVE_TEMPORARY_REGISTERS(18) /* save 5 int/16 float temporary registers */ - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception + ast itmp1,(2+16+22+0)*8(sp) /* save itmp1 */ + ast itmp2,(2+16+22+1)*8(sp) /* save itmp2 */ + ast ra,(2+16+22+2)*8(sp) /* save method return address (for leafs) */ + ast pv,(2+16+22+3)*8(sp) /* save pv of calling java function */ - .end asm_builtin_ldiv + aaddiu a0,sp,(2+16+22+4)*8 /* create stackframe info */ + move a1,pv /* pass java pv */ + aaddiu a2,sp,((6+2+16+22+4)*8+sizestackframeinfo) /* pass java sp */ + move a3,ra /* this is correct for leafs */ + ald a4,((5+2+16+22+4)*8+sizestackframeinfo)(sp) /* pass xpc */ + jal stacktrace_create_extern_stackframeinfo + aaddiu a0,sp,((0+2+16+22+4)*8+sizestackframeinfo) /* pass sp */ + ald itmp3,((0+2+16+22+4)*8+sizestackframeinfo)(sp) /* get function */ + ald itmp1,(2+16+22+3)*8(sp) /* save pv to the position of fp */ + ast itmp1,((0+2+16+22+4)*8+sizestackframeinfo)(sp) + jalr itmp3 + ast v0,((0+2+16+22+4)*8+sizestackframeinfo)(sp) /* save return value */ -/************************ function asm_builtin_irem **************************** -* * -* Does null check and calls irem or throws an exception * -* * -*******************************************************************************/ + aaddiu a0,sp,(2+16+22+4)*8 /* remove stackframe info */ + jal stacktrace_remove_stackframeinfo - .ent asm_builtin_irem + RESTORE_RETURN_REGISTERS(0) /* restore 1 int/1 float return registers */ + RESTORE_ARGUMENT_REGISTERS(2) /* restore 8 int/8 float argument registers */ + RESTORE_TEMPORARY_REGISTERS(18) /* restore 5 int/16 float temporary reg. */ -asm_builtin_irem: - beqz a1,nb_irem /* if (null) throw exception */ - ala t9,builtin_irem /* else call builtin_irem */ - j t9 + ald itmp1,(2+16+22+0)*8(sp) /* restore itmp1 */ + ald itmp2,(2+16+22+1)*8(sp) /* restore itmp2 */ + ald ra,(2+16+22+2)*8(sp) /* restore method return address (for leafs)*/ + ald pv,(2+16+22+3)*8(sp) /* restore pv of calling java function */ -nb_irem: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - jal new_arithmeticexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 + ald itmp3,((0+2+16+22+4)*8+sizestackframeinfo)(sp) /* get return value*/ + beqz itmp3,L_asm_wrapper_patcher_exception - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception + ald itmp3,((5+2+16+22+4)*8+sizestackframeinfo)(sp) /* get RA to JIT */ + aaddiu sp,sp,((6+2+16+22+4)*8+sizestackframeinfo) /* remove stack frame */ - .end asm_builtin_irem + jr itmp3 /* jump to new patched code */ +L_asm_wrapper_patcher_exception: + ald xpc,((5+2+16+22+4)*8+sizestackframeinfo)(sp) /* RA to JIT is xpc */ + aaddiu sp,sp,((6+2+16+22+4)*8+sizestackframeinfo) /* remove stack frame */ -/************************ function asm_builtin_lrem **************************** -* * -* Does null check and calls lrem or throws an exception * -* * -*******************************************************************************/ +#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 +#else + la v0,_exceptionptr +#endif + ld xptr,0(v0) /* get the exception pointer */ + sd zero,0(v0) /* clear the exception pointer */ + b asm_handle_exception - .ent asm_builtin_lrem + .end asm_wrapper_patcher -asm_builtin_lrem: - beqz a1,nb_lrem /* if (null) throw exception */ - ala t9,builtin_lrem /* else call builtin_lrem */ - j t9 + +/* asm_replacement_out ********************************************************* -nb_lrem: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - jal new_arithmeticexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 + This code is jumped to from the replacement-out stubs that are executed + when a thread reaches an activated replacement point. - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception + 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. - .end asm_builtin_lrem + 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! -/******************* function asm_builtin_checkarraycast *********************** -* * -* Does the cast check and eventually throws an exception * -* * *******************************************************************************/ - .ent asm_builtin_checkarraycast - -asm_builtin_checkarraycast: - aaddiu sp,sp,-16 /* allocate stack space */ - sd ra,0(sp) /* save return address */ - sd a0,8(sp) /* save object pointer */ - jal builtin_checkarraycast /* builtin_checkarraycast */ - beqz v0,nb_carray_throw /* if (false) throw exception */ - ld ra,0(sp) /* restore return address */ - ld v0,8(sp) /* return object pointer */ - aaddiu sp,sp,16 /* deallocate stack */ - j ra /* return */ +/* 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 */ + daddiu sp,sp,-REPLACEMENT_STACK_OFFSET + + /* save registers in execution state */ + sd $0 ,( 0*8+offes_intregs)(sp) + sd $1 ,( 1*8+offes_intregs)(sp) + sd $2 ,( 2*8+offes_intregs)(sp) + sd $3 ,( 3*8+offes_intregs)(sp) + sd $4 ,( 4*8+offes_intregs)(sp) + sd $5 ,( 5*8+offes_intregs)(sp) + sd $6 ,( 6*8+offes_intregs)(sp) + sd $7 ,( 7*8+offes_intregs)(sp) + sd $8 ,( 8*8+offes_intregs)(sp) + sd $9 ,( 9*8+offes_intregs)(sp) + sd $10,(10*8+offes_intregs)(sp) + sd $11,(11*8+offes_intregs)(sp) + sd $12,(12*8+offes_intregs)(sp) + sd $13,(13*8+offes_intregs)(sp) + sd $14,(14*8+offes_intregs)(sp) + sd $15,(15*8+offes_intregs)(sp) + sd $16,(16*8+offes_intregs)(sp) + sd $17,(17*8+offes_intregs)(sp) + sd $18,(18*8+offes_intregs)(sp) + sd $19,(19*8+offes_intregs)(sp) + sd $20,(20*8+offes_intregs)(sp) + sd $21,(21*8+offes_intregs)(sp) + sd $22,(22*8+offes_intregs)(sp) + sd $23,(23*8+offes_intregs)(sp) + sd $24,(24*8+offes_intregs)(sp) + sd $25,(25*8+offes_intregs)(sp) + sd $26,(26*8+offes_intregs)(sp) + sd $27,(27*8+offes_intregs)(sp) + sd $28,(28*8+offes_intregs)(sp) + sd $29,(29*8+offes_intregs)(sp) + sd $30,(30*8+offes_intregs)(sp) + sd $31,(31*8+offes_intregs)(sp) + + sdc1 $f0 ,( 0*8+offes_fltregs)(sp) + sdc1 $f1 ,( 1*8+offes_fltregs)(sp) + sdc1 $f2 ,( 2*8+offes_fltregs)(sp) + sdc1 $f3 ,( 3*8+offes_fltregs)(sp) + sdc1 $f4 ,( 4*8+offes_fltregs)(sp) + sdc1 $f5 ,( 5*8+offes_fltregs)(sp) + sdc1 $f6 ,( 6*8+offes_fltregs)(sp) + sdc1 $f7 ,( 7*8+offes_fltregs)(sp) + sdc1 $f8 ,( 8*8+offes_fltregs)(sp) + sdc1 $f9 ,( 9*8+offes_fltregs)(sp) + sdc1 $f10,(10*8+offes_fltregs)(sp) + sdc1 $f11,(11*8+offes_fltregs)(sp) + sdc1 $f12,(12*8+offes_fltregs)(sp) + sdc1 $f13,(13*8+offes_fltregs)(sp) + sdc1 $f14,(14*8+offes_fltregs)(sp) + sdc1 $f15,(15*8+offes_fltregs)(sp) + sdc1 $f16,(16*8+offes_fltregs)(sp) + sdc1 $f17,(17*8+offes_fltregs)(sp) + sdc1 $f18,(18*8+offes_fltregs)(sp) + sdc1 $f19,(19*8+offes_fltregs)(sp) + sdc1 $f20,(20*8+offes_fltregs)(sp) + sdc1 $f21,(21*8+offes_fltregs)(sp) + sdc1 $f22,(22*8+offes_fltregs)(sp) + sdc1 $f23,(23*8+offes_fltregs)(sp) + sdc1 $f24,(24*8+offes_fltregs)(sp) + sdc1 $f25,(25*8+offes_fltregs)(sp) + sdc1 $f26,(26*8+offes_fltregs)(sp) + sdc1 $f27,(27*8+offes_fltregs)(sp) + sdc1 $f28,(28*8+offes_fltregs)(sp) + sdc1 $f29,(29*8+offes_fltregs)(sp) + sdc1 $f30,(30*8+offes_fltregs)(sp) + sdc1 $f31,(31*8+offes_fltregs)(sp) + + /* calculate sp of method */ + daddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8) + sd itmp1,(offes_sp)(sp) -nb_carray_throw: - jal new_classcastexception - move xptr,v0 + /* store pv */ + sd pv,(offes_pv)(sp) - ld ra,0(sp) /* restore return address */ - aaddiu sp,sp,16 /* free stack space */ - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception + /* call replace_me */ + ld a0,-(2*8)(itmp1) /* arg0: rplpoint * */ + move a1,sp /* arg1: execution state */ + jal replace_me /* call C function replace_me */ + jal abort /* NEVER REACHED */ - .end asm_builtin_checkarraycast + .end asm_replacement_out +/* asm_replacement_in ********************************************************** -/********************* function asm_builtin_checkcast ************************** -* * -* Does the cast check and eventually throws an exception * -* * -*******************************************************************************/ + This code writes the given execution state and jumps to the replacement + code. - .ent asm_builtin_checkcast - -asm_builtin_checkcast: - aaddiu sp,sp,-16 /* allocate stack space */ - sd ra,0(sp) /* save return address */ - sd a0,8(sp) /* save object pointer */ - jal builtin_checkcast /* builtin_checkcast */ - beqz v0,nb_ccast_throw /* if (false) throw exception */ - ld ra,0(sp) /* restore return address */ - ld v0,8(sp) /* return object pointer */ - aaddiu sp,sp,16 /* deallocate stack */ - j ra /* return */ + This function never returns! -nb_ccast_throw: - jal new_classcastexception - move xptr,v0 - - ld ra,0(sp) /* restore return address */ - aaddiu sp,sp,16 /* free stack space */ - aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ - b asm_handle_nat_exception - - .end asm_builtin_checkcast + NOTE: itmp3 is not restored! + C prototype: + void asm_replacement_in(executionstate *es); -/******************* function asm_builtin_aastore ****************************** -* * -* Does the cast check and eventually throws an exception * -* a0 = arrayref, a1 = index, a2 = value * -* * *******************************************************************************/ - .ent asm_builtin_aastore - -asm_builtin_aastore: - beqz a0,nb_aastore_null /* if null pointer throw exception */ - lw t0,offarraysize(a0) /* load size */ - aaddiu sp,sp,-32 /* allocate stack space */ - sd ra,0(sp) /* save return address */ - asll t1,a1,ashift /* add index*8 to arrayref */ - aaddu t1,a0,t1 /* add index * ashift to arrayref */ - sltu t0,a1,t0 /* do bound check */ - beqz t0,nb_aastore_bound /* if out of bounds throw exception */ - move a1,a2 /* object is second argument */ - sd t1,8(sp) /* save store position */ - sd a1,16(sp) /* save object */ - jal builtin_canstore /* builtin_canstore(arrayref,object) */ - ld ra,0(sp) /* restore return address */ - ld a0,8(sp) /* restore store position */ - ld a1,16(sp) /* restore object */ - aaddiu sp,sp,32 /* free stack space */ - beqz v0,nb_aastore_store /* if (false) throw exception */ - ast a1,offobjarrdata(a0) /* store objectptr in array */ - j ra /* return */ - -nb_aastore_null: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - jal new_nullpointerexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 + .ent asm_replacement_in - move xpc,ra /* faulting address is return adress */ - b asm_handle_nat_exception - -nb_aastore_bound: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - move a0,a1 /* move index into a0 */ - jal new_arrayindexoutofboundsexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 - - aaddiu sp,sp,32 /* free stack space */ - move xpc,ra /* faulting address is return adress */ - b asm_handle_nat_exception +asm_replacement_in: + /* a0 == executionstate *es */ -nb_aastore_store: - daddiu sp,sp,-2*8 - sd ra,0*8(sp) - jal new_arraystoreexception - move xptr,v0 - ld ra,0*8(sp) - daddiu sp,sp,2*8 + /* set new sp and pv */ + ld sp,(offes_sp)(a0) + ld pv,(offes_pv)(a0) + + /* copy registers from execution state */ + /* $0 is zero */ + ld $1 ,( 1*8+offes_intregs)(a0) + ld $2 ,( 2*8+offes_intregs)(a0) + ld $3 ,( 2*8+offes_intregs)(a0) + /* a0 is loaded below */ + ld $5 ,( 5*8+offes_intregs)(a0) + ld $6 ,( 6*8+offes_intregs)(a0) + ld $7 ,( 7*8+offes_intregs)(a0) + ld $8 ,( 8*8+offes_intregs)(a0) + ld $9 ,( 9*8+offes_intregs)(a0) + ld $10,(10*8+offes_intregs)(a0) + ld $11,(11*8+offes_intregs)(a0) + ld $12,(12*8+offes_intregs)(a0) + ld $13,(13*8+offes_intregs)(a0) + ld $14,(14*8+offes_intregs)(a0) + ld $15,(15*8+offes_intregs)(a0) + ld $16,(16*8+offes_intregs)(a0) + ld $17,(17*8+offes_intregs)(a0) + ld $18,(18*8+offes_intregs)(a0) + ld $19,(19*8+offes_intregs)(a0) + ld $20,(20*8+offes_intregs)(a0) + ld $21,(21*8+offes_intregs)(a0) + ld $22,(22*8+offes_intregs)(a0) + ld $23,(23*8+offes_intregs)(a0) + ld $24,(24*8+offes_intregs)(a0) + ld $25,(25*8+offes_intregs)(a0) + ld $26,(26*8+offes_intregs)(a0) + ld $27,(27*8+offes_intregs)(a0) + ld $28,(28*8+offes_intregs)(a0) + /* $29 is sp */ + /* $30 is pv */ + ld $31,(31*8+offes_intregs)(a0) + + ldc1 $f0 ,( 0*8+offes_fltregs)(a0) + ldc1 $f1 ,( 1*8+offes_fltregs)(a0) + ldc1 $f2 ,( 2*8+offes_fltregs)(a0) + ldc1 $f3 ,( 3*8+offes_fltregs)(a0) + ldc1 $f4 ,( 4*8+offes_fltregs)(a0) + ldc1 $f5 ,( 5*8+offes_fltregs)(a0) + ldc1 $f6 ,( 6*8+offes_fltregs)(a0) + ldc1 $f7 ,( 7*8+offes_fltregs)(a0) + ldc1 $f8 ,( 8*8+offes_fltregs)(a0) + ldc1 $f9 ,( 9*8+offes_fltregs)(a0) + ldc1 $f10,(10*8+offes_fltregs)(a0) + ldc1 $f11,(11*8+offes_fltregs)(a0) + ldc1 $f12,(12*8+offes_fltregs)(a0) + ldc1 $f13,(13*8+offes_fltregs)(a0) + ldc1 $f14,(14*8+offes_fltregs)(a0) + ldc1 $f15,(15*8+offes_fltregs)(a0) + ldc1 $f16,(16*8+offes_fltregs)(a0) + ldc1 $f17,(17*8+offes_fltregs)(a0) + ldc1 $f18,(18*8+offes_fltregs)(a0) + ldc1 $f19,(19*8+offes_fltregs)(a0) + ldc1 $f20,(20*8+offes_fltregs)(a0) + ldc1 $f21,(21*8+offes_fltregs)(a0) + ldc1 $f22,(22*8+offes_fltregs)(a0) + ldc1 $f23,(23*8+offes_fltregs)(a0) + ldc1 $f24,(24*8+offes_fltregs)(a0) + ldc1 $f25,(25*8+offes_fltregs)(a0) + ldc1 $f26,(26*8+offes_fltregs)(a0) + ldc1 $f27,(27*8+offes_fltregs)(a0) + ldc1 $f28,(28*8+offes_fltregs)(a0) + ldc1 $f29,(29*8+offes_fltregs)(a0) + ldc1 $f30,(30*8+offes_fltregs)(a0) + ldc1 $f31,(31*8+offes_fltregs)(a0) + + /* load new pc */ + + ld itmp3,offes_pc(a0) + + /* load a0 */ + + ld a0,(4*8+offes_intregs)(a0) - move xpc,ra /* faulting address is return adress */ - b asm_handle_nat_exception + /* jump to new code */ - .end asm_builtin_aastore + jr itmp3 + .end asm_replacement_in /******************* function asm_initialize_thread_stack ********************** * * @@ -1316,12 +888,12 @@ asm_switchstackandcall: .ent asm_getclassvalues_atomic asm_getclassvalues_atomic: -_crit_restart2: -_crit_begin2: +_crit_restart: +_crit_begin: lw t0,offbaseval(a0) lw t1,offdiffval(a0) lw t2,offbaseval(a1) -_crit_end2: +_crit_end: sw t0,offcast_super_baseval(a2) sw t1,offcast_super_diffval(a2) sw t2,offcast_sub_baseval(a2) @@ -1333,12 +905,9 @@ _crit_end2: 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 + .dword _crit_begin + .dword _crit_end + .dword _crit_restart #endif .dword 0 @@ -1346,17 +915,28 @@ asm_criticalsections: .text .ent compare_and_swap + compare_and_swap: 1: - lld v0,0(a0) - bne v0,a1,2f + all v0,0(a0) + bne v0,a1,2f move t0,a2 - scd t0,0(a0) - beqz t0,1b + asc t0,0(a0) + beqz t0,1b 2: sync - j ra + j ra + .end compare_and_swap + + +/* Disable exec-stacks, required for Gentoo ***********************************/ + +#if defined(__GCC__) && defined(__ELF__) + .section .note.GNU-stack,"",@progbits +#endif + + /* * 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 @@ -1368,4 +948,5 @@ compare_and_swap: * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */