X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Fcodegen.c;h=68ad764c25c95a1976a362173a738ccea746a9f4;hb=2f22fef9e8f80103c54b2bd06492340a4447a2af;hp=15dd71e2678a34897ff32ebe47dbea188e8ff0d7;hpb=d618789d14ccf54bd2f7343f67763983158d1b3b;p=cacao.git diff --git a/src/vm/jit/mips/codegen.c b/src/vm/jit/mips/codegen.c index 15dd71e26..68ad764c2 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 7570 2007-03-24 22:20:09Z twisti $ - */ @@ -41,25 +37,26 @@ #include "mm/memory.h" +#include "native/localref.h" #include "native/native.h" -#if defined(ENABLE_THREADS) -# include "threads/native/lock.h" -#endif +#include "threads/lock-common.h" #include "vm/builtin.h" #include "vm/exceptions.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/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/linenumbertable.h" +#include "vm/jit/patcher-common.h" #include "vm/jit/reg.h" #include "vm/jit/replace.h" +#include "vm/jit/trap.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" @@ -85,7 +82,6 @@ bool codegen_emit(jitdata *jd) varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; u2 currentline; constant_classref *cr; unresolved_class *uc; @@ -120,7 +116,7 @@ bool codegen_emit(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 */ @@ -132,7 +128,7 @@ bool codegen_emit(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 @@ -152,34 +148,18 @@ bool codegen_emit(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) @@ -188,7 +168,7 @@ bool codegen_emit(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--) { @@ -215,121 +195,77 @@ bool codegen_emit(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; @@ -339,10 +275,10 @@ bool codegen_emit(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; } @@ -351,7 +287,7 @@ bool codegen_emit(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); @@ -361,7 +297,7 @@ bool codegen_emit(jitdata *jd) 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, EXCEPTION_HARDWARE_NULLPOINTER); + M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException); } M_JSR(REG_RA, REG_ITMP3); @@ -370,10 +306,10 @@ bool codegen_emit(jitdata *jd) # 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); @@ -454,7 +390,7 @@ bool codegen_emit(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; } @@ -475,14 +411,14 @@ bool codegen_emit(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 */ @@ -535,7 +471,8 @@ bool codegen_emit(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); } @@ -554,23 +491,23 @@ bool codegen_emit(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; @@ -980,22 +917,17 @@ bool codegen_emit(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); @@ -1756,7 +1688,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); /* implicit null-pointer check */ - M_ILD(d, s1, OFFSET(java_arrayheader, size)); + M_ILD(d, s1, OFFSET(java_array_t, size)); emit_store_dst(jd, iptr, d); break; @@ -1768,7 +1700,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP3); /* implicit null-pointer check */ - M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0])); + M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1781,7 +1713,7 @@ bool codegen_emit(jitdata *jd) M_AADD(s2, s1, REG_ITMP3); M_AADD(s2, REG_ITMP3, REG_ITMP3); /* implicit null-pointer check */ - M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0])); + M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1794,7 +1726,7 @@ bool codegen_emit(jitdata *jd) M_AADD(s2, s1, REG_ITMP3); M_AADD(s2, REG_ITMP3, REG_ITMP3); /* implicit null-pointer check */ - M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0])); + M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1807,7 +1739,7 @@ bool codegen_emit(jitdata *jd) M_ASLL_IMM(s2, 2, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); /* implicit null-pointer check */ - M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray, data[0])); + M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1824,7 +1756,7 @@ bool codegen_emit(jitdata *jd) M_ASLL_IMM(s2, 3, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); /* implicit null-pointer check */ - M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0])); + M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1837,7 +1769,7 @@ bool codegen_emit(jitdata *jd) M_ASLL_IMM(s2, 2, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); /* implicit null-pointer check */ - M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray, data[0])); + M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1850,7 +1782,7 @@ bool codegen_emit(jitdata *jd) M_ASLL_IMM(s2, 3, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); /* implicit null-pointer check */ - M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0])); + M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1863,7 +1795,7 @@ bool codegen_emit(jitdata *jd) M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3); M_AADD(REG_ITMP3, s1, REG_ITMP3); /* implicit null-pointer check */ - M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray, data[0])); + M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1876,7 +1808,7 @@ bool codegen_emit(jitdata *jd) M_AADD(s2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); /* implicit null-pointer check */ - M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0])); + M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0])); break; case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1889,7 +1821,7 @@ bool codegen_emit(jitdata *jd) M_AADD(s2, REG_ITMP1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); /* implicit null-pointer check */ - M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0])); + M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0])); break; case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1901,7 +1833,7 @@ bool codegen_emit(jitdata *jd) M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); /* implicit null-pointer check */ - M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0])); + M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0])); break; case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1917,7 +1849,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED); #endif /* implicit null-pointer check */ - M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0])); + M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0])); break; case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1929,7 +1861,7 @@ bool codegen_emit(jitdata *jd) M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_FTMP1); /* implicit null-pointer check */ - M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0])); + M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0])); break; case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1941,7 +1873,7 @@ bool codegen_emit(jitdata *jd) M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_FTMP1); /* implicit null-pointer check */ - M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0])); + M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0])); break; @@ -1954,11 +1886,11 @@ bool codegen_emit(jitdata *jd) M_INTMOVE(s1, REG_A0); M_INTMOVE(s3, REG_A1); - disp = dseg_add_functionptr(cd, BUILTIN_canstore); + disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore); M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); M_NOP; - emit_exception_check(cd, iptr); + emit_arraystore_check(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); @@ -1966,7 +1898,7 @@ bool codegen_emit(jitdata *jd) M_AADD(REG_ITMP2, s1, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ITMP3); /* implicit null-pointer check */ - M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0])); + M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0])); break; @@ -1977,7 +1909,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_AADD(s2, s1, REG_ITMP1); /* implicit null-pointer check */ - M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0])); + M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0])); break; case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */ @@ -1989,7 +1921,7 @@ bool codegen_emit(jitdata *jd) M_AADD(s2, s1, REG_ITMP1); M_AADD(s2, REG_ITMP1, REG_ITMP1); /* implicit null-pointer check */ - M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0])); + M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0])); break; case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */ @@ -2000,7 +1932,7 @@ bool codegen_emit(jitdata *jd) M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); /* implicit null-pointer check */ - M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0])); + M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0])); break; case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */ @@ -2012,9 +1944,9 @@ bool codegen_emit(jitdata *jd) 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; @@ -2026,7 +1958,7 @@ bool codegen_emit(jitdata *jd) M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); /* implicit null-pointer check */ - M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0])); + M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0])); break; @@ -2037,15 +1969,16 @@ bool codegen_emit(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); @@ -2086,15 +2019,16 @@ bool codegen_emit(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); @@ -2128,23 +2062,22 @@ bool codegen_emit(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); @@ -2179,7 +2112,7 @@ bool codegen_emit(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; @@ -2250,7 +2183,7 @@ bool codegen_emit(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: @@ -2277,15 +2210,14 @@ bool codegen_emit(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; } @@ -2321,7 +2253,7 @@ bool codegen_emit(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 */ @@ -2449,10 +2381,10 @@ bool codegen_emit(jitdata *jd) #if SIZEOF_VOID_P == 8 s1 = emit_load_s1(jd, iptr, REG_ITMP1); if (iptr->sx.val.l == 0) - M_BEQZ(s1, 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) { @@ -2477,16 +2409,16 @@ bool codegen_emit(jitdata *jd) #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) { @@ -2513,16 +2445,17 @@ bool codegen_emit(jitdata *jd) #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 @@ -2552,11 +2485,11 @@ bool codegen_emit(jitdata *jd) #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) { @@ -2581,16 +2514,17 @@ bool codegen_emit(jitdata *jd) #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 @@ -2620,16 +2554,17 @@ bool codegen_emit(jitdata *jd) #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) { @@ -2837,7 +2772,7 @@ bool codegen_emit(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; @@ -2879,7 +2814,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); @@ -2940,7 +2875,7 @@ nowperformreturn: /* restore return address */ - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { p--; M_ALD(REG_RA, REG_SP, p * 8); } @@ -3090,6 +3025,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; @@ -3097,107 +3033,79 @@ 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 */ - /* generate the actual call */ + /* TWISTI: i actually don't know the reason for using + REG_ITMP3 here instead of REG_PV. */ + + 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 */ - /* TWISTI: i actually don't know the reason for using - REG_ITMP3 here instead of REG_PV. */ + /* generate the actual call */ + + M_JSR(REG_RA, REG_PV); + M_NOP; + } - M_JSR(REG_RA, REG_ITMP3); - M_NOP; REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); disp = (s4) (cd->mcodeptr - cd->mcodebase); M_LDA(REG_PV, REG_RA, -disp); - - emit_exception_check(cd, iptr); break; case ICMD_INVOKESPECIAL: @@ -3208,7 +3116,7 @@ gen_method: 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 @@ -3229,7 +3137,7 @@ gen_method: 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; } @@ -3238,7 +3146,7 @@ gen_method: sizeof(methodptr) * lm->vftblindex; /* implicit null-pointer check */ - M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl)); M_ALD(REG_PV, REG_METHODPTR, s1); /* generate the actual call */ @@ -3254,20 +3162,20 @@ gen_method: 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); } /* implicit null-pointer check */ - M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl)); + 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); @@ -3314,20 +3222,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; @@ -3338,14 +3232,10 @@ 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); /* if class is not resolved, check which code to call */ @@ -3356,7 +3246,7 @@ gen_method: 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); M_ILD(REG_ITMP2, REG_PV, disp); @@ -3370,14 +3260,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 { 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); @@ -3403,8 +3293,8 @@ gen_method: 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 { @@ -3413,11 +3303,9 @@ gen_method: 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)); */ @@ -3431,9 +3319,7 @@ 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); @@ -3457,11 +3343,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); @@ -3480,20 +3368,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; @@ -3510,10 +3384,6 @@ 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); @@ -3532,7 +3402,7 @@ gen_method: 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); M_ILD(REG_ITMP3, REG_PV, disp); @@ -3546,14 +3416,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 { 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); @@ -3579,7 +3449,7 @@ gen_method: 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 { @@ -3588,17 +3458,13 @@ gen_method: 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); @@ -3648,11 +3514,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 */ @@ -3703,12 +3570,9 @@ gen_method: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ - dseg_createlinenumbertable(cd); + /* generate traps */ - /* generate stubs */ - - emit_patcher_stubs(jd); - REPLACEMENT_EMIT_STUBS(jd); + emit_patcher_traps(jd); /* everything's ok */ @@ -3716,102 +3580,38 @@ gen_method: } -/* createcompilerstub ********************************************************** - - Creates a stub routine which calls the compiler. - -*******************************************************************************/ - -#define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P -#define COMPILERSTUB_CODESIZE 4 * 4 - -#define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE - - -u1 *createcompilerstub(methodinfo *m) -{ - u1 *s; /* memory to hold the stub */ - ptrint *d; - 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; - - /* The codeinfo pointer is actually a pointer to the - methodinfo. This fakes a codeinfo structure. */ - - d[0] = (ptrint) asm_call_jit_compiler; - d[1] = (ptrint) m; - d[2] = (ptrint) &d[1]; /* fake code->m */ - - 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 ************************************************************ +/* codegen_emit_stub_native **************************************************** - Creates a stub routine which calls a native method. + Emits a stub routine which calls a native method. *******************************************************************************/ -u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) +void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams) { - 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 */ + methodinfo *m; + codeinfo *code; + codegendata *cd; + 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 @@ -3829,12 +3629,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 */ @@ -3846,21 +3643,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++; } } @@ -3869,14 +3658,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++; } } @@ -3885,31 +3672,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++; } } @@ -3918,14 +3712,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++; } } @@ -3934,77 +3726,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 } @@ -4016,8 +3794,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 @@ -4026,13 +3802,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 */ @@ -4040,86 +3812,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 * 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); } +#else + 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); + } +#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, _Jv_env); + 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) @@ -4129,7 +3919,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); @@ -4138,21 +3929,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 */ @@ -4172,13 +3974,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); }