X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc64%2Fcodegen.c;h=be082d70c49bf502eccad0ffd882e6ebecb2483a;hb=7659949229c634784f7d27aa8b679fdd4c8351ab;hp=937def193a83c62b6891acb3791bdabc85083d9b;hpb=10d094d20ddbce4a1a66493b286a14eda140d5bf;p=cacao.git diff --git a/src/vm/jit/powerpc64/codegen.c b/src/vm/jit/powerpc64/codegen.c index 937def193..be082d70c 100644 --- a/src/vm/jit/powerpc64/codegen.c +++ b/src/vm/jit/powerpc64/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/powerpc64/codegen.c - machine code generator for 64-bit PowerPC - 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,14 +20,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: codegen.c 7944 2007-05-23 14:15:00Z tbfg $ - */ #include "config.h" #include +#include #include #include @@ -42,6 +39,7 @@ #include "mm/memory.h" +#include "native/localref.h" #include "native/native.h" #include "threads/lock-common.h" @@ -54,17 +52,18 @@ #include "vm/jit/abi.h" #include "vm/jit/abi-asm.h" -#include "vm/jit/md.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/linenumbertable.h" #include "vm/jit/parse.h" -#include "vm/jit/patcher.h" +#include "vm/jit/patcher-common.h" #include "vm/jit/reg.h" #include "vm/jit/replace.h" #include "vm/jit/stacktrace.h" +#include "vm/jit/trap.h" #include "vmcore/loader.h" #include "vmcore/options.h" @@ -91,7 +90,6 @@ bool codegen_emit(jitdata *jd) varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; u2 currentline; methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ unresolved_method *um; @@ -111,9 +109,11 @@ bool codegen_emit(jitdata *jd) /* prevent compiler warnings */ - d = 0; - lm = NULL; + d = 0; + lm = NULL; + um = NULL; bte = NULL; + uf = NULL; { s4 i, p, t, l; @@ -133,7 +133,7 @@ bool codegen_emit(jitdata *jd) /* monitor_exit. The stack position for the argument can not be shared */ /* with place to save the return register on PPC64, since both values */ /* reside in R3 */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* reserve 2 slots for long/double return values for monitorexit */ cd->stackframesize += 2; } @@ -154,39 +154,21 @@ 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 */ - 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, INT_SAV_CNT - rd->savintreguse); /* IntSave */ - (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ + code->synchronizedoffset = rd->memuse * 8; - dseg_addlinenumbertablesize(cd); + /* REMOVEME: We still need it for exception handling in assembler. */ - (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */ + if (code_is_leafmethod(code)) + (void) dseg_add_unique_s4(cd, 1); + else + (void) dseg_add_unique_s4(cd, 0); - /* create exception table */ + (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ + (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ - 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 (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { M_MFLR(REG_ZERO); M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET); } @@ -225,13 +207,13 @@ bool codegen_emit(jitdata *jd) if (!IS_INMEMORY(var->flags)) M_INTMOVE(s1, var->vv.regoff); else - M_LST(s1, REG_SP, var->vv.regoff * 8); + M_LST(s1, REG_SP, var->vv.regoff); } else { if (!IS_INMEMORY(var->flags)) - M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); + M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); else - var->vv.regoff = cd->stackframesize + s1; + var->vv.regoff = cd->stackframesize * 8 + s1; } } else { @@ -239,17 +221,17 @@ bool codegen_emit(jitdata *jd) if (!IS_INMEMORY(var->flags)) M_FLTMOVE(s1, var->vv.regoff); else - M_DST(s1, REG_SP, var->vv.regoff * 8); + M_DST(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) * 8); + M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); else - M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); + M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1); } else - var->vv.regoff = cd->stackframesize + s1; + var->vv.regoff = cd->stackframesize * 8 + s1; } } } @@ -258,7 +240,7 @@ bool codegen_emit(jitdata *jd) #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stackoffset for argument used for LOCK_monitor_exit */ s1 = rd->memuse; @@ -286,13 +268,13 @@ bool codegen_emit(jitdata *jd) /* get or test the lock object */ if (m->flags & ACC_STATIC) { - p = dseg_add_address(cd, &m->class->object.header); + p = dseg_add_address(cd, &m->clazz->object.header); M_ALD(REG_A0, REG_PV, p); } else { M_TST(REG_A0); M_BNE(1); - M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER); + M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException); } M_AST(REG_A0, REG_SP, s1 * 8); /* rd->memuse * 8 */ @@ -316,9 +298,9 @@ bool codegen_emit(jitdata *jd) #if !defined (NDEBUG) if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) emit_verbosecall_enter(jd); +#endif } -#endif /* end of header generation */ @@ -386,7 +368,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; } @@ -406,14 +388,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 */ @@ -462,7 +444,7 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { disp = dseg_add_unique_address(cd, iptr->sx.val.c.ref); - codegen_addpatchref(cd, PATCHER_aconst, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.val.c.ref, disp); } else { @@ -1200,7 +1182,6 @@ bool codegen_emit(jitdata *jd) case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */ case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */ - 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); @@ -1229,109 +1210,8 @@ bool codegen_emit(jitdata *jd) M_IADD_IMM(REG_ZERO, -1, d); emit_store_dst(jd, iptr, d); break; - - case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPEQ: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_beq(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPNE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_bne(cd, iptr->dst.block); - break; - - - case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_LT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_blt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_GT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_bgt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_LE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_ble(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_GE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_bge(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_LT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_blt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_GT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_bgt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_LE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_ble(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_GE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_bge(cd, iptr->dst.block); - break; - + /* memory operations **************************************************/ case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */ @@ -1339,7 +1219,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_nullpointer_check(cd, iptr, s1); - M_ILD(d, s1, OFFSET(java_arrayheader, size)); + M_ILD(d, s1, OFFSET(java_array_t, size)); emit_store_dst(jd, iptr, d); break; @@ -1349,7 +1229,7 @@ bool codegen_emit(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); - M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2); + M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_LBZX(d, s1, REG_ITMP2); M_BSEXT(d, d); @@ -1363,7 +1243,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_SLL_IMM(s2, 1, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_LHZX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); @@ -1376,7 +1256,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_SLL_IMM(s2, 1, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_LHAX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); @@ -1389,7 +1269,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_SLL_IMM(s2, 2, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_LWAX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); @@ -1404,7 +1284,7 @@ bool codegen_emit(jitdata *jd) M_SLL_IMM(s2, 3, REG_ITMP2); M_IADD(s1, REG_ITMP2, REG_ITMP2); /* implicit null-pointer check */ - M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0])); + M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray_t, data[0])); emit_store_dst(jd, iptr, d); break; @@ -1415,7 +1295,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_SLL_IMM(s2, 2, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_LFSX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); @@ -1428,7 +1308,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_SLL_IMM(s2, 3, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_LFDX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); @@ -1441,7 +1321,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_SLL_IMM(s2, 3, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_ALDX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); @@ -1454,7 +1334,7 @@ bool codegen_emit(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); - M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2); + M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_STBX(s3, s1, REG_ITMP2); break; @@ -1466,7 +1346,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_SLL_IMM(s2, 1, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_STHX(s3, s1, REG_ITMP2); break; @@ -1478,7 +1358,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_SLL_IMM(s2, 1, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2); M_STHX(s3, s1, REG_ITMP2); break; @@ -1489,7 +1369,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_SLL_IMM(s2, 2, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_STWX(s3, s1, REG_ITMP2); break; @@ -1501,7 +1381,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_SLL_IMM(s2, 3, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_LSTX(s3, s1, REG_ITMP2); break; @@ -1513,7 +1393,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_FTMP3); M_SLL_IMM(s2, 2, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_STFSX(s3, s1, REG_ITMP2); break; @@ -1525,7 +1405,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_FTMP3); M_SLL_IMM(s2, 3, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_STFDX(s3, s1, REG_ITMP2); break; @@ -1537,7 +1417,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, 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_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ M_MTCTR(REG_ITMP3); @@ -1546,13 +1426,13 @@ bool codegen_emit(jitdata *jd) M_INTMOVE(s3, REG_A1); M_JSR; - 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); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_SLL_IMM(s2, 3, REG_ITMP2); - M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2); + M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2); /* implicit null-pointer check */ M_ASTX(s3, s1, REG_ITMP2); break; @@ -1561,22 +1441,21 @@ bool codegen_emit(jitdata *jd) case ICMD_GETSTATIC: /* ... ==> ..., value */ if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - 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, + patcher_add_patch_ref(jd, PATCHER_get_putstatic, iptr->sx.s23.s3.uf, disp); - } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + } + 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_addpatchref(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); } } @@ -1610,21 +1489,20 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - 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, + patcher_add_patch_ref(jd, PATCHER_get_putstatic, iptr->sx.s23.s3.uf, disp); - } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + } + 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_addpatchref(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); } } @@ -1659,15 +1537,16 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - uf = iptr->sx.s23.s3.uf; + uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; - disp = 0; + disp = 0; - codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); - } else { - fi = iptr->sx.s23.s3.fmiref->p.field; + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); + } + else { + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = fi->offset; + disp = fi->offset; } /* implicit null-pointer check */ @@ -1718,7 +1597,7 @@ bool codegen_emit(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); } @@ -1752,7 +1631,7 @@ bool codegen_emit(jitdata *jd) #ifdef ENABLE_VERIFIER 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); } #endif /* ENABLE_VERIFIER */ @@ -1761,12 +1640,16 @@ bool codegen_emit(jitdata *jd) M_ALD(REG_ITMP2, REG_PV, disp); M_MTCTR(REG_ITMP2); - if (jd->isleafmethod) M_MFLR(REG_ITMP3); /* save LR */ + if (code_is_leafmethod(code)) + M_MFLR(REG_ITMP3); /* save LR */ + M_BL(0); /* get current PC */ M_MFLR(REG_ITMP2_XPC); - if (jd->isleafmethod) M_MTLR(REG_ITMP3); /* restore LR */ - M_RTS; /* jump to CTR */ + if (code_is_leafmethod(code)) + M_MTLR(REG_ITMP3); /* restore LR */ + + M_RTS; /* jump to CTR */ ALIGNCODENOP; break; @@ -1925,7 +1808,7 @@ bool codegen_emit(jitdata *jd) #ifdef ENABLE_VERIFIER 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); } #endif /* ENABLE_VERIFIER */ @@ -1953,13 +1836,12 @@ nowperformreturn: /* call trace function */ #if !defined(NDEBUG) - if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { + if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) emit_verbosecall_exit(jd); - } #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); M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ @@ -2006,7 +1888,7 @@ nowperformreturn: /* restore return address */ - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD may have a displacement overflow. */ @@ -2160,7 +2042,7 @@ gen_method: } else { s1 = emit_load(jd, iptr, var, REG_ITMP1); - M_LST(s1, REG_SP, d * 8); + M_LST(s1, REG_SP, d); } } else { @@ -2170,30 +2052,32 @@ gen_method: } else { s1 = emit_load(jd, iptr, var, REG_FTMP1); - M_DST(s1, REG_SP, d * 8); + M_DST(s1, REG_SP, d); } } } switch (iptr->opc) { case ICMD_BUILTIN: - disp = dseg_add_functionptr(cd, bte->fp); - M_ALD(REG_PV, REG_PV, disp); - M_ALD(REG_PV, REG_PV, 0); /* TOC */ + if (bte->stub == NULL) { + disp = dseg_add_functionptr(cd, bte->fp); + M_ALD(REG_PV, REG_PV, disp); + M_ALD(REG_PV, REG_PV, 0); /* TOC */ + } + else { + disp = dseg_add_functionptr(cd, bte->stub); + M_ALD(REG_PV, REG_PV, disp); + } /* generate the actual call */ - REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); M_MTCTR(REG_PV); M_JSR; REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); disp = (s4) (cd->mcodeptr - cd->mcodebase); M_MFLR(REG_ITMP1); M_LDA(REG_PV, REG_ITMP1, -disp); - - emit_exception_check(cd, iptr); break; - case ICMD_INVOKESPECIAL: emit_nullpointer_check(cd, iptr, REG_A0); /* fall through */ @@ -2202,7 +2086,7 @@ gen_method: if (lm == NULL) { disp = dseg_add_unique_address(cd, um); - codegen_addpatchref(cd, PATCHER_invokestatic_special, + patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, disp); } else { disp = dseg_add_address(cd, lm->stubroutine); @@ -2217,11 +2101,11 @@ gen_method: disp = (s4) (cd->mcodeptr - cd->mcodebase); M_MFLR(REG_ITMP1); M_LDA(REG_PV, REG_ITMP1, -disp); - break; + case ICMD_INVOKEVIRTUAL: if (lm == NULL) { - codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0); + patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0); s1 = 0; } else { s1 = OFFSET(vftbl_t, table[0]) + @@ -2229,7 +2113,7 @@ gen_method: } /* 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 */ @@ -2244,20 +2128,20 @@ gen_method: case ICMD_INVOKEINTERFACE: if (lm == NULL) { - codegen_addpatchref(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); @@ -2312,17 +2196,14 @@ gen_method: s4 superindex; if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - super = NULL; + super = NULL; superindex = 0; - } else { - super = iptr->sx.s23.s3.c.cls; + } + else { + super = iptr->sx.s23.s3.c.cls; 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 */ @@ -2332,8 +2213,8 @@ gen_method: 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); @@ -2347,7 +2228,7 @@ gen_method: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, + patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0); @@ -2356,7 +2237,7 @@ gen_method: emit_label_beq(cd, BRANCH_LABEL_3); } - 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_LDATST(REG_ITMP3, REG_ITMP3, -superindex); emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1); @@ -2380,7 +2261,7 @@ gen_method: emit_label(cd, BRANCH_LABEL_2); disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_checkcast_class, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, disp); } else { @@ -2389,9 +2270,7 @@ gen_method: emit_label_beq(cd, BRANCH_LABEL_5); } - M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); - - CODEGEN_CRITICAL_SECTION_START; + M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ALD(REG_ITMP2, REG_PV, disp); @@ -2399,8 +2278,6 @@ gen_method: M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_SUB(REG_ITMP3, REG_ITMP1, REG_ITMP3); M_EXTSW(REG_ITMP3, REG_ITMP3); } else { @@ -2409,9 +2286,6 @@ gen_method: M_EXTSW(REG_ITMP3, REG_ITMP3); M_ALD(REG_ITMP2, REG_PV, disp); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); - - CODEGEN_CRITICAL_SECTION_END; - } M_CMPU(REG_ITMP3, REG_ITMP2); emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1); @@ -2435,7 +2309,7 @@ gen_method: 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); } else { @@ -2477,22 +2351,17 @@ gen_method: { classinfo *super; - vftbl_t *supervftbl; s4 superindex; if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - super = NULL; + super = NULL; superindex = 0; } else { - super = iptr->sx.s23.s3.c.cls; + super = iptr->sx.s23.s3.c.cls; 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); if (s1 == d) { @@ -2509,7 +2378,7 @@ gen_method: 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); M_ILD(REG_ITMP3, REG_PV, disp); @@ -2521,7 +2390,7 @@ gen_method: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, + patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0); @@ -2530,7 +2399,7 @@ gen_method: emit_label_beq(cd, BRANCH_LABEL_3); } - 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_LDATST(REG_ITMP3, REG_ITMP3, -superindex); M_BLE(4); @@ -2556,7 +2425,7 @@ gen_method: emit_label(cd, BRANCH_LABEL_2); disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_instanceof_class, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, disp); @@ -2566,17 +2435,13 @@ gen_method: emit_label_beq(cd, BRANCH_LABEL_5); } - 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); - CODEGEN_CRITICAL_SECTION_START; - 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)); - CODEGEN_CRITICAL_SECTION_END; - M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); M_EXTSW(REG_ITMP1, REG_ITMP1); M_CMPU(REG_ITMP1, REG_ITMP2); @@ -2628,7 +2493,7 @@ gen_method: 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); } else { disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); @@ -2671,12 +2536,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 */ @@ -2684,48 +2546,22 @@ gen_method: } -/* codegen_emit_stub_compiler ************************************************** - - Emits a stub routine which calls the compiler. - -*******************************************************************************/ - -void codegen_emit_stub_compiler(jitdata *jd) -{ - methodinfo *m; - codegendata *cd; - - /* get required compiler data */ - - m = jd->m; - cd = jd->cd; - - /* code for the stub */ - - M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); - M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); - M_MTCTR(REG_PV); - M_RTS; -} - - /* codegen_emit_stub_native **************************************************** Emits a stub routine which calls a native method. *******************************************************************************/ -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; methoddesc *md; - s4 nativeparams; s4 i, j; s4 t; - s4 s1, s2, disp; - s4 funcdisp; + int s1, s2; + int disp; /* get required compiler data */ @@ -2733,15 +2569,18 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) code = jd->code; cd = jd->cd; + /* Sanity check. */ + + assert(!code_is_leafmethod(code)); + /* set some variables */ md = m->parseddesc; - nativeparams = (m->flags & ACC_STATIC) ? 2 : 1; /* calculate stackframe size */ cd->stackframesize = - sizeof(stackframeinfo) / SIZEOF_VOID_P + + sizeof(stackframeinfo_t) / SIZEOF_VOID_P + sizeof(localref_table) / SIZEOF_VOID_P + 4 + /* 4 stackframeinfo arguments (darwin)*/ nmd->paramcount + @@ -2751,14 +2590,11 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* create method header */ - (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 */ + (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); /* IsLeaf */ + (void) dseg_add_unique_s4(cd, 0); /* IntSave */ + (void) dseg_add_unique_s4(cd, 0); /* FltSave */ /* generate code */ @@ -2766,89 +2602,64 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET); M_STDU(REG_SP, REG_SP, -(cd->stackframesize * 8)); -#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(WITH_STATIC_CLASSPATH) - if (f == NULL) { - codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp); - } -#endif - /* save integer and float argument registers */ - j = 0; - for (i = 0; i < md->paramcount; i++) { - t = md->paramtypes[i].type; - - if (IS_INT_LNG_TYPE(t)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_LST(s1, REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8); - j++; - } - } - } + if (!md->params[i].inmemory) { + s1 = md->params[i].regoff; - for (i = 0; i < md->paramcount; i++) { - if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_DST(s1, REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8); - j++; + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: + M_LST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; } } } /* create native stack info */ - M_AADD_IMM(REG_SP, cd->stackframesize * 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 * 8 + LA_LR_OFFSET); disp = dseg_add_functionptr(cd, codegen_start_native_call); - M_ALD(REG_ITMP1, REG_PV, disp); M_ALD(REG_ITMP1, REG_ITMP1, 0); /* TOC */ M_MTCTR(REG_ITMP1); M_JSR; - /* restore integer and float argument registers */ + /* remember class argument */ - j = 0; + if (m->flags & ACC_STATIC) + M_MOV(REG_RESULT, REG_ITMP3); - for (i = 0; i < md->paramcount; i++) { - t = md->paramtypes[i].type; - - if (IS_INT_LNG_TYPE(t)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_LLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); - j++; - } - } - } + /* restore integer and float argument registers */ for (i = 0; i < md->paramcount; i++) { - if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_DLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); - j++; + if (!md->params[i].inmemory) { + s1 = md->params[i].regoff; + + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: + M_LLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; } } } /* 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->paramtypes[i].type; if (IS_INT_LNG_TYPE(t)) { @@ -2859,14 +2670,14 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) if (!nmd->params[j].inmemory) M_INTMOVE(s1, s2); else - M_LST(s1, REG_SP, s2 * 8); + M_LST(s1, REG_SP, s2); } else { - s1 = md->params[i].regoff + cd->stackframesize; + s1 = md->params[i].regoff + cd->stackframesize * 8; s2 = nmd->params[j].regoff; - 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 { @@ -2874,36 +2685,39 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) argument registers keep unchanged. */ if (md->params[i].inmemory) { - s1 = md->params[i].regoff + cd->stackframesize; + s1 = md->params[i].regoff + cd->stackframesize * 8; s2 = nmd->params[j].regoff; - M_DLD(REG_FTMP1, REG_SP, s1 * 8); + M_DLD(REG_FTMP1, REG_SP, s1); if (IS_2_WORD_TYPE(t)) - M_DST(REG_FTMP1, REG_SP, s2 * 8); + M_DST(REG_FTMP1, REG_SP, s2); else - M_FST(REG_FTMP1, REG_SP, s2 * 8 + 4); + M_FST(REG_FTMP1, REG_SP, s2 + 4); } } } - /* put class into second argument register */ + /* Handle native Java methods. */ - if (m->flags & ACC_STATIC) { - disp = dseg_add_unique_address(cd, m->class); - M_ALD(REG_A1, REG_PV, 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_ITMP3, REG_A1); - disp = dseg_add_unique_address(cd, _Jv_env); - M_ALD(REG_A0, REG_PV, disp); + /* put env into first argument register */ - /* generate the actual native call */ + disp = dseg_add_unique_address(cd, _Jv_env); + M_ALD(REG_A0, REG_PV, disp); + } + + /* Call the native function. */ /* native functions have a different TOC for sure */ M_AST(REG_TOC, REG_SP, 40); /* save old TOC */ - M_ALD(REG_ITMP3, REG_PV, funcdisp); + disp = dseg_add_functionptr(cd, f); + M_ALD(REG_ITMP3, REG_PV, disp); M_ALD(REG_TOC, REG_ITMP3, 8); /* load TOC from func. descriptor */ M_ALD(REG_ITMP3, REG_ITMP3, 0); M_MTCTR(REG_ITMP3); @@ -2914,22 +2728,17 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) if (md->returntype.type != TYPE_VOID) { if (IS_INT_LNG_TYPE(md->returntype.type)) { - M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); + M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } else { - M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); + M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } } - /* print call trace */ -#if ! defined(NDEBGUU) - if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { - emit_verbosecall_exit(jd); - } -#endif /* remove native stackframe info */ - M_AADD_IMM(REG_SP, cd->stackframesize * 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_ITMP1, REG_PV, disp); M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */ @@ -2941,14 +2750,10 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) if (md->returntype.type != TYPE_VOID) { if (IS_INT_LNG_TYPE(md->returntype.type)) { - M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); + M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } else { -/* if (IS_2_WORD_TYPE(md->returntype.type)) */ - M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); -/* else - M_FLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); F XXX - */ + M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } } @@ -2971,15 +2776,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_ALD(REG_ITMP3, REG_PV, disp); M_MTCTR(REG_ITMP3); M_RTS; - - /* generate patcher stub call code */ - - emit_patcher_stubs(jd); } - - /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where