X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Farm%2Fcodegen.c;h=5c30df214d07ac05707a82a95fad12793d694d8c;hb=0ce178c56bb73f85555e1693ed2019387838b362;hp=bcc6372b016ce5065387addce5f519e4956f0f34;hpb=81621aca875e40515f48bc2092e896eb18985570;p=cacao.git diff --git a/src/vm/jit/arm/codegen.c b/src/vm/jit/arm/codegen.c index bcc6372b0..5c30df214 100644 --- a/src/vm/jit/arm/codegen.c +++ b/src/vm/jit/arm/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/arm/codegen.c - machine code generator for Arm - 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 7931 2007-05-21 14:42:28Z twisti $ - */ @@ -41,33 +37,34 @@ #include "mm/memory.h" +#include "native/localref.h" #include "native/native.h" #include "threads/lock-common.h" -#include "vm/builtin.h" -#include "vm/exceptions.h" +#include "vm/jit/builtin.hpp" +#include "vm/exceptions.hpp" #include "vm/global.h" -#include "vm/vm.h" +#include "vm/loader.hpp" +#include "vm/options.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/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" #include "vm/jit/parse.h" -#include "vm/jit/patcher.h" +#include "vm/jit/patcher-common.hpp" #include "vm/jit/reg.h" #if defined(ENABLE_LSRA) #include "vm/jit/allocator/lsra.h" #endif -#include "vmcore/loader.h" -#include "vmcore/options.h" - /* codegen_emit **************************************************************** @@ -87,9 +84,6 @@ bool codegen_emit(jitdata *jd) varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; - s4 fieldtype; - s4 varindex; s4 spilledregs_num; s4 savedregs_num; @@ -100,6 +94,10 @@ bool codegen_emit(jitdata *jd) unresolved_method *um; builtintable_entry *bte; methoddesc *md; + fieldinfo *fi; + unresolved_field *uf; + int fieldtype; + int varindex; /* get required compiler data */ @@ -118,64 +116,50 @@ bool codegen_emit(jitdata *jd) /* space to save used callee saved registers */ - savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the LR */ + savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the LR */ + savedregs_num += (INT_SAV_CNT - rd->savintreguse); - savedregs_num += (FLT_SAV_CNT - rd->savfltreguse); + /*savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);*/ + assert((FLT_SAV_CNT - rd->savfltreguse) == 0); spilledregs_num = rd->memuse; #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) + if (checksync && code_is_synchronized(code)) spilledregs_num++; #endif - cd->stackframesize = spilledregs_num + savedregs_num; + cd->stackframesize = spilledregs_num * 8 + savedregs_num * 4; /* XXX QUICK FIX: We shouldn't align the stack in Java code, but only in native stubs. */ /* align stack to 8-byte */ - cd->stackframesize = (cd->stackframesize + 1) & ~1; + cd->stackframesize = (cd->stackframesize + 4) & ~4; /* SECTION: Method Header */ /* create method header */ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ - (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */ + (void) dseg_add_unique_s4(cd, cd->stackframesize); /* 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) * 4);/* 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, 0); - (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */ (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ - (void) 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); - } /* save return address and used callee saved registers */ savedregs_bitmask = 0; - if (!jd->isleafmethod) + if (!code_is_leafmethod(code)) savedregs_bitmask = (1<= rd->savintreguse; i--) @@ -193,8 +177,8 @@ bool codegen_emit(jitdata *jd) /* create additional stack frame for spilled variables (if necessary) */ - if ((cd->stackframesize - savedregs_num) > 0) - M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - savedregs_num); + if ((cd->stackframesize / 4 - savedregs_num) > 0) + M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - savedregs_num); /* take arguments out of register or stack frame */ @@ -225,17 +209,17 @@ bool codegen_emit(jitdata *jd) } else { if (IS_2_WORD_TYPE(t)) - M_LST(s1, REG_SP, var->vv.regoff * 4); + M_LST(s1, REG_SP, var->vv.regoff); else - M_IST(s1, REG_SP, var->vv.regoff * 4); + M_IST(s1, REG_SP, var->vv.regoff); } } else { /* stack arguments */ if (!(var->flags & INMEMORY)) { /* stack arg -> register */ if (IS_2_WORD_TYPE(t)) - M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4); + M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1); else - M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4); + M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1); } else { /* stack arg -> spilled */ /* Reuse Memory Position on Caller Stack */ @@ -247,21 +231,24 @@ bool codegen_emit(jitdata *jd) else { if (!md->params[i].inmemory) { if (!(var->flags & INMEMORY)) { - M_CAST_INT_TO_FLT_TYPED(t, s1, var->vv.regoff); + if (IS_2_WORD_TYPE(t)) + M_CAST_L2D(s1, var->vv.regoff); + else + M_CAST_I2F(s1, var->vv.regoff); } else { if (IS_2_WORD_TYPE(t)) - M_LST(s1, REG_SP, var->vv.regoff * 4); + M_LST(s1, REG_SP, var->vv.regoff); else - M_IST(s1, REG_SP, var->vv.regoff * 4); + M_IST(s1, REG_SP, var->vv.regoff); } } else { if (!(var->flags & INMEMORY)) { if (IS_2_WORD_TYPE(t)) - M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4); + M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1); else - M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4); + M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1); } else { /* Reuse Memory Position on Caller Stack */ @@ -275,29 +262,29 @@ bool codegen_emit(jitdata *jd) #if defined(ENABLE_THREADS) /* call monitorenter function */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stack offset for monitor argument */ - s1 = rd->memuse; + s1 = rd->memuse * 8; # if !defined(NDEBUG) if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { M_STMFD(BITMASK_ARGS, REG_SP); - s1 += 4; + s1 += 4 * 4; } # endif /* get the 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_DSEG_LOAD(REG_A0, disp); } else { emit_nullpointer_check_force(cd, iptr, REG_A0); } - M_STR(REG_A0, REG_SP, s1 * 4); + M_STR(REG_A0, REG_SP, s1); disp = dseg_add_functionptr(cd, LOCK_monitor_enter); M_DSEG_BRANCH(disp); s1 = (s4) (cd->mcodeptr - cd->mcodebase); @@ -319,6 +306,9 @@ bool codegen_emit(jitdata *jd) /* end of header generation */ + /* create replacement points */ + REPLACEMENT_POINTS_INIT(cd, jd); + /* SECTION: ICMD Code Generation */ /* for all basic blocks */ @@ -335,6 +325,9 @@ bool codegen_emit(jitdata *jd) codegen_resolve_branchrefs(cd, bptr); + /* handle replacement points */ + REPLACEMENT_POINT_BLOCK_START(cd, bptr); + /* copy interface registers to their destination */ len = bptr->indepth; @@ -381,18 +374,21 @@ bool codegen_emit(jitdata *jd) /* add line number */ if (iptr->line != currentline) { - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add(cd, iptr->line); currentline = iptr->line; } MCODECHECK(64); /* an instruction usually needs < 64 words */ - /* the big switch */ - switch (iptr->opc) { - case ICMD_NOP: /* ... ==> ... */ + /* the big switch */ + switch (iptr->opc) { + + case ICMD_NOP: /* ... ==> ... */ + case ICMD_POP: /* ..., value ==> ... */ + case ICMD_POP2: /* ..., value, value ==> ... */ break; - /* constant operations ************************************************/ + /* constant operations ************************************************/ case ICMD_ICONST: /* ... ==> ..., constant */ @@ -407,12 +403,8 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_aconst, - iptr->sx.val.c.ref, - disp); - - if (opt_showdisassemble) - M_NOP; + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, + iptr->sx.val.c.ref, disp); M_DSEG_LOAD(d, disp); } @@ -474,19 +466,11 @@ bool codegen_emit(jitdata *jd) break; case ICMD_ASTORE: + if (!(iptr->flags.bits & INS_FLAG_RETADDR)) emit_copy(jd, iptr); break; - /* pop operations *****************************************************/ - - /* attention: double and longs are only one entry in CACAO ICMDs */ - - case ICMD_POP: /* ..., value ==> ... */ - case ICMD_POP2: /* ..., value, value ==> ... */ - - break; - /* integer operations *************************************************/ @@ -914,7 +898,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_MNFS(d, s1); + M_FNEG(s1, d); emit_store_dst(jd, iptr, d); break; @@ -923,7 +907,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_ADFS(d, s1, s2); + M_FADD(s1, s2, d); emit_store_dst(jd, iptr, d); break; @@ -932,7 +916,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_SUFS(d, s1, s2); + M_FSUB(s1, s2, d); emit_store_dst(jd, iptr, d); break; @@ -941,7 +925,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_MUFS(d, s1, s2); + M_FMUL(s1, s2, d); emit_store_dst(jd, iptr, d); break; @@ -949,13 +933,14 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_DVFS(d, s1, s2); + M_FDIV(s1, s2, d); emit_store_dst(jd, iptr, d); break; /* ATTENTION: Jave does not want IEEE behaviour in FREM, do not use this */ +#if 0 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */ s1 = emit_load_s1(jd, iptr, REG_FTMP1); @@ -964,12 +949,13 @@ bool codegen_emit(jitdata *jd) M_RMFS(d, s1, s2); emit_store_dst(jd, iptr, d); break; +#endif case ICMD_DNEG: /* ..., value ==> ..., - value */ s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_MNFD(d, s1); + M_DNEG(s1, d); emit_store_dst(jd, iptr, d); break; @@ -978,7 +964,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_ADFD(d, s1, s2); + M_DADD(s1, s2, d); emit_store_dst(jd, iptr, d); break; @@ -987,7 +973,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_SUFD(d, s1, s2); + M_DSUB(s1, s2, d); emit_store_dst(jd, iptr, d); break; @@ -996,7 +982,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_MUFD(d, s1, s2); + M_DMUL(s1, s2, d); emit_store_dst(jd, iptr, d); break; @@ -1005,13 +991,14 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_DVFD(d, s1, s2); + M_DDIV(s1, s2, d); emit_store_dst(jd, iptr, d); break; /* ATTENTION: Jave does not want IEEE behaviour in DREM, do not use this */ +#if 0 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */ s1 = emit_load_s1(jd, iptr, REG_FTMP1); @@ -1020,12 +1007,13 @@ bool codegen_emit(jitdata *jd) M_RMFD(d, s1, s2); emit_store_dst(jd, iptr, d); break; +#endif case ICMD_I2F: /* ..., value ==> ..., (float) value */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_FLTS(d, s1); + M_CVTIF(s1, d); emit_store_dst(jd, iptr, d); break; @@ -1033,7 +1021,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_FLTD(d, s1); + M_CVTID(s1, d); emit_store_dst(jd, iptr, d); break; @@ -1042,10 +1030,12 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); /* this uses round towards zero, as Java likes it */ - M_FIX(d, s1); + M_CVTFI(s1, d); +#if !defined(__VFP_FP__) /* this checks for NaN; to return zero as Java likes it */ - M_CMF(s1, 0x8); + M_FCMP(s1, 0x8); M_MOVVS_IMM(0, d); +#endif emit_store_dst(jd, iptr, d); break; @@ -1054,10 +1044,12 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); /* this uses round towards zero, as Java likes it */ - M_FIX(d, s1); + M_CVTDI(s1, d); +#if !defined(__VFP_FP__) /* this checks for NaN; to return zero as Java likes it */ - M_CMF(s1, 0x8); + M_DCMP(s1, 0x8); M_MOVVS_IMM(0, d); +#endif emit_store_dst(jd, iptr, d); break; @@ -1065,7 +1057,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_FTMP2); - M_MVFS(d,s1); + M_CVTDF(s1, d); emit_store_dst(jd, iptr, d); break; @@ -1073,7 +1065,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_FTMP2); - M_MVFD(d,s1); + M_CVTFD(s1, d); emit_store_dst(jd, iptr, d); break; @@ -1082,8 +1074,11 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - M_CMF(s2, s1); + M_FCMP(s2, s1); M_MOV_IMM(d, 0); +#if defined(__VFP_FP__) + M_FMSTAT; /* on VFP we need to transfer the flags */ +#endif M_SUBGT_IMM(d, d, 1); M_ADDLT_IMM(d, d, 1); emit_store_dst(jd, iptr, d); @@ -1094,8 +1089,11 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - M_CMF(s2, s1); + M_DCMP(s2, s1); M_MOV_IMM(d, 0); +#if defined(__VFP_FP__) + M_FMSTAT; /* on VFP we need to transfer the flags */ +#endif M_SUBGT_IMM(d, d, 1); M_ADDLT_IMM(d, d, 1); emit_store_dst(jd, iptr, d); @@ -1106,8 +1104,11 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - M_CMF(s1, s2); + M_FCMP(s1, s2); M_MOV_IMM(d, 0); +#if defined(__VFP_FP__) + M_FMSTAT; /* on VFP we need to transfer the flags */ +#endif M_SUBLT_IMM(d, d, 1); M_ADDGT_IMM(d, d, 1); emit_store_dst(jd, iptr, d); @@ -1118,8 +1119,11 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - M_CMF(s1, s2); + M_DCMP(s1, s2); M_MOV_IMM(d, 0); +#if defined(__VFP_FP__) + M_FMSTAT; /* on VFP we need to transfer the flags */ +#endif M_SUBLT_IMM(d, d, 1); M_ADDGT_IMM(d, d, 1); emit_store_dst(jd, iptr, d); @@ -1135,7 +1139,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_INTERN(d, s1, OFFSET(java_arrayheader, size)); + M_ILD_INTERN(d, s1, OFFSET(java_array_t, size)); emit_store_dst(jd, iptr, d); break; @@ -1147,7 +1151,7 @@ bool codegen_emit(jitdata *jd) /* implicit null-pointer check */ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ADD(REG_ITMP1, s1, s2); /* REG_ITMP1 = s1 + 1 * s2 */ - M_LDRSB(d, REG_ITMP1, OFFSET(java_bytearray, data[0])); + M_LDRSB(d, REG_ITMP1, OFFSET(java_bytearray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1159,7 +1163,7 @@ bool codegen_emit(jitdata *jd) /* implicit null-pointer check */ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */ - M_LDRH(d, REG_ITMP1, OFFSET(java_chararray, data[0])); + M_LDRH(d, REG_ITMP1, OFFSET(java_chararray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1171,7 +1175,7 @@ bool codegen_emit(jitdata *jd) /* implicit null-pointer check */ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */ - M_LDRSH(d, REG_ITMP1, OFFSET(java_shortarray, data[0])); + M_LDRSH(d, REG_ITMP1, OFFSET(java_shortarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1183,7 +1187,7 @@ bool codegen_emit(jitdata *jd) /* implicit null-pointer check */ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */ - M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_intarray, data[0])); + M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_intarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1195,7 +1199,7 @@ bool codegen_emit(jitdata *jd) /* implicit null-pointer check */ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */ - 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; @@ -1208,10 +1212,10 @@ bool codegen_emit(jitdata *jd) M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */ #if !defined(ENABLE_SOFTFLOAT) d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_FLD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray, data[0])); + M_FLD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0])); #else d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray, data[0])); + M_ILD_INTERN(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0])); #endif emit_store_dst(jd, iptr, d); break; @@ -1225,10 +1229,10 @@ bool codegen_emit(jitdata *jd) M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */ #if !defined(ENABLE_SOFTFLOAT) d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0])); + M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0])); #else d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); - M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0])); + M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0])); #endif emit_store_dst(jd, iptr, d); break; @@ -1241,7 +1245,7 @@ bool codegen_emit(jitdata *jd) /* implicit null-pointer check */ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */ - M_LDR_INTERN(d, REG_ITMP1, OFFSET(java_objectarray, data[0])); + M_LDR_INTERN(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1253,7 +1257,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_ADD(REG_ITMP1, s1, s2); /* REG_ITMP1 = s1 + 1 * s2 */ - M_STRB(s3, REG_ITMP1, OFFSET(java_bytearray, data[0])); + M_STRB(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0])); break; case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1264,7 +1268,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */ - M_STRH(s3, REG_ITMP1, OFFSET(java_chararray, data[0])); + M_STRH(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0])); break; case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1275,7 +1279,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 1)); /* REG_ITMP1 = s1 + 2 * s2 */ - M_STRH(s3, REG_ITMP1, OFFSET(java_shortarray, data[0])); + M_STRH(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0])); break; case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1286,7 +1290,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */ - 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 ==> ... */ @@ -1297,7 +1301,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_ADD(REG_ITMP3, s1, REG_LSL(s2, 3)); /* REG_ITMP3 = s1 + 8 * s2 */ s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED); - M_LST_INTERN(s3, REG_ITMP3, OFFSET(java_longarray, data[0])); + M_LST_INTERN(s3, REG_ITMP3, OFFSET(java_longarray_t, data[0])); break; case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1309,10 +1313,10 @@ bool codegen_emit(jitdata *jd) M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */ #if !defined(ENABLE_SOFTFLOAT) s3 = emit_load_s3(jd, iptr, REG_FTMP1); - M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0])); + M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0])); #else s3 = emit_load_s3(jd, iptr, REG_ITMP3); - M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0])); + M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0])); #endif break; @@ -1325,10 +1329,10 @@ bool codegen_emit(jitdata *jd) M_ADD(REG_ITMP1, s1, REG_LSL(s2, 3)); /* REG_ITMP1 = s1 + 8 * s2 */ #if !defined(ENABLE_SOFTFLOAT) s3 = emit_load_s3(jd, iptr, REG_FTMP1); - M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0])); + M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0])); #else s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED); - M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0])); + M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0])); #endif break; @@ -1346,7 +1350,7 @@ bool codegen_emit(jitdata *jd) M_INTMOVE(s3, REG_A1); /* call builtin function */ - disp = dseg_add_functionptr(cd, BUILTIN_canstore); + disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore); M_DSEG_BRANCH(disp); /* recompute pv */ @@ -1354,43 +1358,34 @@ bool codegen_emit(jitdata *jd) M_RECOMPUTE_PV(s1); /* check resturn value of builtin */ - emit_exception_check(cd, iptr); + emit_arraystore_check(cd, iptr); /* finally store address into array */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_ADD(REG_ITMP1, s1, REG_LSL(s2, 2)); /* REG_ITMP1 = s1 + 4 * s2 */ - M_STR_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0])); + M_STR_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0])); break; case ICMD_GETSTATIC: /* ... ==> ..., value */ 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 = dseg_add_unique_address(cd, NULL); - disp = dseg_add_unique_address(cd, NULL); - - codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp); - - if (opt_showdisassemble) - M_NOP; + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; + disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { - codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0); - - if (opt_showdisassemble) - M_NOP; + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { + patcher_add_patch_ref(jd, PATCHER_initialize_class, + fi->clazz, 0); } - - disp = dseg_add_address(cd, &(fi->value)); } M_DSEG_LOAD(REG_ITMP3, disp); @@ -1429,30 +1424,21 @@ bool codegen_emit(jitdata *jd) case ICMD_PUTSTATIC: /* ..., value ==> ... */ 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 = dseg_add_unique_address(cd, NULL); - disp = dseg_add_unique_address(cd, NULL); - - codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp); - - if (opt_showdisassemble) - M_NOP; + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; + disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { - codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0); - - if (opt_showdisassemble) - M_NOP; + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { + patcher_add_patch_ref(jd, PATCHER_initialize_class, + fi->clazz, 0); } - - disp = dseg_add_address(cd, &(fi->value)); } M_DSEG_LOAD(REG_ITMP3, disp); @@ -1494,13 +1480,12 @@ bool codegen_emit(jitdata *jd) 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; } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = fi->offset; } @@ -1512,14 +1497,10 @@ bool codegen_emit(jitdata *jd) #endif if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - unresolved_field *uf = iptr->sx.s23.s3.uf; - - codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); - - if (opt_showdisassemble) - M_NOP; + /* XXX REMOVE ME */ + uf = iptr->sx.s23.s3.uf; - disp = 0; + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); } switch (fieldtype) { @@ -1560,13 +1541,12 @@ 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; } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = fi->offset; } @@ -1602,14 +1582,10 @@ bool codegen_emit(jitdata *jd) } if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - unresolved_field *uf = iptr->sx.s23.s3.uf; - - codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); - - if (opt_showdisassemble) - M_NOP; + /* XXX REMOVE ME */ + uf = iptr->sx.s23.s3.uf; - disp = 0; + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); } switch (fieldtype) { @@ -1647,11 +1623,8 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); M_INTMOVE(s1, REG_ITMP1_XPTR); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - codegen_addpatchref(cd, PATCHER_athrow_areturn, + patcher_add_patch_ref(jd, PATCHER_resolve_class, iptr->sx.s23.s2.uc, 0); - - if (opt_showdisassemble) - M_NOP; } disp = dseg_add_functionptr(cd, asm_handle_exception); M_DSEG_LOAD(REG_ITMP3, disp); @@ -2069,13 +2042,15 @@ bool codegen_emit(jitdata *jd) case ICMD_FRETURN: /* ..., retvalue ==> ... */ #if !defined(ENABLE_SOFTFLOAT) + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_FTMP1); - M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT); + M_CAST_F2I(s1, REG_RESULT); goto ICMD_RETURN_do; #endif case ICMD_IRETURN: /* ..., retvalue ==> ... */ + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_RESULT); M_INTMOVE(s1, REG_RESULT); goto ICMD_RETURN_do; @@ -2083,31 +2058,33 @@ bool codegen_emit(jitdata *jd) case ICMD_DRETURN: /* ..., retvalue ==> ... */ #if !defined(ENABLE_SOFTFLOAT) + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_FTMP1); - M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT_PACKED); + M_CAST_D2L(s1, REG_RESULT_PACKED); goto ICMD_RETURN_do; #endif case ICMD_LRETURN: /* ..., retvalue ==> ... */ + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED); M_LNGMOVE(s1, REG_RESULT_PACKED); goto ICMD_RETURN_do; case ICMD_ARETURN: /* ..., retvalue ==> ... */ + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_RESULT); M_INTMOVE(s1, REG_RESULT); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - codegen_addpatchref(cd, PATCHER_athrow_areturn, + patcher_add_patch_ref(jd, PATCHER_resolve_class, iptr->sx.s23.s2.uc, 0); - - if (opt_showdisassemble) - M_NOP; } goto ICMD_RETURN_do; case ICMD_RETURN: /* ... ==> ... */ + + REPLACEMENT_POINT_RETURN(cd, iptr); ICMD_RETURN_do: #if !defined(NDEBUG) @@ -2118,10 +2095,10 @@ bool codegen_emit(jitdata *jd) #if defined(ENABLE_THREADS) /* call monitorexit function */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stack offset for monitor argument */ - s1 = rd->memuse; + s1 = rd->memuse * 8; /* we need to save the proper return value */ @@ -2132,11 +2109,11 @@ bool codegen_emit(jitdata *jd) case ICMD_FRETURN: /* XXX TWISTI: is that correct? */ case ICMD_DRETURN: M_STMFD(BITMASK_RESULT, REG_SP); - s1 += 2; + s1 += 2 * 4; break; } - M_LDR(REG_A0, REG_SP, s1 * 4); + M_LDR(REG_A0, REG_SP, s1); disp = dseg_add_functionptr(cd, LOCK_monitor_exit); M_DSEG_BRANCH(disp); @@ -2158,13 +2135,13 @@ bool codegen_emit(jitdata *jd) /* deallocate stackframe for spilled variables */ - if ((cd->stackframesize - savedregs_num) > 0) - M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - savedregs_num); + if ((cd->stackframesize / 4 - savedregs_num) > 0) + M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - savedregs_num); /* restore callee saved registers + do return */ if (savedregs_bitmask) { - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { savedregs_bitmask &= ~(1<isleafmethod) + if (code_is_leafmethod(code)) M_MOV(REG_PC, REG_LR); break; @@ -2188,6 +2165,8 @@ bool codegen_emit(jitdata *jd) case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */ case ICMD_INVOKEINTERFACE: + REPLACEMENT_POINT_INVOKE(cd, iptr); + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { lm = NULL; um = iptr->sx.s23.s3.um; @@ -2228,11 +2207,11 @@ bool codegen_emit(jitdata *jd) else { if (IS_2_WORD_TYPE(var->type)) { s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED); - M_LST(s1, REG_SP, d * 4); + M_LST(s1, REG_SP, d); } else { s1 = emit_load(jd, iptr, var, REG_ITMP1); - M_IST(s1, REG_SP, d * 4); + M_IST(s1, REG_SP, d); } } #if !defined(ENABLE_SOFTFLOAT) @@ -2240,14 +2219,17 @@ bool codegen_emit(jitdata *jd) else { if (!md->params[s3].inmemory) { s1 = emit_load(jd, iptr, var, REG_FTMP1); - M_CAST_FLT_TO_INT_TYPED(var->type, s1, d); + if (IS_2_WORD_TYPE(var->type)) + M_CAST_D2L(s1, d); + else + M_CAST_F2I(s1, d); } else { s1 = emit_load(jd, iptr, var, REG_FTMP1); if (IS_2_WORD_TYPE(var->type)) - M_DST(s1, REG_SP, d * 4); + M_DST(s1, REG_SP, d); else - M_FST(s1, REG_SP, d * 4); + M_FST(s1, REG_SP, d); } } #endif /* !defined(ENABLE_SOFTFLOAT) */ @@ -2255,7 +2237,12 @@ bool codegen_emit(jitdata *jd) switch (iptr->opc) { case ICMD_BUILTIN: - disp = dseg_add_functionptr(cd, bte->fp); + + if (bte->stub == NULL) { + disp = dseg_add_functionptr(cd, bte->fp); + } else { + disp = dseg_add_functionptr(cd, bte->stub); + } M_DSEG_LOAD(REG_PV, disp); /* pointer to built-in-function */ @@ -2265,8 +2252,6 @@ bool codegen_emit(jitdata *jd) M_MOV(REG_PC, REG_PV); s1 = (s4) (cd->mcodeptr - cd->mcodebase); M_RECOMPUTE_PV(s1); - - emit_exception_check(cd, iptr); break; case ICMD_INVOKESPECIAL: @@ -2277,11 +2262,8 @@ bool codegen_emit(jitdata *jd) if (lm == NULL) { disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_invokestatic_special, + patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, disp); - - if (opt_showdisassemble) - M_NOP; } else disp = dseg_add_address(cd, lm->stubroutine); @@ -2298,10 +2280,7 @@ bool codegen_emit(jitdata *jd) case ICMD_INVOKEVIRTUAL: if (lm == NULL) { - codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0); - - if (opt_showdisassemble) - M_NOP; + patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0); s1 = 0; } @@ -2311,7 +2290,7 @@ bool codegen_emit(jitdata *jd) /* implicit null-pointer check */ M_LDR_INTERN(REG_METHODPTR, REG_A0, - OFFSET(java_objectheader, vftbl)); + OFFSET(java_object_t, vftbl)); M_LDR_INTERN(REG_PV, REG_METHODPTR, s1); /* generate the actual call */ @@ -2324,23 +2303,20 @@ bool codegen_emit(jitdata *jd) case ICMD_INVOKEINTERFACE: if (lm == NULL) { - codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0); - - if (opt_showdisassemble) - M_NOP; + 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; - s2 = sizeof(methodptr) * (lm - lm->class->methods); + sizeof(methodptr*) * lm->clazz->index; + s2 = sizeof(methodptr) * (lm - lm->clazz->methods); } /* implicit null-pointer check */ M_LDR_INTERN(REG_METHODPTR, REG_A0, - OFFSET(java_objectheader, vftbl)); + OFFSET(java_object_t, vftbl)); M_LDR_INTERN(REG_METHODPTR, REG_METHODPTR, s1); M_LDR_INTERN(REG_PV, REG_METHODPTR, s2); @@ -2353,6 +2329,9 @@ bool codegen_emit(jitdata *jd) break; } + /* store size of call code in replacement point */ + REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); + /* store return value */ d = md->returntype.type; @@ -2363,7 +2342,7 @@ bool codegen_emit(jitdata *jd) our ENABLE_SOFTFLOAT define */ if (iptr->opc == ICMD_BUILTIN && d != TYPE_VOID && IS_FLT_DBL_TYPE(d)) { #if 0 && !defined(NDEBUG) - dolog("BUILTIN that returns float or double (%s.%s)", m->class->name->text, m->name->text); + dolog("BUILTIN that returns float or double (%s.%s)", m->clazz->name->text, m->name->text); #endif /* we cannot use this macro, since it is not defined in ENABLE_SOFTFLOAT M_CAST_FLT_TO_INT_TYPED(d, @@ -2394,7 +2373,10 @@ bool codegen_emit(jitdata *jd) #if !defined(ENABLE_SOFTFLOAT) } else { s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - M_CAST_INT_TO_FLT_TYPED(VAROP(iptr->dst)->type, REG_RESULT_TYPED(VAROP(iptr->dst)->type), s1); + if (IS_2_WORD_TYPE(d)) + M_CAST_L2D(REG_RESULT_PACKED, s1); + else + M_CAST_I2F(REG_RESULT, s1); } #endif /* !defined(ENABLE_SOFTFLOAT) */ @@ -2419,9 +2401,6 @@ bool codegen_emit(jitdata *jd) superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) - CODEGEN_CRITICAL_SECTION_NEW; - s1 = emit_load_s1(jd, iptr, REG_ITMP1); /* if class is not resolved, check which code to call */ @@ -2431,12 +2410,9 @@ bool codegen_emit(jitdata *jd) emit_label_beq(cd, BRANCH_LABEL_1); disp = dseg_add_unique_s4(cd, 0); /* super->flags */ - codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, disp); - if (opt_showdisassemble) - M_NOP; - M_DSEG_LOAD(REG_ITMP2, disp); disp = dseg_add_s4(cd, ACC_INTERFACE); M_DSEG_LOAD(REG_ITMP3, disp); @@ -2451,19 +2427,15 @@ bool codegen_emit(jitdata *jd) disp = dseg_add_unique_s4(cd, superindex); } if (super == NULL) { - codegen_addpatchref(cd, - PATCHER_checkcast_instanceof_interface, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; } else { M_TST(s1, s1); emit_label_beq(cd, BRANCH_LABEL_3); } - M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); + M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength)); /* we put unresolved or non-immediate superindices onto dseg */ @@ -2482,7 +2454,7 @@ bool codegen_emit(jitdata *jd) things differently here! */ if ((super == NULL) || !IS_IMM(superindex)) { - M_LDR_INTERN(REG_ITMP3, s1, OFFSET(java_objectheader, vftbl)); + M_LDR_INTERN(REG_ITMP3, s1, OFFSET(java_object_t, vftbl)); /* this assumes something */ assert(OFFSET(vftbl_t, interfacetable[0]) == 0); @@ -2518,12 +2490,9 @@ bool codegen_emit(jitdata *jd) disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; } else { disp = dseg_add_address(cd, super->vftbl); @@ -2532,19 +2501,15 @@ bool codegen_emit(jitdata *jd) emit_label_beq(cd, BRANCH_LABEL_5); } - M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); + M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_DSEG_LOAD(REG_ITMP3, disp); - CODEGEN_CRITICAL_SECTION_START; - M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval)); M_SUB(REG_ITMP2, REG_ITMP2, REG_ITMP3); M_DSEG_LOAD(REG_ITMP3, disp); M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_CMP(REG_ITMP2, REG_ITMP3); emit_classcast_check(cd, iptr, BRANCH_UGT, 0, s1); @@ -2568,12 +2533,9 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; } else disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); @@ -2612,9 +2574,6 @@ bool codegen_emit(jitdata *jd) superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) - CODEGEN_CRITICAL_SECTION_NEW; - s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); @@ -2632,12 +2591,9 @@ bool codegen_emit(jitdata *jd) emit_label_beq(cd, BRANCH_LABEL_1); disp = dseg_add_unique_s4(cd, 0); /* super->flags */ - codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, disp); - if (opt_showdisassemble) - M_NOP; - M_DSEG_LOAD(REG_ITMP2, disp); disp = dseg_add_s4(cd, ACC_INTERFACE); M_DSEG_LOAD(REG_ITMP3, disp); @@ -2657,12 +2613,8 @@ bool codegen_emit(jitdata *jd) if (d == REG_ITMP2) M_EOR(d, d, d); - codegen_addpatchref(cd, - PATCHER_checkcast_instanceof_interface, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; } else { M_EOR(d, d, d); @@ -2670,7 +2622,7 @@ bool codegen_emit(jitdata *jd) emit_label_beq(cd, BRANCH_LABEL_3); } - M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl)); + M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_object_t, vftbl)); M_LDR_INTERN(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength)); @@ -2730,12 +2682,8 @@ bool codegen_emit(jitdata *jd) disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class, - iptr->sx.s23.s3.c.ref, - disp); - - if (opt_showdisassemble) - M_NOP; + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, + iptr->sx.s23.s3.c.ref, disp); } else { disp = dseg_add_address(cd, super->vftbl); @@ -2745,17 +2693,13 @@ bool codegen_emit(jitdata *jd) emit_label_beq(cd, BRANCH_LABEL_5); } - M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl)); + M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_object_t, vftbl)); M_DSEG_LOAD(REG_ITMP2, disp); - CODEGEN_CRITICAL_SECTION_START; - M_LDR_INTERN(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval)); M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_SUB(REG_ITMP1, REG_ITMP1, REG_ITMP3); M_CMP(REG_ITMP1, REG_ITMP2); /* If d == REG_ITMP2, then it's destroyed */ @@ -2805,11 +2749,8 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_builtin_multianewarray, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; } else disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); @@ -2859,12 +2800,9 @@ bool codegen_emit(jitdata *jd) } /* for all basic blocks */ - dseg_createlinenumbertable(cd); - + /* generate traps */ - /* generate stubs */ - - emit_patcher_stubs(jd); + emit_patcher_traps(jd); /* everything's ok */ @@ -2901,16 +2839,16 @@ void codegen_emit_stub_compiler(jitdata *jd) *******************************************************************************/ -void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) +void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams) { methodinfo *m; codeinfo *code; codegendata *cd; - s4 nativeparams; methoddesc *md; s4 i, j; s4 t; - s4 disp, funcdisp, s1, s2; + int s1, s2; + int disp; /* get required compiler data */ @@ -2921,52 +2859,46 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* initialize variables */ md = m->parseddesc; - nativeparams = (m->flags & ACC_STATIC) ? 2 : 1; /* calculate stackframe size */ - cd->stackframesize = - 1 + /* return address */ - sizeof(stackframeinfo) / SIZEOF_VOID_P + /* stackframeinfo */ - sizeof(localref_table) / SIZEOF_VOID_P + /* localref_table */ - nmd->memuse; /* stack arguments */ + cd->stackframesize = + 4 + /* return address */ + sizeof(stackframeinfo_t) + /* stackframeinfo */ + sizeof(localref_table) + /* localref_table */ + nmd->memuse * 4; /* stack arguments */ /* align stack to 8-byte */ - cd->stackframesize = (cd->stackframesize + 1) & ~1; + cd->stackframesize = (cd->stackframesize + 4) & ~4; /* create method header */ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ - (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */ - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ + (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */ (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 */ M_STMFD(1<stackframesize - 1); + M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - 1); #if !defined(NDEBUG) if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) emit_verbosecall_enter(jd); #endif - /* get function address (this must happen before the stackframeinfo) */ - - funcdisp = dseg_add_functionptr(cd, f); +#if defined(ENABLE_GC_CACAO) + /* Save callee saved integer registers in stackframeinfo (GC may + need to recover them during a collection). */ -#if !defined(WITH_STATIC_CLASSPATH) - if (f == NULL) { - codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp); + disp = cd->stackframesize - SIZEOF_VOID_P - sizeof(stackframeinfo_t) + + OFFSET(stackframeinfo_t, intregs); - if (opt_showdisassemble) - M_NOP; - } + for (i = 0; i < INT_SAV_CNT; i++) + M_STR_INTERN(abi_registers_integer_saved[i], REG_SP, disp + i * 4); #endif /* Save integer and float argument registers (these are 4 @@ -2977,11 +2909,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* create native stackframe info */ - assert(IS_IMM(4*4 + cd->stackframesize * 4)); - M_ADD_IMM(REG_A0, REG_SP, 4*4 + cd->stackframesize * 4 - SIZEOF_VOID_P); + M_ADD_IMM(REG_A0, REG_SP, 4*4); M_MOV(REG_A1, REG_PV); - M_ADD_IMM(REG_A2, REG_SP, 4*4 + cd->stackframesize * 4); - M_LDR_INTERN(REG_A3, REG_SP, 4*4 + cd->stackframesize * 4 - SIZEOF_VOID_P); disp = dseg_add_functionptr(cd, codegen_start_native_call); M_DSEG_BRANCH(disp); @@ -2990,6 +2919,11 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) s1 = (s4) (cd->mcodeptr - cd->mcodebase); M_RECOMPUTE_PV(s1); + /* remember class argument */ + + if (m->flags & ACC_STATIC) + M_MOV(REG_ITMP3, REG_RESULT); + /* Restore integer and float argument registers (these are 4 registers, stack is 8-byte aligned). */ @@ -2999,7 +2933,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* copy or spill arguments to new locations */ /* ATTENTION: the ARM has only integer argument registers! */ - 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->paramtypes[i].type; if (!md->params[i].inmemory) { @@ -3008,8 +2942,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) if (!nmd->params[j].inmemory) { #if !defined(__ARM_EABI__) - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); SPLIT_OPEN(t, s2, REG_ITMP1); #endif @@ -3023,16 +2955,10 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) #endif } else { -#if !defined(__ARM_EABI__) - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); -#endif - 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); - /* no SPLIT_CLOSE here because argument is fully on stack now */ + M_IST(s1, REG_SP, s2); } } else { @@ -3040,31 +2966,34 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) s2 = nmd->params[j].regoff; if (IS_2_WORD_TYPE(t)) { - M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 4); - M_LST(REG_ITMP12_PACKED, 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 * 4); - M_IST(REG_ITMP1, REG_SP, s2 * 4); + M_ILD(REG_ITMP1, REG_SP, s1); + M_IST(REG_ITMP1, REG_SP, s2); } } } - /* put class into second argument register */ + /* Handle native Java methods. */ - if (m->flags & ACC_STATIC) { - disp = dseg_add_address(cd, m->class); - M_DSEG_LOAD(REG_A1, disp); - } + if (m->flags & ACC_NATIVE) { + /* put class into second argument register */ - /* put env into first argument register */ + if (m->flags & ACC_STATIC) + M_MOV(REG_A1, REG_ITMP3); - disp = dseg_add_address(cd, _Jv_env); - M_DSEG_LOAD(REG_A0, disp); + /* put env into first argument register */ - /* do the native function call */ + disp = dseg_add_address(cd, VM_get_jnienv()); + M_DSEG_LOAD(REG_A0, disp); + } + + /* Call the native function. */ - M_DSEG_BRANCH(funcdisp); + disp = dseg_add_functionptr(cd, f); + M_DSEG_BRANCH(disp); /* recompute pv */ /* TODO: this is only needed because of the tracer ... do we @@ -3078,7 +3007,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* this depends on gcc; it is independent from our ENABLE_SOFTFLOAT define */ if (md->returntype.type != TYPE_VOID && IS_FLT_DBL_TYPE(md->returntype.type)) { #if 0 && !defined(NDEBUG) - dolog("NATIVESTUB that returns float or double (%s.%s)", m->class->name->text, m->name->text); + dolog("NATIVESTUB that returns float or double (%s.%s)", m->clazz->name->text, m->name->text); #endif /* we cannot use this macro, since it is not defined in ENABLE_SOFTFLOAT */ /* M_CAST_FLT_TO_INT_TYPED(md->returntype.type, REG_FRESULT, REG_RESULT_TYPED(md->returntype.type)); */ @@ -3102,7 +3031,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_STMFD(BITMASK_RESULT, REG_SP); - M_ADD_IMM(REG_A0, REG_SP, 2*4 + cd->stackframesize * 4 - SIZEOF_VOID_P); + M_ADD_IMM(REG_A0, REG_SP, 2*4); + M_MOV(REG_A1, REG_PV); disp = dseg_add_functionptr(cd, codegen_finish_native_call); M_DSEG_BRANCH(disp); s1 = (s4) (cd->mcodeptr - cd->mcodebase); @@ -3111,9 +3041,20 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_MOV(REG_ITMP1_XPTR, REG_RESULT); M_LDMFD(BITMASK_RESULT, REG_SP); +#if defined(ENABLE_GC_CACAO) + /* restore callee saved int registers from stackframeinfo (GC might have */ + /* modified them during a collection). */ + + disp = cd->stackframesize - SIZEOF_VOID_P - sizeof(stackframeinfo_t) + + OFFSET(stackframeinfo_t, intregs); + + for (i = 0; i < INT_SAV_CNT; i++) + M_LDR_INTERN(abi_registers_integer_saved[i], REG_SP, disp + i * 4); +#endif + /* finish stub code, but do not yet return to caller */ - M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize - 1); + M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - 1); M_LDMFD(1<