X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fm68k%2Fcodegen.c;h=342baca4614ebfa059a8ff17fe2b087f8cb6e395;hb=b6fbb1958c8971b06e87ea3c37be0deaff131768;hp=687901b970d8dd4c067c825c7672cc962ec02c12;hpb=139ea04e747d8216b123d58e6309fbab2e02c99b;p=cacao.git diff --git a/src/vm/jit/m68k/codegen.c b/src/vm/jit/m68k/codegen.c index 687901b97..342baca46 100644 --- a/src/vm/jit/m68k/codegen.c +++ b/src/vm/jit/m68k/codegen.c @@ -22,14 +22,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: codegen.c 7564 2007-03-23 23:36:17Z twisti $ - */ #include "config.h" #include +#include #include "md-abi.h" #include "md-os.h" @@ -40,6 +39,7 @@ #include "mm/memory.h" #include "native/jni.h" +#include "native/localref.h" #include "native/native.h" #include "threads/lock-common.h" @@ -55,6 +55,7 @@ #include "vm/jit/dseg.h" #include "vm/jit/emit-common.h" #include "vm/jit/jit.h" +#include "vm/jit/abi.h" #include "vm/jit/parse.h" #include "vm/jit/patcher.h" #include "vm/jit/reg.h" @@ -109,17 +110,19 @@ bool codegen_emit(jitdata *jd) savedregs_num += (INT_SAV_CNT - rd->savintreguse); savedregs_num += (ADR_SAV_CNT - rd->savadrreguse); - savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2; + savedregs_num += (FLT_SAV_CNT - rd->savfltreguse); cd->stackframesize = rd->memuse + savedregs_num; - /* we always add 3 words, - * 1 word the lock word, which may be unused and resides @ rd->memuse * 4 - * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 4 + 4 + /* we always add 2 stack slots. + * 1 word the lock word, which may be unused and resides @ rd->memuse * 8 + * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8 * on the other hand we could use 2 words when a builtin returns a doulbe which are * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd - * so we always _need_ at least 2 words, and this keeps the code simple */ - cd->stackframesize += 3; + * so we always _need_ at least 2 slots, and this keeps the code simple */ + cd->stackframesize += 2; + + cd->stackframesize *= 8; /* we use 8 byte stack slots */ #if 0 #if defined(ENABLE_THREADS) @@ -136,10 +139,10 @@ bool codegen_emit(jitdata *jd) /* 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) if (checksync && (m->flags & ACC_SYNCHRONIZED)) - (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync */ + (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8);/* IsSync */ else #endif (void) dseg_add_unique_s4(cd, 0); /* IsSync */ @@ -169,19 +172,19 @@ bool codegen_emit(jitdata *jd) emit_verbosecall_enter(jd); #endif /* create stack frame */ - M_AADD_IMM(-(cd->stackframesize*4), REG_SP); + M_AADD_IMM(-(cd->stackframesize), REG_SP); /* save used callee saved registers */ p = cd->stackframesize; for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) { - p--; M_IST(rd->savintregs[i], REG_SP, p*4); + p-=8; M_IST(rd->savintregs[i], REG_SP, p); } for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) { - p--; M_AST(rd->savadrregs[i], REG_SP, p*4); + p-=8; M_AST(rd->savadrregs[i], REG_SP, p); } #if !defined(ENABLE_SOFTFLOAT) for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) { - p-=2; M_FSTORE(rd->savfltregs[i], REG_SP, p*4); + p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p); } #else assert(FLT_SAV_CNT == 0); @@ -214,22 +217,17 @@ bool codegen_emit(jitdata *jd) case TYPE_INT: if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */ if (IS_2_WORD_TYPE(t)) { - M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } else { - M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } } else { /* stack arg -> spilled */ -#if 1 - M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4); + M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4); + M_IST(REG_ITMP1, REG_SP, var->vv.regoff); if (IS_2_WORD_TYPE(t)) { - M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4 + 4); - M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4); + M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4); + M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4); } -#else - /* Reuse Memory Position on Caller Stack */ - var->vv.regoff = cd->stackframesize + s1; -#endif } break; #if !defined(ENABLE_SOFTFLOAT) @@ -237,37 +235,27 @@ bool codegen_emit(jitdata *jd) case TYPE_DBL: if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */ if (IS_2_WORD_TYPE(t)) { - M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } else { - M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } } else { /* stack-arg -> spilled */ -#if 1 if (IS_2_WORD_TYPE(t)) { - M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4); + M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4); + M_DST(REG_FTMP1, REG_SP, var->vv.regoff); } else { - M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4); + M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4); + M_FST(REG_FTMP1, REG_SP, var->vv.regoff); } -#else - /* Reuse Memory Position on Caller Stack */ - var->vv.regoff = cd->stackframesize + s1; -#endif } break; #endif /* SOFTFLOAT */ case TYPE_ADR: if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */ - M_ALD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } else { /* stack-arg -> spilled */ -#if 1 - M_ALD(REG_ATMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_AST(REG_ATMP1, REG_SP, var->vv.regoff * 4); -#else - /* Reuse Memory Position on Caller Stack */ - var->vv.regoff = cd->stackframesize + s1; -#endif + M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4); + M_AST(REG_ATMP1, REG_SP, var->vv.regoff); } break; default: assert(0); @@ -281,13 +269,13 @@ bool codegen_emit(jitdata *jd) M_AMOV_IMM((&m->class->object.header), REG_ATMP1); } else { /* for non-static case the first arg is the object */ - M_ALD(REG_ATMP1, REG_SP, cd->stackframesize*4 + 4); + M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4); M_ATST(REG_ATMP1); M_BNE(2); M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER); } - M_AST(REG_ATMP1, REG_SP, rd->memuse * 4); + M_AST(REG_ATMP1, REG_SP, rd->memuse * 8); M_AST(REG_ATMP1, REG_SP, 0 * 4); M_JSR_IMM(LOCK_monitor_enter); } @@ -1128,21 +1116,27 @@ bool codegen_emit(jitdata *jd) /* MEMORY *************************************************************/ - case ICMD_GETSTATIC: - if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + + case ICMD_GETSTATIC: /* ... ==> ..., value */ + + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; - codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0); - } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; + disp = 0; + codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0); + } + else { + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; + disp = (intptr_t) fi->value; + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { - codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0); + codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, + 0); } - - disp = (ptrint) &(fi->value); } + M_AMOV_IMM(disp, REG_ATMP1); switch (fieldtype) { #if defined(ENABLE_SOFTFLOAT) @@ -1182,15 +1176,18 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; + disp = 0; codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0); - } else { + } + else { fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = &(fi->value); + disp = (intptr_t) fi->value; if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) - codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0); + codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, + 0); } M_AMOV_IMM(disp, REG_ATMP1); @@ -1340,7 +1337,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ATMP1); 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; @@ -1351,7 +1348,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1368,7 +1365,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1385,7 +1382,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); @@ -1403,7 +1400,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1419,7 +1416,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP1); M_ISSL_IMM(3, REG_ITMP1); - M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1); + M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP1, REG_ATMP1); /* implicit null-pointer check */ @@ -1433,7 +1430,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1453,7 +1450,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(3, REG_ITMP2); - M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1474,7 +1471,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); @@ -1490,7 +1487,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1504,7 +1501,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1518,7 +1515,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1532,7 +1529,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1546,7 +1543,7 @@ bool codegen_emit(jitdata *jd) M_INTMOVE(s2, REG_ITMP1); M_ISSL_IMM(3, REG_ITMP1); - M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1); + M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP1, REG_ATMP1); /* implicit null-pointer check */ @@ -1560,7 +1557,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1579,7 +1576,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(3, REG_ITMP2); - M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1613,7 +1610,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ATMP2); M_INTMOVE(s2, REG_ITMP1); M_ISSL_IMM(2, REG_ITMP1); - M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP1); + M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP1, REG_ATMP1); /* implicit null-pointer check */ @@ -1624,6 +1621,8 @@ bool codegen_emit(jitdata *jd) /* METHOD INVOCATION *********************************************************/ case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */ + REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr); + bte = iptr->sx.s23.s3.bte; md = bte->md; goto gen_method; @@ -1663,27 +1662,27 @@ bool codegen_emit(jitdata *jd) #endif case TYPE_LNG: d = emit_load(jd, iptr, var, REG_ITMP12_PACKED); - M_LST(d, REG_SP, md->params[s3].regoff*4); + M_LST(d, REG_SP, md->params[s3].regoff); break; #if defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #endif case TYPE_INT: d = emit_load(jd, iptr, var, REG_ITMP1); - M_IST(d, REG_SP, md->params[s3].regoff*4); + M_IST(d, REG_SP, md->params[s3].regoff); break; case TYPE_ADR: d = emit_load(jd, iptr, var, REG_ATMP1); - M_AST(d, REG_SP, md->params[s3].regoff*4); + M_AST(d, REG_SP, md->params[s3].regoff); break; #if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: d = emit_load(jd, iptr, var, REG_FTMP1); - M_FST(d, REG_SP, md->params[s3].regoff*4); + M_FST(d, REG_SP, md->params[s3].regoff); break; case TYPE_DBL: d = emit_load(jd, iptr, var, REG_FTMP1); - M_DST(d, REG_SP, md->params[s3].regoff*4); + M_DST(d, REG_SP, md->params[s3].regoff); break; #endif default: @@ -1733,7 +1732,7 @@ bool codegen_emit(jitdata *jd) /* load object pointer (==argument 0) */ M_ALD(REG_ATMP1, REG_SP, 0); /* implicit null-pointer check */ - M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ATMP3, REG_METHODPTR, s1); /* generate the actual call */ M_JSR(REG_ATMP3); @@ -1752,7 +1751,7 @@ bool codegen_emit(jitdata *jd) M_ALD(REG_ATMP1, REG_SP, 0); /* implicit null-pointer check */ - M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl)); M_ALD(REG_METHODPTR, REG_METHODPTR, s1); M_ALD(REG_ATMP3, REG_METHODPTR, s2); @@ -1765,6 +1764,7 @@ bool codegen_emit(jitdata *jd) } /* switch (iptr->opc) */ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); + REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr); /* store return value */ d = md->returntype.type; @@ -1887,7 +1887,7 @@ nowperformreturn: #if defined(ENABLE_THREADS) /* call lock_monitor_exit */ if (checksync && (m->flags & ACC_SYNCHRONIZED)) { - M_ILD(REG_ITMP3, REG_SP, rd->memuse * 4); + M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8); /* we need to save the proper return value */ /* we do not care for the long -> doubel convert space here */ @@ -1896,21 +1896,21 @@ nowperformreturn: case ICMD_DRETURN: #endif case ICMD_LRETURN: - M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4); + M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8); break; #if defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: #endif case ICMD_IRETURN: case ICMD_ARETURN: - M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4); + M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8); break; #if !defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: - M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4); + M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; case ICMD_DRETURN: - M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4); + M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; #endif } @@ -1925,21 +1925,21 @@ nowperformreturn: case ICMD_DRETURN: #endif case ICMD_LRETURN: - M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4); + M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8); break; #if defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: #endif case ICMD_IRETURN: case ICMD_ARETURN: - M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4); + M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8); break; #if !defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: - M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4); + M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; case ICMD_DRETURN: - M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4); + M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; #endif } @@ -1960,18 +1960,18 @@ nowperformreturn: /* restore saved registers */ for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) { - p--; M_ILD(rd->savintregs[i], REG_SP, p * 4); + p-=8; M_ILD(rd->savintregs[i], REG_SP, p); } for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) { - p--; M_ALD(rd->savadrregs[i], REG_SP, p*4); + p-=8; M_ALD(rd->savadrregs[i], REG_SP, p); } #if !defined(ENABLE_SOFTFLOAT) for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) { - p -= 2; M_FLOAD(rd->savfltregs[i], REG_SP, p * 4); + p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p); } #endif /* deallocate stack */ - M_AADD_IMM(cd->stackframesize*4, REG_SP); + M_AADD_IMM(cd->stackframesize, REG_SP); M_RET; } break; @@ -2040,7 +2040,7 @@ nowperformreturn: emit_label_beq(cd, BRANCH_LABEL_3); } - M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength)); M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */ M_ITST(REG_ITMP3); @@ -2070,7 +2070,7 @@ nowperformreturn: emit_label_beq(cd, BRANCH_LABEL_5); } - M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl)); CODEGEN_CRITICAL_SECTION_START; @@ -2160,7 +2160,7 @@ nowperformreturn: emit_label_beq(cd, BRANCH_LABEL_3); } - M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength)); M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */ @@ -2191,7 +2191,7 @@ nowperformreturn: emit_label_beq(cd, BRANCH_LABEL_5); } - M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl)); CODEGEN_CRITICAL_SECTION_START; @@ -2359,8 +2359,21 @@ nowperformreturn: exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc); return false; } /* switch */ - M_TPF; + /* M_TPF; */ /* nop after each ICMD */ } /* for each instruction */ + + /* At the end of a basic block we may have to append some nops, + because the patcher stub calling code might be longer than the + actual instruction. So codepatching does not change the + following block unintentionally. */ + + if (cd->mcodeptr < cd->lastmcodeptr) { + while (cd->mcodeptr < cd->lastmcodeptr) { + M_NOP; + } + } + + } /* if (btpre->flags >= BBREACHED) */ } /* for each basic block */ @@ -2368,7 +2381,6 @@ nowperformreturn: /* generate stubs */ emit_patcher_stubs(jd); - REPLACEMENT_EMIT_STUBS(jd); return true; } @@ -2397,6 +2409,169 @@ void codegen_emit_stub_compiler(jitdata *jd) M_JMP(REG_ATMP3); } +/* codegen_emit_stub_builtin *************************************************** + + Creates a stub routine which calls a builtin function. + +*******************************************************************************/ + +void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte) +{ + codeinfo *code; + codegendata *cd; + methoddesc *md; + s4 i; + s4 disp; + s4 s1, s2; + + /* get required compiler data */ + code = jd->code; + cd = jd->cd; + + /* set some variables */ + md = bte->md; + + /* calculate stack frame size */ + cd->stackframesize = + sizeof(stackframeinfo) / SIZEOF_VOID_P + + 4; /* 4 arguments or return value */ + + /* 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, 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_AADD_IMM(-(cd->stackframesize*4), REG_SP); + +#if defined(ENABLE_GC_CACAO) + /* Save callee saved integer registers in stackframeinfo (GC may + need to recover them during a collection). */ + + disp = cd->stackframesize * 4 - sizeof(stackframeinfo) + + OFFSET(stackframeinfo, adrregs); + + for (i = 0; i < ADR_SAV_CNT; i++) + M_AST(abi_registers_address_saved[i], REG_SP, disp + i * 4); +#endif + + /* create dynamic stack info */ + + M_AMOV(REG_SP, REG_ATMP1); + M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1); + M_AST(REG_ATMP1, REG_SP, 0 * 4); /* datasp */ + + M_AMOV_IMM(0, REG_ATMP1); /* we need pv patched in */ + dseg_adddata(cd); /* this does the trick */ + M_AST(REG_ATMP1, REG_SP, 1 * 4); /* pv */ + + M_AMOV(REG_SP, REG_ATMP1); + M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ATMP1); + M_AST(REG_ATMP1, REG_SP, 2 * 4); /* sp */ + + M_ALD(REG_ATMP3, REG_SP, cd->stackframesize * 4); + M_AST(REG_ATMP3, REG_SP, 3 * 4); /* ra */ + + M_JSR_IMM(codegen_stub_builtin_enter); + + /* builtins are allowed to have 4 arguments max */ + + assert(md->paramcount <= 4); + + /* copy arguments into new stackframe */ + + for (i = 0; i < md->paramcount; i++) { + if (!md->params[i].inmemory) { + log_text("No integer argument registers available!"); + assert(0); + + } else { /* float/double in memory can be copied like int/longs */ + s1 = md->params[i].regoff + cd->stackframesize * 4 + 4; + s2 = md->params[i].regoff; + + M_ILD(REG_ITMP1, REG_SP, s1); + M_IST(REG_ITMP1, REG_SP, s2); + if (IS_2_WORD_TYPE(md->paramtypes[i].type)) { + M_ILD(REG_ITMP1, REG_SP, s1 + 4); + M_IST(REG_ITMP1, REG_SP, s2 + 4); + } + + } + } + + /* call the builtin function */ + + M_AMOV_IMM(bte->fp, REG_ATMP3); + M_JSR(REG_ATMP3); + + /* save return value */ + switch (md->returntype.type) { + case TYPE_VOID: break; + + /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */ + case TYPE_DBL: + case TYPE_LNG: + M_IST(REG_D1, REG_SP, 2 * 4); + /* fall through */ + + case TYPE_FLT: + case TYPE_INT: + case TYPE_ADR: + M_IST(REG_D0, REG_SP, 1 * 4); + break; + + default: assert(0); + } + + /* remove native stackframe info */ + + M_AMOV(REG_SP, REG_ATMP1); + M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1); + M_AST(REG_ATMP1, REG_SP, 0 * 4); + + M_JSR_IMM(codegen_stub_builtin_exit); + + /* restore return value */ + switch (md->returntype.type) { + case TYPE_VOID: break; + + case TYPE_DBL: + case TYPE_LNG: + M_ILD(REG_D1, REG_SP, 2 * 4); + /* fall through */ + + case TYPE_FLT: + case TYPE_INT: + case TYPE_ADR: + M_ILD(REG_D0, REG_SP, 1 * 4); + break; + + default: assert(0); + } + +#if defined(ENABLE_GC_CACAO) + /* Restore callee saved integer registers from stackframeinfo (GC + might have modified them during a collection). */ + + disp = cd->stackframesize * 4 - sizeof(stackframeinfo) + + OFFSET(stackframeinfo, adrregs); + + for (i = 0; i < ADR_SAV_CNT; i++) + M_ALD(abi_registers_address_saved[i], REG_SP, disp + i * 4); +#endif + + /* remove stackframe */ + M_AADD_IMM(cd->stackframesize * 4, REG_SP); + M_RET; +} + + + /* codegen_emit_stub_native **************************************************** @@ -2490,8 +2665,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* all arguments via stack */ assert(md->params[i].inmemory); - s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4; - s2 = nmd->params[j].regoff * 4; + s1 = md->params[i].regoff + cd->stackframesize * 4 + 4; + s2 = nmd->params[j].regoff; /* simply copy argument stack */ M_ILD(REG_ITMP1, REG_SP, s1);