X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Fcodegen.c;h=5260e939d6b802dbd998156d9f8504b621fe319f;hb=3cf9c83d2043bb7eaa5ec20d8b87220f58afc12b;hp=a01ff66903a89d6b720abb7045052410a783fd21;hpb=1deac13e9bc6f4db546f48a5c9e0b2c4d6857740;p=cacao.git diff --git a/src/vm/jit/mips/codegen.c b/src/vm/jit/mips/codegen.c index a01ff6690..5260e939d 100644 --- a/src/vm/jit/mips/codegen.c +++ b/src/vm/jit/mips/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/mips/codegen.c - machine code generator for MIPS - 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 + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -22,8 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: codegen.c 7241 2007-01-27 15:52:01Z twisti $ - */ @@ -39,41 +35,43 @@ #include "vm/jit/mips/arch.h" #include "vm/jit/mips/codegen.h" -#include "native/native.h" +#include "mm/memory.h" -#if defined(ENABLE_THREADS) -# include "threads/native/lock.h" -#endif +#include "native/localref.hpp" +#include "native/native.hpp" -#include "vm/builtin.h" +#include "threads/lock.hpp" + +#include "vm/jit/builtin.hpp" #include "vm/class.h" -#include "vm/exceptions.h" +#include "vm/exceptions.hpp" #include "vm/options.h" -#include "vm/stringlocal.h" -#include "vm/vm.h" +#include "vm/vm.hpp" +#include "vm/jit/abi.h" #include "vm/jit/asmpart.h" -#include "vm/jit/codegen-common.h" +#include "vm/jit/codegen-common.hpp" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" -#include "vm/jit/jit.h" -#include "vm/jit/md.h" -#include "vm/jit/patcher.h" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/linenumbertable.hpp" +#include "vm/jit/patcher-common.hpp" #include "vm/jit/reg.h" -#include "vm/jit/replace.h" +#include "vm/jit/replace.hpp" +#include "vm/jit/trap.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" #endif -/* codegen ********************************************************************* +/* codegen_emit **************************************************************** Generates machine code. *******************************************************************************/ -bool codegen(jitdata *jd) +bool codegen_emit(jitdata *jd) { methodinfo *m; codeinfo *code; @@ -83,7 +81,6 @@ bool codegen(jitdata *jd) varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; u2 currentline; constant_classref *cr; unresolved_class *uc; @@ -118,7 +115,7 @@ bool codegen(jitdata *jd) s4 i, p, t, l; s4 savedregs_num; - savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */ + savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */ /* space to save used callee saved registers */ @@ -130,7 +127,7 @@ bool codegen(jitdata *jd) #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { # if SIZEOF_VOID_P == 8 cd->stackframesize++; # else @@ -150,34 +147,18 @@ bool codegen(jitdata *jd) (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ -#if defined(ENABLE_THREADS) - /* IsSync contains the offset relative to the stack pointer for the - argument of monitor_exit used in the exception handler. Since the - offset could be zero and give a wrong meaning of the flag it is - offset by one. - */ - - if (checksync && (m->flags & ACC_SYNCHRONIZED)) - (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */ + code->synchronizedoffset = rd->memuse * 8; + + /* REMOVEME: We still need it for exception handling in assembler. */ + + if (code_is_leafmethod(code)) + (void) dseg_add_unique_s4(cd, 1); else -#endif - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ - - (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */ + (void) dseg_add_unique_s4(cd, 0); + (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ - dseg_addlinenumbertablesize(cd); - (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */ - /* create exception table */ - - for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) { - dseg_add_target(cd, ex->start); - dseg_add_target(cd, ex->end); - dseg_add_target(cd, ex->handler); - (void) dseg_add_unique_address(cd, ex->catchtype.any); - } - /* create stack frame (if necessary) */ if (cd->stackframesize) @@ -186,7 +167,7 @@ bool codegen(jitdata *jd) /* save return address and used callee saved registers */ p = cd->stackframesize; - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { p--; M_AST(REG_RA, REG_SP, p * 8); } for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) { @@ -213,121 +194,77 @@ bool codegen(jitdata *jd) continue; var = VAR(varindex); + s1 = md->params[p].regoff; - s1 = md->params[p].regoff; if (IS_INT_LNG_TYPE(t)) { /* integer args */ if (!md->params[p].inmemory) { /* register arguments */ #if SIZEOF_VOID_P == 8 - s2 = rd->argintregs[s1]; - if (!(var->flags & INMEMORY)) { /* reg arg -> register */ - M_INTMOVE(s2, var->vv.regoff); - } else { /* reg arg -> spilled */ - M_LST(s2, REG_SP, var->vv.regoff * 8); - } + if (!(var->flags & INMEMORY)) + M_INTMOVE(s1, var->vv.regoff); + else + M_LST(s1, REG_SP, var->vv.regoff); #else - if (IS_2_WORD_TYPE(t)) { - s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); - if (!(var->flags & INMEMORY)) /* reg arg -> register */ - M_LNGMOVE(s2, var->vv.regoff); - else /* reg arg -> spilled */ - M_LST(s2, REG_SP, var->vv.regoff * 8); + if (!(var->flags & INMEMORY)) { + if (IS_2_WORD_TYPE(t)) + M_LNGMOVE(s1, var->vv.regoff); + else + M_INTMOVE(s1, var->vv.regoff); } else { - s2 = rd->argintregs[s1]; - if (!(var->flags & INMEMORY)) /* reg arg -> register */ - M_INTMOVE(s2, var->vv.regoff); - else /* reg arg -> spilled */ - M_IST(s2, REG_SP, var->vv.regoff * 8); + if (IS_2_WORD_TYPE(t)) + M_LST(s1, REG_SP, var->vv.regoff); + else + M_IST(s1, REG_SP, var->vv.regoff); } #endif - } else { /* stack arguments */ - if (!(var->flags & INMEMORY)) { /* stack arg -> register */ + } + else { /* stack arguments */ + if (!(var->flags & INMEMORY)) { #if SIZEOF_VOID_P == 8 - M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); + M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); #else if (IS_2_WORD_TYPE(t)) - M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); + M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); else - M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); + M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); #endif - } else { /* stack arg -> spilled */ - var->vv.regoff = cd->stackframesize + s1; - } + } + else + var->vv.regoff = cd->stackframesize * 8 + s1; } - - } else { /* floating args */ - if (!md->params[p].inmemory) { /* register arguments */ -#if SIZEOF_VOID_P == 8 - s2 = rd->argfltregs[s1]; - if (!(var->flags & INMEMORY)) { /* reg arg -> register */ + } + else { /* floating args */ + if (!md->params[p].inmemory) { + if (!(var->flags & INMEMORY)) { if (IS_2_WORD_TYPE(t)) - M_DMOV(s2, var->vv.regoff); + M_DBLMOVE(s1, var->vv.regoff); else - M_FMOV(s2, var->vv.regoff); - } else { /* reg arg -> spilled */ + M_FLTMOVE(s1, var->vv.regoff); + } + else { if (IS_2_WORD_TYPE(t)) - M_DST(s2, REG_SP, var->vv.regoff * 8); + M_DST(s1, REG_SP, var->vv.regoff); else - M_FST(s2, REG_SP, var->vv.regoff * 8); + M_FST(s1, REG_SP, var->vv.regoff); } -#else - if ((p == 0) || - ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) { - s2 = rd->argfltregs[s1]; - if (!(var->flags & INMEMORY)) { /* reg arg -> register */ - if (IS_2_WORD_TYPE(t)) - M_DBLMOVE(s2, var->vv.regoff); - else - M_FLTMOVE(s2, var->vv.regoff); - } - else { /* reg arg -> spilled */ - if (IS_2_WORD_TYPE(t)) - M_DST(s2, REG_SP, var->vv.regoff * 8); - else - M_FST(s2, REG_SP, var->vv.regoff * 8); - } - } - else { - if (IS_2_WORD_TYPE(t)) { - s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); - if (!(var->flags & INMEMORY)) { - M_MTC1(GET_LOW_REG(s2), var->vv.regoff); - M_MTC1(GET_HIGH_REG(s2), var->vv.regoff + 1); - M_NOP; - } - else - M_LST(s2, REG_SP, var->vv.regoff * 8); - } - else { - s2 = rd->argintregs[s1]; - if (!(var->flags & INMEMORY)) { - M_MTC1(s2, var->vv.regoff); - M_NOP; - } - else - M_IST(s2, REG_SP, var->vv.regoff * 8); - } - } -#endif - - } else { /* stack arguments */ - if (!(var->flags & INMEMORY)) { /* stack-arg -> register */ + } + else { + if (!(var->flags & INMEMORY)) { if (IS_2_WORD_TYPE(t)) - M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); + M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); else - M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); - } else /* stack-arg -> spilled */ - var->vv.regoff = cd->stackframesize + s1; + M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); + } + else + var->vv.regoff = cd->stackframesize * 8 + s1; } } - } /* end for */ + } /* call monitorenter function */ #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stack offset for monitor argument */ s1 = rd->memuse; @@ -337,10 +274,10 @@ bool codegen(jitdata *jd) M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8); for (p = 0; p < INT_ARG_CNT; p++) - M_AST(rd->argintregs[p], REG_SP, p * 8); + M_AST(abi_registers_integer_argument[p], REG_SP, p * 8); for (p = 0; p < FLT_ARG_CNT; p++) - M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8); + M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8); s1 += INT_ARG_CNT + FLT_ARG_CNT; } @@ -349,34 +286,29 @@ bool codegen(jitdata *jd) /* get correct lock object */ if (m->flags & ACC_STATIC) { - disp = dseg_add_address(cd, &m->class->object.header); + disp = dseg_add_address(cd, &m->clazz->object.header); M_ALD(REG_A0, REG_PV, disp); + disp = dseg_add_functionptr(cd, LOCK_monitor_enter); + M_ALD(REG_ITMP3, REG_PV, disp); } else { /* emit_nullpointer_check(cd, iptr, REG_A0); */ - M_BNEZ(REG_A0, 6); - M_NOP; - - M_LUI(REG_ITMP3, 0); - M_OR_IMM(REG_ITMP3, 0, REG_ITMP3); - codegen_add_nullpointerexception_ref(cd); - M_AADD(REG_PV, REG_ITMP3, REG_ITMP3); - M_JMP(REG_ITMP3); - M_NOP; + M_BNEZ(REG_A0, 2); + disp = dseg_add_functionptr(cd, LOCK_monitor_enter); + M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */ + M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException); } - disp = dseg_add_functionptr(cd, LOCK_monitor_enter); - M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); - M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */ + M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */ # if !defined(NDEBUG) if (opt_verbosecall) { for (p = 0; p < INT_ARG_CNT; p++) - M_ALD(rd->argintregs[p], REG_SP, p * 8); + M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8); for (p = 0; p < FLT_ARG_CNT; p++) - M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8); + M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8); M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8); @@ -457,7 +389,7 @@ bool codegen(jitdata *jd) for (iptr = bptr->iinstr; len > 0; len--, iptr++) { if (iptr->line != currentline) { - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add(cd, iptr->line); currentline = iptr->line; } @@ -478,14 +410,14 @@ bool codegen(jitdata *jd) case ICMD_INLINE_BODY: REPLACEMENT_POINT_INLINE_BODY(cd, iptr); - dseg_addlinenumber_inline_start(cd, iptr); - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add_inline_start(cd, iptr); + linenumbertable_list_entry_add(cd, iptr->line); break; case ICMD_INLINE_END: - dseg_addlinenumber_inline_end(cd, iptr); - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add_inline_end(cd, iptr); + linenumbertable_list_entry_add(cd, iptr->line); break; case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */ @@ -538,7 +470,8 @@ bool codegen(jitdata *jd) cr = iptr->sx.val.c.ref; disp = dseg_add_unique_address(cd, cr); - codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, + cr, disp); M_ALD(d, REG_PV, disp); } @@ -557,23 +490,23 @@ bool codegen(jitdata *jd) /* load/store/copy/move operations ************************************/ case ICMD_ILOAD: /* ... ==> ..., content of local variable */ - case ICMD_LLOAD: /* ... ==> ..., content of local variable */ - case ICMD_ALOAD: /* ... ==> ..., content of local variable */ - case ICMD_FLOAD: /* ... ==> ..., content of local variable */ - case ICMD_DLOAD: /* ... ==> ..., content of local variable */ + case ICMD_LLOAD: + case ICMD_ALOAD: + case ICMD_FLOAD: + case ICMD_DLOAD: case ICMD_ISTORE: /* ..., value ==> ... */ - case ICMD_LSTORE: /* ..., value ==> ... */ - case ICMD_FSTORE: /* ..., value ==> ... */ - case ICMD_DSTORE: /* ..., value ==> ... */ + case ICMD_LSTORE: + case ICMD_FSTORE: + case ICMD_DSTORE: case ICMD_COPY: case ICMD_MOVE: - emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst)); + emit_copy(jd, iptr); break; case ICMD_ASTORE: if (!(iptr->flags.bits & INS_FLAG_RETADDR)) - emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst)); + emit_copy(jd, iptr); break; @@ -983,22 +916,17 @@ bool codegen(jitdata *jd) case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */ case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */ - bte = iptr->sx.s23.s3.bte; - md = bte->md; + s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED); + s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED); - s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED); + /* XXX TODO: only do this if arithmetic check is really done! */ M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3); emit_arithmetic_check(cd, iptr, REG_ITMP3); - s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)], - rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]); - M_LNGMOVE(s2, s3); - - s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); - s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)], - rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]); - M_LNGMOVE(s1, s3); + M_LNGMOVE(s1, REG_A0_A1_PACKED); + M_LNGMOVE(s2, REG_A2_A3_PACKED); + bte = iptr->sx.s23.s3.bte; disp = dseg_add_functionptr(cd, bte->fp); M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); @@ -1758,8 +1686,8 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - emit_nullpointer_check(cd, iptr, s1); - M_ILD(d, s1, OFFSET(java_arrayheader, size)); + /* implicit null-pointer check */ + M_ILD(d, s1, OFFSET(java_array_t, size)); emit_store_dst(jd, iptr, d); break; @@ -1768,9 +1696,10 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP3); - M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0])); + /* implicit null-pointer check */ + M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1779,10 +1708,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP3); M_AADD(s2, REG_ITMP3, REG_ITMP3); - M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0])); + /* implicit null-pointer check */ + M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1791,10 +1721,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP3); M_AADD(s2, REG_ITMP3, REG_ITMP3); - M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0])); + /* implicit null-pointer check */ + M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1803,10 +1734,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 2, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); - M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0])); + /* implicit null-pointer check */ + M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1819,10 +1751,11 @@ bool codegen(jitdata *jd) #else d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); #endif - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 3, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); - M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0])); + /* implicit null-pointer check */ + M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1831,10 +1764,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 2, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); - M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0])); + /* implicit null-pointer check */ + M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1843,10 +1777,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 3, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); - M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0])); + /* implicit null-pointer check */ + M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1855,10 +1790,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); - M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0])); + /* implicit null-pointer check */ + M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1867,10 +1803,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); - M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0])); + /* implicit null-pointer check */ + M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0])); break; case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1878,29 +1815,31 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP1); M_AADD(s2, REG_ITMP1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); - M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0])); + /* implicit null-pointer check */ + M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0])); break; case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); - M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0])); + /* implicit null-pointer check */ + M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0])); break; case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 3, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); #if SIZEOF_VOID_P == 8 @@ -1908,29 +1847,32 @@ bool codegen(jitdata *jd) #else s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED); #endif - M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0])); + /* implicit null-pointer check */ + M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0])); break; case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_FTMP1); - M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0])); + /* implicit null-pointer check */ + M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0])); break; case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 3, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_FTMP1); - M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0])); + /* implicit null-pointer check */ + M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0])); break; @@ -1938,27 +1880,24 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); - M_MOV(s1, REG_A0); - M_MOV(s3, REG_A1); - disp = dseg_add_functionptr(cd, BUILTIN_canstore); + M_INTMOVE(s1, REG_A0); + M_INTMOVE(s3, REG_A1); + disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore); M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); M_NOP; - -/* M_BEQZ(REG_RESULT, 0); */ -/* codegen_add_arraystoreexception_ref(cd); */ -/* M_NOP; */ - emit_arraystore_check(cd, iptr, REG_RESULT); + emit_arraystore_check(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); - M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0])); + /* implicit null-pointer check */ + M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0])); break; @@ -1966,9 +1905,10 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP1); - M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0])); + /* implicit null-pointer check */ + M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0])); break; case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */ @@ -1976,33 +1916,36 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP1); M_AADD(s2, REG_ITMP1, REG_ITMP1); - M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0])); + /* implicit null-pointer check */ + M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0])); break; case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); - M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0])); + /* implicit null-pointer check */ + M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0])); break; case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, 3, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); + /* implicit null-pointer check */ #if SIZEOF_VOID_P == 8 - M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0])); + M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0])); #else - M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0])); + M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0])); #endif break; @@ -2010,10 +1953,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - emit_array_checks(cd, iptr, s1, s2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); - M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0])); + /* implicit null-pointer check */ + M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0])); break; @@ -2024,15 +1968,16 @@ bool codegen(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, uf); - codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp); + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); } else { fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = dseg_add_address(cd, &(fi->value)); + disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) - codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp); + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) + patcher_add_patch_ref(jd, PATCHER_initialize_class, + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2073,15 +2018,16 @@ bool codegen(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, uf); - codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp); + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); } else { fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = dseg_add_address(cd, &(fi->value)); + disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) - codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp); + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) + patcher_add_patch_ref(jd, PATCHER_initialize_class, + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2115,23 +2061,22 @@ bool codegen(jitdata *jd) break; case ICMD_PUTSTATICCONST: /* ... ==> ... */ - /* val = value (in current instruction) */ - /* following NOP) */ if (INSTRUCTION_IS_UNRESOLVED(iptr)) { uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, uf); - codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp); + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); } else { fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = dseg_add_address(cd, &(fi->value)); + disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) - codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp); + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) + patcher_add_patch_ref(jd, PATCHER_initialize_class, + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2166,7 +2111,7 @@ bool codegen(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = 0; - codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0); + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); } else { fi = iptr->sx.s23.s3.fmiref->p.field; @@ -2237,7 +2182,7 @@ bool codegen(jitdata *jd) #endif if (INSTRUCTION_IS_UNRESOLVED(iptr)) - codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0); + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); switch (fieldtype) { case TYPE_INT: @@ -2264,15 +2209,14 @@ bool codegen(jitdata *jd) emit_nullpointer_check(cd, iptr, s1); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - unresolved_field *uf = iptr->sx.s23.s3.uf; - + uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; disp = 0; - codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0); + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = fi->offset; } @@ -2308,7 +2252,7 @@ bool codegen(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { uc = iptr->sx.s23.s2.uc; - codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0); } #endif /* ENABLE_VERIFIER */ @@ -2324,151 +2268,128 @@ bool codegen(jitdata *jd) case ICMD_GOTO: /* ... ==> ... */ case ICMD_RET: /* ... ==> ... */ - M_BR(0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_br(cd, iptr->dst.block); ALIGNCODENOP; break; case ICMD_JSR: /* ... ==> ... */ - M_BR(0); - codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block); - M_NOP; + emit_br(cd, iptr->sx.s23.s3.jsrtarget.block); ALIGNCODENOP; break; case ICMD_IFNULL: /* ..., value ==> ... */ + case ICMD_IFNONNULL: s1 = emit_load_s1(jd, iptr, REG_ITMP1); - M_BEQZ(s1, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; - break; - - case ICMD_IFNONNULL: /* ..., value ==> ... */ - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - M_BNEZ(s1, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE); break; case ICMD_IFEQ: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.i == 0) { - M_BEQZ(s1, 0); - } else { + if (iptr->sx.val.i == 0) + emit_beqz(cd, iptr->dst.block, s1); + else { ICONST(REG_ITMP2, iptr->sx.val.i); - M_BEQ(s1, REG_ITMP2, 0); + emit_beq(cd, iptr->dst.block, s1, REG_ITMP2); } - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IFLT: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.i == 0) { - M_BLTZ(s1, 0); - } else { - if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) { + if (iptr->sx.val.i == 0) + emit_bltz(cd, iptr->dst.block, s1); + else { + if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1); - } else { + else { ICONST(REG_ITMP2, iptr->sx.val.i); M_CMPLT(s1, REG_ITMP2, REG_ITMP1); } - M_BNEZ(REG_ITMP1, 0); + emit_bnez(cd, iptr->dst.block, REG_ITMP1); } - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IFLE: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.i == 0) { - M_BLEZ(s1, 0); - } else { + if (iptr->sx.val.i == 0) + emit_blez(cd, iptr->dst.block, s1); + else { if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) { M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1); - M_BNEZ(REG_ITMP1, 0); - } else { + emit_bnez(cd, iptr->dst.block, REG_ITMP1); + } + else { ICONST(REG_ITMP2, iptr->sx.val.i); M_CMPGT(s1, REG_ITMP2, REG_ITMP1); - M_BEQZ(REG_ITMP1, 0); + emit_beqz(cd, iptr->dst.block, REG_ITMP1); } } - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IFNE: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.i == 0) { - M_BNEZ(s1, 0); - } else { + if (iptr->sx.val.i == 0) + emit_bnez(cd, iptr->dst.block, s1); + else { ICONST(REG_ITMP2, iptr->sx.val.i); - M_BNE(s1, REG_ITMP2, 0); + emit_bne(cd, iptr->dst.block, s1, REG_ITMP2); } - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IFGT: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.i == 0) { - M_BGTZ(s1, 0); - } else { + if (iptr->sx.val.i == 0) + emit_bgtz(cd, iptr->dst.block, s1); + else { if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) { M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1); - M_BEQZ(REG_ITMP1, 0); - } else { + emit_beqz(cd, iptr->dst.block, REG_ITMP1); + } + else { ICONST(REG_ITMP2, iptr->sx.val.i); M_CMPGT(s1, REG_ITMP2, REG_ITMP1); - M_BNEZ(REG_ITMP1, 0); + emit_bnez(cd, iptr->dst.block, REG_ITMP1); } } - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IFGE: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.i == 0) { - M_BGEZ(s1, 0); - } else { - if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) { + if (iptr->sx.val.i == 0) + emit_bgez(cd, iptr->dst.block, s1); + else { + if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1); - } else { + else { ICONST(REG_ITMP2, iptr->sx.val.i); M_CMPLT(s1, REG_ITMP2, REG_ITMP1); } - M_BEQZ(REG_ITMP1, 0); + emit_beqz(cd, iptr->dst.block, REG_ITMP1); } - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IF_LEQ: /* ..., value ==> ... */ #if SIZEOF_VOID_P == 8 s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.l == 0) { - M_BEQZ(s1, 0); - } else { + if (iptr->sx.val.l == 0) + emit_beqz(cd, iptr->dst.block, s1); + else { LCONST(REG_ITMP2, iptr->sx.val.l); - M_BEQ(s1, REG_ITMP2, 0); + emit_beq(cd, iptr->dst.block, s1, REG_ITMP2); } #else if (iptr->sx.val.l == 0) { s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); + emit_beqz(cd, iptr->dst.block, REG_ITMP3); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); @@ -2478,113 +2399,102 @@ bool codegen(jitdata *jd) ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); M_XOR(s1, REG_ITMP3, REG_ITMP3); M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); + emit_beqz(cd, iptr->dst.block, REG_ITMP3); } #endif - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IF_LLT: /* ..., value ==> ... */ #if SIZEOF_VOID_P == 8 s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.l == 0) { - M_BLTZ(s1, 0); - } else { - if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) { - M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1); - } else { + if (iptr->sx.val.l == 0) + emit_bltz(cd, iptr->dst.block, s1); + else { + if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) + M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3); + else { LCONST(REG_ITMP2, iptr->sx.val.l); - M_CMPLT(s1, REG_ITMP2, REG_ITMP1); + M_CMPLT(s1, REG_ITMP2, REG_ITMP3); } - M_BNEZ(REG_ITMP1, 0); + emit_bnez(cd, iptr->dst.block, REG_ITMP3); } #else if (iptr->sx.val.l == 0) { /* if high word is less than zero, the whole long is too */ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); - M_BLTZ(s1, 0); + emit_bltz(cd, iptr->dst.block, s1); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPLT(s1, REG_ITMP2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); + M_BNE(s1, REG_ITMP2, 5); /* XXX */ M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPULT(s2, REG_ITMP2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); + emit_bnez(cd, iptr->dst.block, REG_ITMP3); } #endif - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IF_LLE: /* ..., value ==> ... */ #if SIZEOF_VOID_P == 8 s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.l == 0) { - M_BLEZ(s1, 0); - } else { + if (iptr->sx.val.l == 0) + emit_blez(cd, iptr->dst.block, s1); + else { if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) { - M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1); - M_BNEZ(REG_ITMP1, 0); - } else { + M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2); + emit_bnez(cd, iptr->dst.block, REG_ITMP2); + } + else { LCONST(REG_ITMP2, iptr->sx.val.l); - M_CMPGT(s1, REG_ITMP2, REG_ITMP1); - M_BEQZ(REG_ITMP1, 0); + M_CMPGT(s1, REG_ITMP2, REG_ITMP3); + emit_beqz(cd, iptr->dst.block, REG_ITMP3); } } #else if (iptr->sx.val.l == 0) { s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); - M_BGTZ(GET_HIGH_REG(s1), 5); - M_NOP; - M_BLTZ(GET_HIGH_REG(s1), 0); - codegen_add_branch_ref(cd, iptr->dst.block); + M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */ M_NOP; - M_BEQZ(GET_LOW_REG(s1), 0); + emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1)); + emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1)); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPLT(s1, REG_ITMP2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); + M_BNE(s1, REG_ITMP2, 5); /* XXX */ M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPUGT(s2, REG_ITMP2, REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); + emit_beqz(cd, iptr->dst.block, REG_ITMP3); } #endif - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IF_LNE: /* ..., value ==> ... */ #if SIZEOF_VOID_P == 8 s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.l == 0) { - M_BNEZ(s1, 0); - } else { + if (iptr->sx.val.l == 0) + emit_bnez(cd, iptr->dst.block, s1); + else { LCONST(REG_ITMP2, iptr->sx.val.l); - M_BNE(s1, REG_ITMP2, 0); + emit_bne(cd, iptr->dst.block, s1, REG_ITMP2); } #else if (iptr->sx.val.l == 0) { s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); + emit_bnez(cd, iptr->dst.block, REG_ITMP3); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); @@ -2594,96 +2504,86 @@ bool codegen(jitdata *jd) ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); M_XOR(s1, REG_ITMP3, REG_ITMP3); M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); + emit_bnez(cd, iptr->dst.block, REG_ITMP3); } #endif - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IF_LGT: /* ..., value ==> ... */ #if SIZEOF_VOID_P == 8 s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.l == 0) { - M_BGTZ(s1, 0); - } else { + if (iptr->sx.val.l == 0) + emit_bgtz(cd, iptr->dst.block, s1); + else { if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) { - M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1); - M_BEQZ(REG_ITMP1, 0); - } else { + M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2); + emit_beqz(cd, iptr->dst.block, REG_ITMP2); + } + else { LCONST(REG_ITMP2, iptr->sx.val.l); - M_CMPGT(s1, REG_ITMP2, REG_ITMP1); - M_BNEZ(REG_ITMP1, 0); + M_CMPGT(s1, REG_ITMP2, REG_ITMP3); + emit_bnez(cd, iptr->dst.block, REG_ITMP3); } } #else if (iptr->sx.val.l == 0) { s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); - M_BGTZ(GET_HIGH_REG(s1), 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; - M_BLTZ(GET_HIGH_REG(s1), 3); + emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1)); + M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */ M_NOP; - M_BNEZ(GET_LOW_REG(s1), 0); + emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1)); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPGT(s1, REG_ITMP2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); + M_BNE(s1, REG_ITMP2, 5); /* XXX */ M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPUGT(s2, REG_ITMP2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); + emit_bnez(cd, iptr->dst.block, REG_ITMP3); } #endif - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IF_LGE: /* ..., value ==> ... */ #if SIZEOF_VOID_P == 8 s1 = emit_load_s1(jd, iptr, REG_ITMP1); - if (iptr->sx.val.l == 0) { - M_BGEZ(s1, 0); - } else { + if (iptr->sx.val.l == 0) + emit_bgez(cd, iptr->dst.block, s1); + else { if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) { - M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1); - } else { + M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3); + } + else { LCONST(REG_ITMP2, iptr->sx.val.l); - M_CMPLT(s1, REG_ITMP2, REG_ITMP1); + M_CMPLT(s1, REG_ITMP2, REG_ITMP3); } - M_BEQZ(REG_ITMP1, 0); + emit_beqz(cd, iptr->dst.block, REG_ITMP3); } #else if (iptr->sx.val.l == 0) { /* if high word is greater equal zero, the whole long is too */ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); - M_BGEZ(s1, 0); + emit_bgez(cd, iptr->dst.block, s1); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPGT(s1, REG_ITMP2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); + M_BNE(s1, REG_ITMP2, 5); /* XXX */ M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPULT(s2, REG_ITMP2, REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); + emit_beqz(cd, iptr->dst.block, REG_ITMP3); } #endif - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; break; case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */ @@ -2694,9 +2594,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - M_BEQ(s1, s2, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_beq(cd, iptr->dst.block, s1, s2); break; #if SIZEOF_VOID_P == 4 @@ -2705,13 +2603,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); - M_BNE(s1, s2, 3); + M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */ M_NOP; s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BEQ(s1, s2, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_beq(cd, iptr->dst.block, s1, s2); break; #endif @@ -2723,24 +2619,19 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - M_BNE(s1, s2, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bne(cd, iptr->dst.block, s1, s2); break; #if SIZEOF_VOID_P == 4 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */ + /* TODO: could be optimized (XOR or SUB) */ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); - M_BNE(s1, s2, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bne(cd, iptr->dst.block, s1, s2); s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNE(s1, s2, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bne(cd, iptr->dst.block, s1, s2); break; #endif @@ -2752,9 +2643,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMPLT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); break; #if SIZEOF_VOID_P == 4 @@ -2763,19 +2652,15 @@ bool codegen(jitdata *jd) s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); M_CMPLT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPGT(s1, s2, REG_ITMP3); /* load low-bits before the branch, so we know the distance */ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); + M_BNEZ(REG_ITMP3, 4); /* XXX */ M_NOP; M_CMPULT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); break; #endif @@ -2787,9 +2672,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMPGT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); break; #if SIZEOF_VOID_P == 4 @@ -2798,19 +2681,15 @@ bool codegen(jitdata *jd) s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); M_CMPGT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPLT(s1, s2, REG_ITMP3); /* load low-bits before the branch, so we know the distance */ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); + M_BNEZ(REG_ITMP3, 4); /* XXX */ M_NOP; M_CMPUGT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); break; #endif @@ -2822,9 +2701,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMPGT(s1, s2, REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_beqz(cd, iptr->dst.block, REG_ITMP3); break; #if SIZEOF_VOID_P == 4 @@ -2833,19 +2710,15 @@ bool codegen(jitdata *jd) s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); M_CMPLT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPGT(s1, s2, REG_ITMP3); /* load low-bits before the branch, so we know the distance */ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); + M_BNEZ(REG_ITMP3, 4); /* XXX */ M_NOP; M_CMPUGT(s1, s2, REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_beqz(cd, iptr->dst.block, REG_ITMP3); break; #endif @@ -2857,9 +2730,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMPLT(s1, s2, REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_beqz(cd, iptr->dst.block, REG_ITMP3); break; #if SIZEOF_VOID_P == 4 @@ -2868,19 +2739,15 @@ bool codegen(jitdata *jd) s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); M_CMPGT(s1, s2, REG_ITMP3); - M_BNEZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPLT(s1, s2, REG_ITMP3); /* load low-bits before the branch, so we know the distance */ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); + M_BNEZ(REG_ITMP3, 4); /* XXX */ M_NOP; M_CMPULT(s1, s2, REG_ITMP3); - M_BEQZ(REG_ITMP3, 0); - codegen_add_branch_ref(cd, iptr->dst.block); - M_NOP; + emit_beqz(cd, iptr->dst.block, REG_ITMP3); break; #endif @@ -2904,7 +2771,7 @@ bool codegen(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { uc = iptr->sx.s23.s2.uc; - codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0); } #endif /* ENABLE_VERIFIER */ goto nowperformreturn; @@ -2946,7 +2813,7 @@ nowperformreturn: #endif #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { disp = dseg_add_functionptr(cd, LOCK_monitor_exit); M_ALD(REG_ITMP3, REG_PV, disp); @@ -3007,7 +2874,7 @@ nowperformreturn: /* restore return address */ - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { p--; M_ALD(REG_RA, REG_SP, p * 8); } @@ -3076,9 +2943,7 @@ nowperformreturn: /* range check */ M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2); - M_BEQZ(REG_ITMP2, 0); - codegen_add_branch_ref(cd, table[0].block); /* default target */ - M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot */ + emit_beqz(cd, table[0].block, REG_ITMP2); /* build jump table top down and use address of lowest entry */ @@ -3092,6 +2957,7 @@ nowperformreturn: /* length of dataseg after last dseg_add_target is used by load */ + M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); M_AADD(REG_ITMP1, REG_PV, REG_ITMP2); M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen)); M_JMP(REG_ITMP2); @@ -3114,15 +2980,11 @@ nowperformreturn: while (--i >= 0) { ICONST(REG_ITMP2, lookup->value); - M_BEQ(s1, REG_ITMP2, 0); - codegen_add_branch_ref(cd, lookup->target.block); - M_NOP; + emit_beq(cd, lookup->target.block, s1, REG_ITMP2); ++lookup; } - M_BR(0); - codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block); - M_NOP; + emit_br(cd, iptr->sx.s23.s3.lookupdefault.block); ALIGNCODENOP; break; } @@ -3162,6 +3024,7 @@ gen_method: for (s3 = s3 - 1; s3 >= 0; s3--) { var = VAR(iptr->sx.s23.s2.args[s3]); + d = md->params[s3].regoff; if (var->flags & PREALLOC) continue; @@ -3169,133 +3032,111 @@ gen_method: if (IS_INT_LNG_TYPE(var->type)) { #if SIZEOF_VOID_P == 8 if (!md->params[s3].inmemory) { - s1 = rd->argintregs[md->params[s3].regoff]; - d = emit_load(jd, iptr, var, s1); - M_INTMOVE(d, s1); + s1 = emit_load(jd, iptr, var, d); + M_INTMOVE(s1, d); } else { - d = emit_load(jd, iptr, var, REG_ITMP1); - M_LST(d, REG_SP, md->params[s3].regoff * 8); + s1 = emit_load(jd, iptr, var, REG_ITMP1); + M_LST(s1, REG_SP, d); } #else if (!md->params[s3].inmemory) { - if (IS_2_WORD_TYPE(var->type)) { - s1 = md->params[s3].regoff; - s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); - d = emit_load(jd, iptr, var, s1); - M_LNGMOVE(d, s1); - } - else { - s1 = rd->argintregs[md->params[s3].regoff]; - d = emit_load(jd, iptr, var, s1); - M_INTMOVE(d, s1); - } + s1 = emit_load(jd, iptr, var, d); + + if (IS_2_WORD_TYPE(var->type)) + M_LNGMOVE(s1, d); + else + M_INTMOVE(s1, d); } else { if (IS_2_WORD_TYPE(var->type)) { - d = emit_load(jd, iptr, var, REG_ITMP12_PACKED); - M_LST(d, REG_SP, md->params[s3].regoff * 8); + s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED); + M_LST(s1, REG_SP, d); } else { - d = emit_load(jd, iptr, var, REG_ITMP1); - M_IST(d, REG_SP, md->params[s3].regoff * 8); + s1 = emit_load(jd, iptr, var, REG_ITMP1); + M_IST(s1, REG_SP, d); } } #endif } else { if (!md->params[s3].inmemory) { -#if SIZEOF_VOID_P == 8 - s1 = rd->argfltregs[md->params[s3].regoff]; - d = emit_load(jd, iptr, var, s1); + s1 = emit_load(jd, iptr, var, d); if (IS_2_WORD_TYPE(var->type)) - M_DMOV(d, s1); + M_DBLMOVE(s1, d); else - M_FMOV(d, s1); -#else - if ((s3 == 0) || - ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) { - s1 = rd->argfltregs[md->params[s3].regoff]; - d = emit_load(jd, iptr, var, s1); - if (IS_2_WORD_TYPE(var->type)) - M_DBLMOVE(d, s1); - else - M_FLTMOVE(d, s1); - } - else { - if (IS_2_WORD_TYPE(var->type)) { - s1 = md->params[s3].regoff; - s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); - d = emit_load(jd, iptr, var, REG_FTMP1); - M_MFC1(GET_LOW_REG(s2), d); - M_MFC1(GET_HIGH_REG(s2), d + 1); - M_NOP; - } - else { - s1 = rd->argintregs[md->params[s3].regoff]; - d = emit_load(jd, iptr, var, s1); - M_MFC1(s1, d); - M_NOP; - } - } -#endif + M_FLTMOVE(s1, d); } else { - d = emit_load(jd, iptr, var, REG_FTMP1); + s1 = emit_load(jd, iptr, var, REG_FTMP1); if (IS_2_WORD_TYPE(var->type)) - M_DST(d, REG_SP, md->params[s3].regoff * 8); + M_DST(s1, REG_SP, d); else - M_FST(d, REG_SP, md->params[s3].regoff * 8); + M_FST(s1, REG_SP, d); } } } switch (iptr->opc) { case ICMD_BUILTIN: - disp = dseg_add_functionptr(cd, bte->fp); + if (bte->stub == NULL) { + disp = dseg_add_functionptr(cd, bte->fp); + M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */ - M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */ + /* generate the actual call */ - /* TWISTI: i actually don't know the reason for using - REG_ITMP3 here instead of REG_PV. */ - s1 = REG_ITMP3; - break; + /* TWISTI: i actually don't know the reason for using + REG_ITMP3 here instead of REG_PV. */ - case ICMD_INVOKESPECIAL: -/* emit_nullpointer_check(cd, REG_A0); */ - M_BNEZ(REG_A0, 6); - M_NOP; + M_JSR(REG_RA, REG_ITMP3); + M_NOP; + } + else { + disp = dseg_add_functionptr(cd, bte->stub); + M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */ - M_LUI(REG_ITMP3, 0); - M_OR_IMM(REG_ITMP3, 0, REG_ITMP3); - codegen_add_nullpointerexception_ref(cd); - M_AADD(REG_PV, REG_ITMP3, REG_ITMP3); - M_JMP(REG_ITMP3); - M_NOP; + /* generate the actual call */ + + M_JSR(REG_RA, REG_PV); + M_NOP; + } + + REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); + disp = (s4) (cd->mcodeptr - cd->mcodebase); + M_LDA(REG_PV, REG_RA, -disp); + break; + case ICMD_INVOKESPECIAL: + emit_nullpointer_check(cd, iptr, REG_A0); /* fall through */ case ICMD_INVOKESTATIC: if (lm == NULL) { disp = dseg_add_unique_address(cd, um); - codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um, + patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, disp); } else disp = dseg_add_address(cd, lm->stubroutine); M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */ - s1 = REG_PV; + + /* generate the actual call */ + + M_JSR(REG_RA, REG_PV); + M_NOP; + REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); + disp = (s4) (cd->mcodeptr - cd->mcodebase); + M_LDA(REG_PV, REG_RA, -disp); break; case ICMD_INVOKEVIRTUAL: emit_nullpointer_check(cd, iptr, REG_A0); if (lm == NULL) { - codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0); + patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0); s1 = 0; } @@ -3303,45 +3144,49 @@ gen_method: s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex; - M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl)); + /* implicit null-pointer check */ + M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl)); M_ALD(REG_PV, REG_METHODPTR, s1); - s1 = REG_PV; + + /* generate the actual call */ + + M_JSR(REG_RA, REG_PV); + M_NOP; + REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); + disp = (s4) (cd->mcodeptr - cd->mcodebase); + M_LDA(REG_PV, REG_RA, -disp); break; case ICMD_INVOKEINTERFACE: emit_nullpointer_check(cd, iptr, REG_A0); if (lm == NULL) { - codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0); + patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0); s1 = 0; s2 = 0; } else { s1 = OFFSET(vftbl_t, interfacetable[0]) - - sizeof(methodptr*) * lm->class->index; + sizeof(methodptr*) * lm->clazz->index; - s2 = sizeof(methodptr) * (lm - lm->class->methods); + s2 = sizeof(methodptr) * (lm - lm->clazz->methods); } - M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl)); + /* implicit null-pointer check */ + M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl)); M_ALD(REG_METHODPTR, REG_METHODPTR, s1); M_ALD(REG_PV, REG_METHODPTR, s2); - s1 = REG_PV; - break; - } - /* generate the actual call */ + /* generate the actual call */ - M_JSR(REG_RA, s1); - M_NOP; - REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); - disp = (s4) (cd->mcodeptr - cd->mcodebase); - M_LDA(REG_PV, REG_RA, -disp); - - /* actually only used for ICMD_BUILTIN */ - - emit_exception_check(cd, iptr); + M_JSR(REG_RA, REG_PV); + M_NOP; + REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); + disp = (s4) (cd->mcodeptr - cd->mcodebase); + M_LDA(REG_PV, REG_RA, -disp); + break; + } /* store return value */ @@ -3376,20 +3221,6 @@ gen_method: case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */ - /* val.a: (classinfo*) superclass */ - - /* superclass is an interface: - * - * OK if ((sub == NULL) || - * (sub->vftbl->interfacetablelength > super->index) && - * (sub->vftbl->interfacetable[-super->index] != NULL)); - * - * superclass is a class: - * - * OK if ((sub == NULL) || (0 - * <= (sub->vftbl->baseval - super->vftbl->baseval) <= - * super->vftbl->diffvall)); - */ if (!(iptr->flags.bits & INS_FLAG_ARRAY)) { classinfo *super; @@ -3400,47 +3231,26 @@ gen_method: superindex = 0; } else { - super = iptr->sx.s23.s3.c.cls; + super = iptr->sx.s23.s3.c.cls; superindex = super->index; } -#if defined(ENABLE_THREADS) - codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase); -#endif - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - /* calculate interface checkcast code size */ - -/* s2 = 3 + 2 + 1 + 2; */ - s2 = 3 + 7 + 1 + 7; - if (super == NULL) - s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0); - - /* calculate class checkcast code size */ - -/* s3 = 2 + 1 + 4 + 1 + 2 /\* 10 + (s1 == REG_ITMP1) *\/; */ - s3 = 2 + 1 + 4 + 1 + 7; - if (super == NULL) - s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0); - /* if class is not resolved, check which code to call */ if (super == NULL) { - M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_1, s1); cr = iptr->sx.s23.s3.c.ref; disp = dseg_add_unique_s4(cd, 0); /* super->flags */ - codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, cr, disp); - /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */ M_ILD(REG_ITMP2, REG_PV, disp); M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2); - M_BEQZ(REG_ITMP2, 1 + s2 + 2); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2); } /* interface checkcast code */ @@ -3449,15 +3259,14 @@ gen_method: if (super == NULL) { cr = iptr->sx.s23.s3.c.ref; - codegen_add_patch_ref(cd, PATCHER_checkcast_interface, + patcher_add_patch_ref(jd, PATCHER_checkcast_interface, cr, 0); } else { - M_BEQZ(s1, 1 + s2); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_3, s1); } - M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength)); M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3); @@ -3468,35 +3277,34 @@ gen_method: superindex * sizeof(methodptr*)); emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1); - if (super == NULL) { - M_BR(1 + s3); - M_NOP; - } + if (super == NULL) + emit_label_br(cd, BRANCH_LABEL_4); + else + emit_label(cd, BRANCH_LABEL_3); } /* class checkcast code */ if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { if (super == NULL) { + emit_label(cd, BRANCH_LABEL_2); + cr = iptr->sx.s23.s3.c.ref; disp = dseg_add_unique_address(cd, NULL); - codegen_add_patch_ref(cd, - PATCHER_checkcast_instanceof_class, + patcher_add_patch_ref(jd, + PATCHER_resolve_classref_to_vftbl, cr, disp); } else { disp = dseg_add_address(cd, super->vftbl); - M_BEQZ(s1, 1 + s3); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_5, s1); } - M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP3, REG_PV, disp); -#if defined(ENABLE_THREADS) - codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase); -#endif + M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); /* if (s1 != REG_ITMP1) { */ /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */ @@ -3510,12 +3318,18 @@ gen_method: M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); M_ALD(REG_ITMP3, REG_PV, disp); M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); -#if defined(ENABLE_THREADS) - codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); -#endif + /* } */ M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3); emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1); + + if (super != NULL) + emit_label(cd, BRANCH_LABEL_5); + } + + if (super == NULL) { + emit_label(cd, BRANCH_LABEL_1); + emit_label(cd, BRANCH_LABEL_4); } d = codegen_reg_of_dst(jd, iptr, s1); @@ -3528,11 +3342,13 @@ gen_method: cr = iptr->sx.s23.s3.c.ref; disp = dseg_add_unique_address(cd, NULL); - codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast, + patcher_add_patch_ref(jd, + PATCHER_resolve_classref_to_classinfo, cr, disp); } - else + else { disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); + } M_ALD(REG_A1, REG_PV, disp); disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast); @@ -3551,20 +3367,6 @@ gen_method: break; case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */ - /* val.a: (classinfo*) superclass */ - - /* superclass is an interface: - * - * return (sub != NULL) && - * (sub->vftbl->interfacetablelength > super->index) && - * (sub->vftbl->interfacetable[-super->index] != NULL); - * - * superclass is a class: - * - * return ((sub != NULL) && (0 - * <= (sub->vftbl->baseval - super->vftbl->baseval) <= - * super->vftbl->diffvall)); - */ { classinfo *super; @@ -3581,48 +3383,30 @@ gen_method: superindex = super->index; } -#if defined(ENABLE_THREADS) - codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase); -#endif - s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + if (s1 == d) { M_MOV(s1, REG_ITMP1); s1 = REG_ITMP1; } - /* calculate interface instanceof code size */ - - s2 = 7; - if (super == NULL) - s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0); - - /* calculate class instanceof code size */ - - s3 = 8; - if (super == NULL) - s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0); - M_CLR(d); /* if class is not resolved, check which code to call */ if (super == NULL) { - M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_1, s1); cr = iptr->sx.s23.s3.c.ref; disp = dseg_add_unique_s4(cd, 0); /* super->flags */ - codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, cr, disp); - /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */ M_ILD(REG_ITMP3, REG_PV, disp); M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3); - M_BEQZ(REG_ITMP3, 1 + s2 + 2); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3); } /* interface instanceof code */ @@ -3631,15 +3415,14 @@ gen_method: if (super == NULL) { cr = iptr->sx.s23.s3.c.ref; - codegen_add_patch_ref(cd, PATCHER_instanceof_interface, + patcher_add_patch_ref(jd, PATCHER_instanceof_interface, cr, 0); } else { - M_BEQZ(s1, 1 + s2); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_3, s1); } - M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength)); M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3); @@ -3650,44 +3433,50 @@ gen_method: superindex * sizeof(methodptr*)); M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */ - if (super == NULL) { - M_BR(1 + s3); - M_NOP; - } + if (super == NULL) + emit_label_br(cd, BRANCH_LABEL_4); + else + emit_label(cd, BRANCH_LABEL_3); } /* class instanceof code */ if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { if (super == NULL) { + emit_label(cd, BRANCH_LABEL_2); + cr = iptr->sx.s23.s3.c.ref; disp = dseg_add_unique_address(cd, NULL); - codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, cr, disp); } else { disp = dseg_add_address(cd, super->vftbl); - M_BEQZ(s1, 1 + s3); - M_NOP; + emit_label_beqz(cd, BRANCH_LABEL_5, s1); } - M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP2, REG_PV, disp); -#if defined(ENABLE_THREADS) - codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase); -#endif + M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); -#if defined(ENABLE_THREADS) - codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); -#endif + M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); M_CMPULT(REG_ITMP2, REG_ITMP1, d); M_XOR_IMM(d, 1, d); + + if (super != NULL) + emit_label(cd, BRANCH_LABEL_5); } + + if (super == NULL) { + emit_label(cd, BRANCH_LABEL_1); + emit_label(cd, BRANCH_LABEL_4); + } + emit_store_dst(jd, iptr, d); } break; @@ -3724,11 +3513,12 @@ gen_method: cr = iptr->sx.s23.s3.c.ref; disp = dseg_add_unique_address(cd, NULL); - codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, disp); } - else + else { disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); + } /* a1 = arraydescriptor */ @@ -3779,15 +3569,9 @@ gen_method: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ - dseg_createlinenumbertable(cd); + /* generate traps */ - /* generate exception and patcher stubs */ - - emit_exception_stubs(jd); - emit_patcher_stubs(jd); - REPLACEMENT_EMIT_STUBS(jd); - - codegen_finish(jd); + emit_patcher_traps(jd); /* everything's ok */ @@ -3795,105 +3579,38 @@ gen_method: } -/* createcompilerstub ********************************************************** - - Creates a stub routine which calls the compiler. - -*******************************************************************************/ - -#define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P -#define COMPILERSTUB_CODESIZE 4 * 4 +/* codegen_emit_stub_native **************************************************** -#define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE + Emits a stub routine which calls a native method. +*******************************************************************************/ -u1 *createcompilerstub(methodinfo *m) +void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams) { - u1 *s; /* memory to hold the stub */ - ptrint *d; + methodinfo *m; codeinfo *code; codegendata *cd; - s4 dumpsize; - - s = CNEW(u1, COMPILERSTUB_SIZE); - - /* set data pointer and code pointer */ - - d = (ptrint *) s; - s = s + COMPILERSTUB_DATASIZE; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - cd = DNEW(codegendata); - cd->mcodeptr = s; - - /* Store the codeinfo pointer in the same place as in the - methodheader for compiled methods. */ - - code = code_codeinfo_new(m); - - d[0] = (ptrint) asm_call_jit_compiler; - d[1] = (ptrint) m; - d[2] = (ptrint) code; - - M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */ - M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */ - M_JMP(REG_PV); - M_NOP; - - md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d)); - -#if defined(ENABLE_STATISTICS) - if (opt_stat) - count_cstub_len += COMPILERSTUB_SIZE; -#endif - - /* release dump area */ - - dump_release(dumpsize); - - return s; -} - - -/* createnativestub ************************************************************ - - Creates a stub routine which calls a native method. - -*******************************************************************************/ - -u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) -{ - methodinfo *m; - codeinfo *code; - codegendata *cd; - registerdata *rd; - methoddesc *md; - s4 nativeparams; - s4 i, j; /* count variables */ - s4 t; - s4 s1, s2, disp; - s4 funcdisp; /* displacement of the function */ + methoddesc *md; + s4 i, j; + s4 t; + int s1, s2; + int disp; /* get required compiler data */ m = jd->m; code = jd->code; cd = jd->cd; - rd = jd->rd; /* initialize variables */ md = m->parseddesc; - nativeparams = (m->flags & ACC_STATIC) ? 2 : 1; /* calculate stack frame size */ cd->stackframesize = 1 + /* return address */ - sizeof(stackframeinfo) / SIZEOF_VOID_P + + sizeof(stackframeinfo_t) / SIZEOF_VOID_P + sizeof(localref_table) / SIZEOF_VOID_P + md->paramcount + /* for saving arguments over calls */ #if SIZEOF_VOID_P == 4 @@ -3911,12 +3628,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */ (void) dseg_add_unique_s4(cd, 0); /* IntSave */ (void) dseg_add_unique_s4(cd, 0); /* FltSave */ - (void) dseg_addlinenumbertablesize(cd); - (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */ /* generate stub code */ @@ -3928,21 +3642,13 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) emit_verbosecall_enter(jd); #endif - /* get function address (this must happen before the stackframeinfo) */ - - funcdisp = dseg_add_functionptr(cd, f); - -#if !defined(WITH_STATIC_CLASSPATH) - if (f == NULL) - codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp); -#endif - /* save integer and float argument registers */ #if SIZEOF_VOID_P == 8 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) { if (IS_INT_LNG_TYPE(md->params[i].type)) { - M_AST(rd->argintregs[i], REG_SP, j * 8); + s1 = md->params[i].regoff; + M_AST(s1, REG_SP, j * 8); j++; } } @@ -3951,14 +3657,12 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (IS_INT_LNG_TYPE(md->params[i].type)) { if (!md->params[i].inmemory) { s1 = md->params[i].regoff; - if (IS_2_WORD_TYPE(md->params[i].type)) { - s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); + + if (IS_2_WORD_TYPE(md->params[i].type)) M_LST(s1, REG_SP, j * 8); - } - else { - M_IST(rd->argintregs[s1], REG_SP, j * 8); - } + else + M_IST(s1, REG_SP, j * 8); + j++; } } @@ -3967,31 +3671,38 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) { if (IS_FLT_DBL_TYPE(md->params[i].type)) { + s1 = md->params[i].regoff; + if (IS_2_WORD_TYPE(md->params[i].type)) - M_DST(rd->argfltregs[i], REG_SP, j * 8); + M_DST(s1, REG_SP, j * 8); else - M_FST(rd->argfltregs[i], REG_SP, j * 8); + M_FST(s1, REG_SP, j * 8); + j++; } } /* prepare data structures for native function call */ - M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0); + M_MOV(REG_SP, REG_A0); M_MOV(REG_PV, REG_A1); - M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2); - M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8); disp = dseg_add_functionptr(cd, codegen_start_native_call); M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); M_NOP; /* XXX fill me! */ + /* remember class argument */ + + if (m->flags & ACC_STATIC) + M_MOV(REG_RESULT, REG_ITMP3); + /* restore integer and float argument registers */ #if SIZEOF_VOID_P == 8 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) { if (IS_INT_LNG_TYPE(md->params[i].type)) { - M_LLD(rd->argintregs[i], REG_SP, j * 8); + s1 = md->params[i].regoff; + M_LLD(s1, REG_SP, j * 8); j++; } } @@ -4000,14 +3711,12 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (IS_INT_LNG_TYPE(md->params[i].type)) { if (!md->params[i].inmemory) { s1 = md->params[i].regoff; - if (IS_2_WORD_TYPE(md->params[i].type)) { - s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); + + if (IS_2_WORD_TYPE(md->params[i].type)) M_LLD(s1, REG_SP, j * 8); - } - else { - M_ILD(rd->argintregs[s1], REG_SP, j * 8); - } + else + M_ILD(s1, REG_SP, j * 8); + j++; } } @@ -4016,77 +3725,63 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) { if (IS_FLT_DBL_TYPE(md->params[i].type)) { + s1 = md->params[i].regoff; + if (IS_2_WORD_TYPE(md->params[i].type)) - M_DLD(rd->argfltregs[i], REG_SP, j * 8); + M_DLD(s1, REG_SP, j * 8); else - M_FLD(rd->argfltregs[i], REG_SP, j * 8); + M_FLD(s1, REG_SP, j * 8); + j++; } } /* copy or spill arguments to new locations */ - for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) { + for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) { t = md->params[i].type; if (IS_INT_LNG_TYPE(t)) { if (!md->params[i].inmemory) { s1 = md->params[i].regoff; -#if SIZEOF_VOID_P == 8 - s1 = rd->argintregs[s1]; -#else - if (IS_2_WORD_TYPE(t)) - s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); - else - s1 = rd->argintregs[s1]; -#endif + s2 = nmd->params[j].regoff; if (!nmd->params[j].inmemory) { - s2 = nmd->params[j].regoff; #if SIZEOF_VOID_P == 8 - s2 = rd->argintregs[s2]; M_INTMOVE(s1, s2); #else - if (IS_2_WORD_TYPE(t)) { - s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)], - rd->argintregs[GET_HIGH_REG(s2)]); + if (IS_2_WORD_TYPE(t)) M_LNGMOVE(s1, s2); - } - else { - s2 = rd->argintregs[s2]; + else M_INTMOVE(s1, s2); - } #endif } else { - s2 = nmd->params[j].regoff; - #if SIZEOF_VOID_P == 8 - M_LST(s1, REG_SP, s2 * 8); + M_LST(s1, REG_SP, s2); #else if (IS_2_WORD_TYPE(t)) - M_LST(s1, REG_SP, s2 * 4); + M_LST(s1, REG_SP, s2); else - M_IST(s1, REG_SP, s2 * 4); + M_IST(s1, REG_SP, s2); #endif } } else { - s1 = md->params[i].regoff + cd->stackframesize; + s1 = md->params[i].regoff + cd->stackframesize * 8; s2 = nmd->params[j].regoff; #if SIZEOF_VOID_P == 8 - M_LLD(REG_ITMP1, REG_SP, s1 * 8); - M_LST(REG_ITMP1, REG_SP, s2 * 8); + M_LLD(REG_ITMP1, REG_SP, s1); + M_LST(REG_ITMP1, REG_SP, s2); #else if (IS_2_WORD_TYPE(t)) { - M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8); - M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4); + M_LLD(REG_ITMP12_PACKED, REG_SP, s1); + M_LST(REG_ITMP12_PACKED, REG_SP, s2); } else { - M_ILD(REG_ITMP1, REG_SP, s1 * 8); - M_IST(REG_ITMP1, REG_SP, s2 * 4); + M_ILD(REG_ITMP1, REG_SP, s1); + M_IST(REG_ITMP1, REG_SP, s2); } #endif } @@ -4098,8 +3793,6 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (!nmd->params[j].inmemory) { #if SIZEOF_VOID_P == 8 - s1 = rd->argfltregs[s1]; - s2 = rd->argfltregs[s2]; if (IS_2_WORD_TYPE(t)) M_DMOV(s1, s2); else @@ -4108,13 +3801,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) /* On MIPS32 float arguments for native functions can never be in float argument registers, since the first argument is _always_ an integer - argument (JNIenv) */ + argument (JNIEnv) */ if (IS_2_WORD_TYPE(t)) { - s1 = rd->argfltregs[s1]; - s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)], - rd->argintregs[GET_HIGH_REG(s2)]); - /* double high/low order is endian independent: even numbered holds low 32-bits, odd numbered high 32-bits */ @@ -4122,86 +3811,104 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */ M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */ } - else { - s1 = rd->argfltregs[s1]; - s2 = rd->argintregs[s2]; + else M_MFC1(s2, s1); - } #endif } else { #if SIZEOF_VOID_P == 8 - s1 = rd->argfltregs[s1]; - if (IS_2_WORD_TYPE(t)) - M_DST(s1, REG_SP, s2 * 8); + M_DST(s1, REG_SP, s2); else - M_FST(s1, REG_SP, s2 * 8); + M_FST(s1, REG_SP, s2); #else /* s1 may have been originally in 2 int registers, but was moved out by the native function argument(s), just get low register */ - s1 = rd->argfltregs[GET_LOW_REG(s1)]; - if (IS_2_WORD_TYPE(t)) - M_DST(s1, REG_SP, s2 * 4); + M_DST(GET_LOW_REG(s1), REG_SP, s2); else - M_FST(s1, REG_SP, s2 * 4); + M_FST(GET_LOW_REG(s1), REG_SP, s2); #endif } } else { - s1 = md->params[i].regoff + cd->stackframesize; + s1 = md->params[i].regoff + cd->stackframesize * 8; s2 = nmd->params[j].regoff; +#if SIZEOF_VOID_P == 8 + if (IS_2_WORD_TYPE(t)) { + M_DLD(REG_FTMP1, REG_SP, s1); + M_DST(REG_FTMP1, REG_SP, s2); + } + else { + M_FLD(REG_FTMP1, REG_SP, s1); + M_FST(REG_FTMP1, REG_SP, s2); + } +#else if (IS_2_WORD_TYPE(t)) { - M_DLD(REG_FTMP1, REG_SP, s1 * 8); - M_DST(REG_FTMP1, REG_SP, s2 * 8); + M_DLD(REG_FTMP1, REG_SP, s1); + M_DST(REG_FTMP1, REG_SP, s2); } else { - M_FLD(REG_FTMP1, REG_SP, s1 * 8); - M_FST(REG_FTMP1, REG_SP, s2 * 8); + M_FLD(REG_FTMP1, REG_SP, s1); + M_FST(REG_FTMP1, REG_SP, s2); } +#endif } } } - /* put class into second argument register */ + /* Handle native Java methods. */ - if (m->flags & ACC_STATIC) { - disp = dseg_add_address(cd, m->class); - M_ALD(REG_A1, REG_PV, disp); - } + if (m->flags & ACC_NATIVE) { + /* put class into second argument register */ + + if (m->flags & ACC_STATIC) + M_MOV(REG_ITMP3, REG_A1); - /* put env into first argument register */ + /* put env into first argument register */ - disp = dseg_add_address(cd, _Jv_env); - M_ALD(REG_A0, REG_PV, disp); + disp = dseg_add_address(cd, VM_get_jnienv()); + M_ALD(REG_A0, REG_PV, disp); + } - /* do the native function call */ + /* Call the native function. */ - M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */ + disp = dseg_add_functionptr(cd, f); + M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */ M_JSR(REG_RA, REG_ITMP3); /* call native method */ M_NOP; /* delay slot */ /* save return value */ - if (md->returntype.type != TYPE_VOID) { + switch (md->returntype.type) { #if SIZEOF_VOID_P == 8 - if (IS_INT_LNG_TYPE(md->returntype.type)) - M_LST(REG_RESULT, REG_SP, 0 * 8); - else - M_DST(REG_FRESULT, REG_SP, 0 * 8); + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: + M_LST(REG_RESULT, REG_SP, 0 * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DST(REG_FRESULT, REG_SP, 0 * 8); + break; #else - if (IS_INT_LNG_TYPE(md->returntype.type)) { - M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8); - if (IS_2_WORD_TYPE(md->returntype.type)) - M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4); - } - else - M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8); -#endif + case TYPE_INT: + case TYPE_ADR: + M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8); + break; + case TYPE_LNG: + M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8); + break; +#endif + case TYPE_VOID: + break; } #if !defined(NDEBUG) @@ -4211,7 +3918,8 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) /* remove native stackframe info */ - M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0); + M_MOV(REG_SP, REG_A0); + M_MOV(REG_PV, REG_A1); disp = dseg_add_functionptr(cd, codegen_finish_native_call); M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); @@ -4220,21 +3928,32 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) /* restore return value */ - if (md->returntype.type != TYPE_VOID) { + switch (md->returntype.type) { #if SIZEOF_VOID_P == 8 - if (IS_INT_LNG_TYPE(md->returntype.type)) - M_LLD(REG_RESULT, REG_SP, 0 * 8); - else - M_DLD(REG_FRESULT, REG_SP, 0 * 8); + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: + M_LLD(REG_RESULT, REG_SP, 0 * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DLD(REG_FRESULT, REG_SP, 0 * 8); + break; #else - if (IS_INT_LNG_TYPE(md->returntype.type)) { - M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8); - if (IS_2_WORD_TYPE(md->returntype.type)) - M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4); - } - else - M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8); -#endif + case TYPE_INT: + case TYPE_ADR: + M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8); + break; + case TYPE_LNG: + M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8); + break; +#endif + case TYPE_VOID: + break; } M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */ @@ -4254,13 +3973,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) M_JMP(REG_ITMP3); /* jump to asm exception handler */ M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */ - /* generate patcher stubs */ - - emit_patcher_stubs(jd); - - codegen_finish(jd); + /* Generate patcher traps. */ - return code->entrypoint; + emit_patcher_traps(jd); }