X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc64%2Fcodegen.c;h=3df801b9bb4e8b422adae998567ceb849924505a;hb=bfb7d15b502b8170ec8a9b348c546418c0e44ace;hp=fdceaee1e3dda1147b5c34c3aca5da0971ba5cb5;hpb=de5f99d455edae3fcff3243a59bc9f8b3864d55b;p=cacao.git diff --git a/src/vm/jit/powerpc64/codegen.c b/src/vm/jit/powerpc64/codegen.c index fdceaee1e..3df801b9b 100644 --- a/src/vm/jit/powerpc64/codegen.c +++ b/src/vm/jit/powerpc64/codegen.c @@ -1,6 +1,6 @@ -/* src/vm/jit/powerpc64/codegen.c - machine code generator for 32-bit PowerPC +/* src/vm/jit/powerpc64/codegen.c - machine code generator for 64-bit PowerPC - Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, + 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 @@ -22,16 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Andreas Krall - Stefan Ring - - Changes: Christian Thalinger - Christian Ullrich - Edwin Steiner - - $Id: codegen.c 5576 2006-09-28 22:33:48Z edwin $ + $Id: codegen.c 7891 2007-05-09 16:37:20Z tbfg $ */ @@ -45,20 +36,25 @@ #include "vm/types.h" #include "md-abi.h" -#include "vm/jit/abi-asm.h" #include "vm/jit/powerpc64/arch.h" #include "vm/jit/powerpc64/codegen.h" #include "mm/memory.h" + #include "native/native.h" + +#include "threads/lock-common.h" + #include "vm/builtin.h" #include "vm/exceptions.h" #include "vm/global.h" -#include "vm/loader.h" -#include "vm/options.h" #include "vm/stringlocal.h" #include "vm/vm.h" + +#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" @@ -68,19 +64,23 @@ #include "vm/jit/patcher.h" #include "vm/jit/reg.h" #include "vm/jit/replace.h" +#include "vm/jit/stacktrace.h" + +#include "vmcore/loader.h" +#include "vmcore/options.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" #endif -/* codegen ********************************************************************* +/* codegen_emit **************************************************************** Generates machine code. *******************************************************************************/ -bool codegen(jitdata *jd) +bool codegen_emit(jitdata *jd) { methodinfo *m; codeinfo *code; @@ -88,18 +88,19 @@ bool codegen(jitdata *jd) registerdata *rd; s4 len, s1, s2, s3, d, disp; ptrint a; - s4 stackframesize; - stackptr src; varinfo *var; basicblock *bptr; instruction *iptr; - exceptiontable *ex; + exception_entry *ex; u2 currentline; methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ + unresolved_method *um; builtintable_entry *bte; methoddesc *md; - rplpoint *replacementpoint; s4 fieldtype; + s4 varindex; + unresolved_field *uf; + fieldinfo *fi; /* get required compiler data */ @@ -125,7 +126,7 @@ bool codegen(jitdata *jd) savedregs_num += (INT_SAV_CNT - rd->savintreguse); savedregs_num += (FLT_SAV_CNT - rd->savfltreguse); - stackframesize = rd->memuse + savedregs_num; + cd->stackframesize = rd->memuse + savedregs_num; #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter and Return Values to survive */ @@ -134,7 +135,7 @@ bool codegen(jitdata *jd) /* reside in R3 */ if (checksync && (m->flags & ACC_SYNCHRONIZED)) { /* reserve 2 slots for long/double return values for monitorexit */ - stackframesize += 2; + cd->stackframesize += 2; } #endif @@ -143,14 +144,15 @@ bool codegen(jitdata *jd) /* align stack to 16-bytes */ +/* FIXME */ /* if (!m->isleafmethod || opt_verbosecall) */ - stackframesize = (stackframesize + 3) & ~3; - +/* stackframesize = (stackframesize + 3) & ~3; +*/ /* else if (m->isleafmethod && (stackframesize == LA_WORD_SIZE)) */ /* stackframesize = 0; */ - (void) dseg_addaddress(cd, code); /* CodeinfoPointer */ - (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */ + (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 @@ -160,26 +162,26 @@ bool codegen(jitdata *jd) */ if (checksync && (m->flags & ACC_SYNCHRONIZED)) - (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */ + (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */ else #endif - (void) dseg_adds4(cd, 0); /* IsSync */ + (void) dseg_add_unique_s4(cd, 0); /* IsSync */ - (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */ - (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ - (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ + (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 */ dseg_addlinenumbertablesize(cd); - (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */ + (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */ /* create exception table */ - for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) { - dseg_addtarget(cd, ex->start); - dseg_addtarget(cd, ex->end); - dseg_addtarget(cd, ex->handler); - (void) dseg_addaddress(cd, ex->catchtype.any); + 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) */ @@ -189,12 +191,12 @@ bool codegen(jitdata *jd) M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET); } - if (stackframesize) - M_STDU(REG_SP, REG_SP, -stackframesize * 8); + if (cd->stackframesize) + M_STDU(REG_SP, REG_SP, -cd->stackframesize * 8); /* save return address and used callee saved registers */ - p = stackframesize; + p = cd->stackframesize; for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) { p--; M_LST(rd->savintregs[i], REG_SP, p * 8); } @@ -208,96 +210,49 @@ bool codegen(jitdata *jd) for (p = 0, l = 0; p < md->paramcount; p++) { t = md->paramtypes[p].type; - var = &(rd->locals[l][t]); + varindex = jd->local_map[l*5 + t]; l++; if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */ l++; - if (var->type < 0) + if (varindex == UNUSED) continue; - s1 = md->params[p].regoff; - if (IS_INT_LNG_TYPE(t)) { /* integer args */ - if (IS_2_WORD_TYPE(t)) - s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)], - rd->argintregs[GET_HIGH_REG(s1)]); - else - s2 = rd->argintregs[s1]; - if (!md->params[p].inmemory) { /* register arguments */ - if (!(var->flags & INMEMORY)) { /* reg arg -> register */ - M_NOP; - if (IS_2_WORD_TYPE(t)) /* FIXME, only M_INTMOVE here */ - M_LNGMOVE(s2, var->regoff); - else - M_INTMOVE(s2, var->regoff); - } else { /* reg arg -> spilled */ - if (IS_2_WORD_TYPE(t)) - M_LST(s2, REG_SP, var->regoff * 4); - else - M_IST(s2, REG_SP, var->regoff * 4); - } + var = VAR(varindex); + s1 = md->params[p].regoff; - } else { /* stack arguments */ - if (!(var->flags & INMEMORY)) { /* stack arg -> register */ - if (IS_2_WORD_TYPE(t)) - M_LLD(var->regoff, REG_SP, (stackframesize + s1) * 4); - else - M_ILD(var->regoff, REG_SP, (stackframesize + s1) * 4); - - } else { /* stack arg -> spilled */ -#if 1 - M_ILD(REG_ITMP1, REG_SP, (stackframesize + s1) * 4); - M_IST(REG_ITMP1, REG_SP, var->regoff * 4); - if (IS_2_WORD_TYPE(t)) { - M_ILD(REG_ITMP1, REG_SP, (stackframesize + s1) * 4 +4); - M_IST(REG_ITMP1, REG_SP, var->regoff * 4 + 4); - } -#else - /* Reuse Memory Position on Caller Stack */ - var->regoff = stackframesize + s1; -#endif - } + if (IS_INT_LNG_TYPE(t)) { + if (!md->params[p].inmemory) { + if (!IS_INMEMORY(var->flags)) + M_INTMOVE(s1, var->vv.regoff); + else + M_LST(s1, REG_SP, var->vv.regoff * 8); } - - } else { /* floating args */ - if (!md->params[p].inmemory) { /* register arguments */ - s2 = rd->argfltregs[s1]; - if (!(var->flags & INMEMORY)) { /* reg arg -> register */ - M_FLTMOVE(s2, var->regoff); - - } else { /* reg arg -> spilled */ + else { + if (!IS_INMEMORY(var->flags)) + M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); + else + var->vv.regoff = cd->stackframesize + s1; + } + } + else { + if (!md->params[p].inmemory) { + if (!IS_INMEMORY(var->flags)) + M_FLTMOVE(s1, var->vv.regoff); + else + M_DST(s1, REG_SP, var->vv.regoff * 8); + } + else { + if (!(var->flags & INMEMORY)) { if (IS_2_WORD_TYPE(t)) - M_DST(s2, REG_SP, var->regoff * 4); + M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); else - M_FST(s2, REG_SP, var->regoff * 4); + M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); } - - } else { /* stack arguments */ - if (!(var->flags & INMEMORY)) { /* stack-arg -> register */ - if (IS_2_WORD_TYPE(t)) - M_DLD(var->regoff, REG_SP, (stackframesize + s1) * 4); - - else - M_FLD(var->regoff, REG_SP, (stackframesize + s1) * 4); - - } else { /* stack-arg -> spilled */ -#if 1 - if (IS_2_WORD_TYPE(t)) { - M_DLD(REG_FTMP1, REG_SP, (stackframesize + s1) * 4); - M_DST(REG_FTMP1, REG_SP, var->regoff * 4); - var->regoff = stackframesize + s1; - - } else { - M_FLD(REG_FTMP1, REG_SP, (stackframesize + s1) * 4); - M_FST(REG_FTMP1, REG_SP, var->regoff * 4); - } -#else - /* Reuse Memory Position on Caller Stack */ - var->regoff = stackframesize + s1; -#endif - } + else + var->vv.regoff = cd->stackframesize + s1; } } - } /* end for */ + } /* save monitorenter argument */ @@ -307,21 +262,23 @@ bool codegen(jitdata *jd) /* stackoffset for argument used for LOCK_monitor_exit */ s1 = rd->memuse; + #if !defined (NDEBUG) if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP); for (p = 0; p < INT_ARG_CNT; p++) - M_LST(rd->argintregs[p], REG_SP, LA_SIZE + PA_SIZE + p * 8); + M_LST(abi_registers_integer_argument[p], REG_SP, LA_SIZE + PA_SIZE + p * 8); for (p = 0; p < FLT_ARG_CNT; p++) - M_DST(rd->argfltregs[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8); + M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8); /* used for LOCK_monitor_exit, adopt size because we created another stackframe */ s1 += (LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT); } #endif - p = dseg_addaddress(cd, LOCK_monitor_enter); + + p = dseg_add_functionptr(cd, LOCK_monitor_enter); M_ALD(REG_ITMP3, REG_PV, p); M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ M_MTCTR(REG_ITMP3); @@ -329,24 +286,25 @@ bool codegen(jitdata *jd) /* get or test the lock object */ if (m->flags & ACC_STATIC) { - p = dseg_addaddress(cd, &m->class->object.header); - M_ALD(rd->argintregs[0], REG_PV, p); + p = dseg_add_address(cd, &m->class->object.header); + M_ALD(REG_A0, REG_PV, p); } else { - M_TST(rd->argintregs[0]); - M_BEQ(0); - codegen_add_nullpointerexception_ref(cd); + M_TST(REG_A0); + M_BNE(1); + M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER); } - M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* rd->memuse * 8 */ + M_AST(REG_A0, REG_SP, s1 * 8); /* rd->memuse * 8 */ M_JSR; -#if !defined (NDEBUG) + +#if !defined(NDEBUG) if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { for (p = 0; p < INT_ARG_CNT; p++) - M_LLD(rd->argintregs[p], REG_SP, LA_SIZE + PA_SIZE + p * 8); + M_LLD(abi_registers_integer_argument[p], REG_SP, LA_SIZE + PA_SIZE + p * 8); for (p = 0; p < FLT_ARG_CNT; p++) - M_DLD(rd->argfltregs[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8); + M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + PA_SIZE + (INT_ARG_CNT + p) * 8); M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP); } @@ -364,35 +322,24 @@ bool codegen(jitdata *jd) /* end of header generation */ - replacementpoint = jd->code->rplpoints; + /* create replacement points */ + + REPLACEMENT_POINTS_INIT(cd, jd); /* walk through all basic blocks */ - for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) { + + for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) { bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase); if (bptr->flags >= BBREACHED) { /* branch resolving */ - - { - branchref *brefs; - for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) { - gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos, - brefs->branchpos, - bptr->mpc); - } - } + codegen_resolve_branchrefs(cd, bptr); /* handle replacement points */ -#if 0 - if (bptr->bitflags & BBFLAG_REPLACEMENT) { - replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */ - - replacementpoint++; - } -#endif + REPLACEMENT_POINT_BLOCK_START(cd, bptr); /* copy interface registers to their destination */ @@ -403,68 +350,29 @@ bool codegen(jitdata *jd) if (opt_lsra) { while (len) { len--; - src = bptr->invars[len]; - if ((len == 0) && (bptr->type != BBTYPE_STD)) { - /* d = reg_of_var(m, src, REG_ITMP1); */ - if (!(src->flags & INMEMORY)) - d = src->regoff; + var = VAR(bptr->invars[len]); + if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) { + /* d = reg_of_var(m, var, REG_ITMP1); */ + if (!(var->flags & INMEMORY)) + d = var->vv.regoff; else d = REG_ITMP1; M_INTMOVE(REG_ITMP1, d); - emit_store(jd, NULL, src, d); + emit_store(jd, NULL, var, d); } } } else { #endif while (len) { len--; - src = bptr->invars[len]; - if ((len == 0) && (bptr->type != BBTYPE_STD)) { - d = codegen_reg_of_var(rd, 0, src, REG_ITMP1); + var = VAR(bptr->invars[len]); + if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) { + d = codegen_reg_of_var(0, var, REG_ITMP1); M_INTMOVE(REG_ITMP1, d); - emit_store(jd, NULL, src, d); - } else { - if (src->type == TYPE_LNG) - d = codegen_reg_of_var(rd, 0, src, PACK_REGS(REG_ITMP2, REG_ITMP1)); - else - d = codegen_reg_of_var(rd, 0, src, REG_IFTMP); - if ((src->varkind != STACKVAR)) { - s2 = src->type; - if (IS_FLT_DBL_TYPE(s2)) { - if (!(rd->interfaces[len][s2].flags & INMEMORY)) { - s1 = rd->interfaces[len][s2].regoff; - M_FLTMOVE(s1, d); - } else { - if (IS_2_WORD_TYPE(s2)) { - M_DLD(d, REG_SP, - rd->interfaces[len][s2].regoff * 4); - } else { - M_FLD(d, REG_SP, - rd->interfaces[len][s2].regoff * 4); - } - } - - emit_store(jd, NULL, src, d); - - } else { - if (!(rd->interfaces[len][s2].flags & INMEMORY)) { - s1 = rd->interfaces[len][s2].regoff; - if (IS_2_WORD_TYPE(s2)) - M_LNGMOVE(s1, d); - else - M_INTMOVE(s1, d); - } else { - if (IS_2_WORD_TYPE(s2)) - M_LLD(d, REG_SP, - rd->interfaces[len][s2].regoff * 4); - else - M_ILD(d, REG_SP, - rd->interfaces[len][s2].regoff * 4); - } - - emit_store(jd, NULL, src, d); - } - } + emit_store(jd, NULL, var, d); + } + else { + assert((var->flags & INOUT)); } } @@ -484,19 +392,36 @@ bool codegen(jitdata *jd) MCODECHECK(64); /* an instruction usually needs < 64 words */ - /* M_NOP; M_NOP; XXX */ - switch (iptr->opc) { - case ICMD_NOP: /* ... ==> ... */ - case ICMD_INLINE_START: - case ICMD_INLINE_END: - break; + switch (iptr->opc) { + case ICMD_NOP: /* ... ==> ... */ + case ICMD_POP: /* ..., value ==> ... */ + case ICMD_POP2: /* ..., value, value ==> ... */ + break; + + case ICMD_INLINE_START: + + REPLACEMENT_POINT_INLINE_START(cd, iptr); + break; + + case ICMD_INLINE_BODY: + + REPLACEMENT_POINT_INLINE_BODY(cd, iptr); + dseg_addlinenumber_inline_start(cd, iptr); + dseg_addlinenumber(cd, iptr->line); + break; + + case ICMD_INLINE_END: + + dseg_addlinenumber_inline_end(cd, iptr); + dseg_addlinenumber(cd, iptr->line); + break; case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); M_TST(s1); M_BEQ(0); - codegen_add_nullpointerexception_ref(cd); + emit_nullpointer_check(cd, iptr, s1); break; /* constant operations ************************************************/ @@ -518,7 +443,7 @@ bool codegen(jitdata *jd) case ICMD_FCONST: /* ... ==> ..., constant */ d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - a = dseg_addfloat(cd, iptr->sx.val.f); + a = dseg_add_float(cd, iptr->sx.val.f); M_FLD(d, REG_PV, a); emit_store_dst(jd, iptr, d); break; @@ -526,209 +451,69 @@ bool codegen(jitdata *jd) case ICMD_DCONST: /* ... ==> ..., constant */ d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - a = dseg_adddouble(cd, iptr->sx.val.d); + a = dseg_add_double(cd, iptr->sx.val.d); M_DLD(d, REG_PV, a); emit_store_dst(jd, iptr, d); break; case ICMD_ACONST: /* ... ==> ..., constant */ + d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - disp = dseg_addaddress(cd, iptr->sx.val.anyptr); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + disp = dseg_add_unique_address(cd, iptr->sx.val.c.ref); codegen_addpatchref(cd, PATCHER_aconst, iptr->sx.val.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; + } else { + disp = dseg_add_address(cd, iptr->sx.val.anyptr); } - M_ALD(d, REG_PV, disp); emit_store_dst(jd, iptr, d); break; - /* load/store operations **********************************************/ + /* load/store/copy/move operations ************************************/ case ICMD_ILOAD: /* ... ==> ..., content of local variable */ case ICMD_ALOAD: /* s1.localindex = local variable */ case ICMD_LLOAD: - - d = codegen_reg_of_var(rd, iptr->opc, iptr->dst.var, REG_ITMP1); - if ((iptr->dst.var->varkind == LOCALVAR) && - (iptr->dst.var->varnum == iptr->s1.localindex)) - break; - var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]); - if (var->flags & INMEMORY) - M_LLD(d, REG_SP, var->regoff * 8); - else - M_LNGMOVE(var->regoff, d); - emit_store_dst(jd, iptr, d); - break; - - case ICMD_FLOAD: /* ... ==> ..., content of local variable */ - /* s1.localindex = local variable */ - - d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - if ((iptr->dst.var->varkind == LOCALVAR) && - (iptr->dst.var->varnum == iptr->s1.localindex)) - break; - var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]); - if (var->flags & INMEMORY) - M_FLD(d, REG_SP, var->regoff * 4); - else - M_FLTMOVE(var->regoff, d); - emit_store_dst(jd, iptr, d); - break; - - case ICMD_DLOAD: /* ... ==> ..., content of local variable */ - /* s1.localindex = local variable */ - - d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - if ((iptr->dst.var->varkind == LOCALVAR) && - (iptr->dst.var->varnum == iptr->s1.localindex)) - break; - var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]); - if (var->flags & INMEMORY) - M_DLD(d, REG_SP, var->regoff * 4); - else - M_FLTMOVE(var->regoff, d); - emit_store_dst(jd, iptr, d); - break; - - + case ICMD_FLOAD: + case ICMD_DLOAD: case ICMD_ISTORE: /* ..., value ==> ... */ - case ICMD_ASTORE: /* dst.localindex = local variable */ case ICMD_LSTORE: + case ICMD_FSTORE: + case ICMD_DSTORE: + case ICMD_COPY: + case ICMD_MOVE: - if ((iptr->s1.var->varkind == LOCALVAR) && - (iptr->s1.var->varnum == iptr->dst.localindex)) - break; - var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]); - if (var->flags & INMEMORY) { - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - M_LST(s1, REG_SP, var->regoff * 8); - } - else { - s1 = emit_load_s1(jd, iptr, var->regoff); - M_LNGMOVE(s1, var->regoff); - } - break; - - case ICMD_FSTORE: /* ..., value ==> ... */ - /* dst.localindex = local variable */ - - if ((iptr->s1.var->varkind == LOCALVAR) && - (iptr->s1.var->varnum == iptr->dst.localindex)) - break; - var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]); - if (var->flags & INMEMORY) { - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - M_FST(s1, REG_SP, var->regoff * 8); - } - else { - s1 = emit_load_s1(jd, iptr, var->regoff); - M_FLTMOVE(s1, var->regoff); - } - break; - - case ICMD_DSTORE: /* ..., value ==> ... */ - /* dst.localindex = local variable */ - - if ((iptr->s1.var->varkind == LOCALVAR) && - (iptr->s1.var->varnum == iptr->dst.localindex)) - break; - var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]); - if (var->flags & INMEMORY) { - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - M_DST(s1, REG_SP, var->regoff * 8); - } - else { - s1 = emit_load_s1(jd, iptr, var->regoff); - M_FLTMOVE(s1, var->regoff); - } - break; - - - /* pop/dup/swap operations ********************************************/ - - /* attention: double and longs are only one entry in CACAO ICMDs */ - - case ICMD_POP: /* ..., value ==> ... */ - case ICMD_POP2: /* ..., value, value ==> ... */ - break; - - case ICMD_DUP: /* ..., a ==> ..., a, a */ - - M_COPY(iptr->s1.var, iptr->dst.var); - break; - - case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */ - - M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]); - M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]); - M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]); - break; - - case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */ - - M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]); - M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]); - M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]); - M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]); - break; - - case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */ - - M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]); - M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]); - break; - - case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */ - - M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]); - M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]); - M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]); - M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]); - M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]); - break; - - case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */ - - M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]); - M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]); - M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]); - M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]); - M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]); - M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]); + emit_copy(jd, iptr); break; - case ICMD_SWAP: /* ..., a, b ==> ..., b, a */ - - M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]); - M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]); + case ICMD_ASTORE: + if (!(iptr->flags.bits & INS_FLAG_RETADDR)) + emit_copy(jd, iptr); break; /* integer operations *************************************************/ case ICMD_INEG: /* ..., value ==> ..., - value */ - s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_NEG(s1, d); + M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; - case ICMD_LNEG: /* ..., value ==> ..., - value */ - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); + case ICMD_LNEG: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - M_NEG(s1, d); /* XXX */ + M_NEG(s1, d); emit_store_dst(jd, iptr, d); break; + case ICMD_I2L: /* ..., value ==> ..., value */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); @@ -780,17 +565,18 @@ bool codegen(jitdata *jd) emit_store_dst(jd, iptr, d); break; - case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */ - /* sx.val.i = constant */ + case ICMD_IINC: + case ICMD_IADDCONST: s1 = emit_load_s1(jd, iptr, REG_ITMP1); - d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) { M_IADD_IMM(s1, iptr->sx.val.i, d); } else { ICONST(REG_ITMP2, iptr->sx.val.i); M_IADD(s1, REG_ITMP2, d); } + M_EXTSW(d,d); emit_store_dst(jd, iptr, d); break; @@ -824,6 +610,7 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_SUB(s1, s2, d); + M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; @@ -838,6 +625,7 @@ bool codegen(jitdata *jd) ICONST(REG_ITMP2, iptr->sx.val.i); M_SUB(s1, REG_ITMP2, d); } + M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; @@ -856,7 +644,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); /* XXX check me */ - if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) { + if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767)) { M_LADD_IMM(s1, -iptr->sx.val.l, d); } else { LCONST(REG_ITMP2, iptr->sx.val.l); @@ -866,38 +654,80 @@ bool codegen(jitdata *jd) break; case ICMD_IDIV: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); + emit_arithmetic_check(cd, iptr, s2); + + M_DIV(s1, s2, d); + M_EXTSW(d, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); - M_TST(s2); - M_BEQ(0); - codegen_add_arithmeticexception_ref(cd); + emit_arithmetic_check(cd, iptr, s2); M_DIV(s1, s2, d); - + /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */ + /* we only need to check this if we did a LDIV, not for IDIV */ + M_MFXER(REG_ITMP2); + M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2); /* test OV */ + M_BLE(1); + M_MOV(s1, d); /* java specs says result == dividend */ emit_store_dst(jd, iptr, d); break; case ICMD_IREM: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + emit_arithmetic_check(cd, iptr, s2); + + M_DIV(s1, s2, REG_ITMP3); + M_MUL(REG_ITMP3, s2, REG_ITMP2); + M_SUB(s1, REG_ITMP2, REG_ITMP3); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); + + M_MOV(REG_ITMP3, d); + emit_store_dst(jd, iptr, d); + break; + + case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); - M_TST(s2); - M_BEQ(0); - codegen_add_arithmeticexception_ref(cd); + emit_arithmetic_check(cd, iptr, s2); + + M_DIV(s1, s2, REG_ITMP3); + /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */ + /* we only need to check this if we did a LDIV, not for IDIV */ + M_MFXER(REG_ITMP2); + M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2); /* test OV */ + M_BLE(2); + LCONST(REG_ITMP3, 0); /* result == 0 in this case */ + M_BR(2); + M_MUL(REG_ITMP3, s2, REG_ITMP2); + M_SUB(s1, REG_ITMP2, REG_ITMP3); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - /* FIXME s1 == -2^63 && s2 == -1 does not work that way */ - M_DIV(s1, s2, d); - M_MUL( d, s2, d); - M_SUB(s1, d, d); + M_MOV(REG_ITMP3, d); emit_store_dst(jd, iptr, d); break; + case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */ + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_MUL(s1, s2, d); + M_EXTSW(d, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LMUL: s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); @@ -916,15 +746,28 @@ bool codegen(jitdata *jd) ICONST(REG_ITMP3, iptr->sx.val.i); M_MUL(s1, REG_ITMP3, d); } + M_EXTSW(d, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LMULCONST: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767)) + M_MUL_IMM(s1, iptr->sx.val.l, d); + else { + LCONST(REG_ITMP3, iptr->sx.val.l); + M_MUL(s1, REG_ITMP3, d); + } emit_store_dst(jd, iptr, d); break; case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */ - + s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); M_SRA_IMM(s1, iptr->sx.val.i, d); M_ADDZE(d, d); + M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; @@ -935,6 +778,7 @@ bool codegen(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_AND_IMM(s2, 0x1f, REG_ITMP3); M_SLL(s1, REG_ITMP3, d); + M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; @@ -944,6 +788,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d); + M_EXTSW(d,d); emit_store_dst(jd, iptr, d); break; @@ -972,7 +817,10 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_AND_IMM(s2, 0x1f, REG_ITMP2); - M_SRL(s1, REG_ITMP2, d); + M_MOV(s1, REG_ITMP1); + M_CLR_HIGH(REG_ITMP1); + M_SRL(REG_ITMP1, REG_ITMP2, d); + M_EXTSW(d,d); /* for the case it was shift 0 bits */ emit_store_dst(jd, iptr, d); break; @@ -982,16 +830,68 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); if (iptr->sx.val.i & 0x1f) { - M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d); + M_MOV(s1, REG_ITMP1); + M_CLR_HIGH(REG_ITMP1); + M_SRA_IMM(REG_ITMP1, iptr->sx.val.i & 0x1f, d); } else { M_INTMOVE(s1, d); } emit_store_dst(jd, iptr, d); break; + + case ICMD_LSHLCONST: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LSHL: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_AND_IMM(s2, 0x3f, REG_ITMP2); + M_SLL(s1, REG_ITMP2, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LSHRCONST: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LSHR: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_AND_IMM(s2, 0x3f, REG_ITMP2); + M_SRA(s1, REG_ITMP2, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LUSHRCONST: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_LUSHR: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_AND_IMM(s2, 0x3f, REG_ITMP2); + M_SRL(s1, REG_ITMP2, d); + emit_store_dst(jd, iptr, d); + break; case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */ - case ICMD_LAND: + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); + M_AND(s1, s2, d); +/* M_EXTSW(d, d);*/ + emit_store_dst(jd, iptr, d); + break; + case ICMD_LAND: s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); @@ -1040,14 +940,25 @@ bool codegen(jitdata *jd) case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */ /* sx.val.i = constant */ - s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); +#if 0 + /* fast division, result in REG_ITMP3) */ + M_SRA_IMM(s1, iptr->sx.val.i, REG_ITMP3); + M_ADDZE(REG_ITMP3, REG_ITMP3); + + M_SUB(s1, REG_ITMP3, d); + M_EXTSW(d, d); + emit_store_dst(jd, iptr, d); + break; +#else + M_MOV(s1, REG_ITMP2); M_CMPI(s1, 0); - M_BGE(1 + 2*(iptr->sx.val.i >= 32768)); + M_BGE(1 + 3*(iptr->sx.val.i >= 32768)); if (iptr->sx.val.i >= 32768) { M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2); + M_EXTSW(REG_ITMP2, REG_ITMP2); M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2); M_IADD(s1, REG_ITMP2, REG_ITMP2); } else { @@ -1060,10 +971,20 @@ bool codegen(jitdata *jd) M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2); } M_SUB(s1, REG_ITMP2, d); + M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; +#endif case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */ + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); + M_OR(s1, s2, d); +/* M_EXTSW(d,d);*/ + emit_store_dst(jd, iptr, d); + break; + case ICMD_LOR: s1 = emit_load_s1(jd, iptr, REG_ITMP1); @@ -1146,29 +1067,11 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP3); /* XXX implement me!!! */ + vm_abort("codegen: implement ICMD_LCMP!"); emit_store_dst(jd, iptr, d); break; break; - case ICMD_IINC: /* ..., value ==> ..., value + constant */ - /* s1.localindex = variable, sx.val.i = constant*/ - - var = &(rd->locals[iptr->s1.localindex][TYPE_INT]); - if (var->flags & INMEMORY) { - s1 = REG_ITMP1; - M_LLD(s1, REG_SP, var->regoff * 8); - } - else - s1 = var->regoff; - - /* XXX implement me more efficiently */ - ICONST(REG_ITMP2, iptr->sx.val.i); - M_IADD(s1, REG_ITMP2, s1); - - if (var->flags & INMEMORY) - M_LST(s1, REG_SP, var->regoff * 8); - break; - /* floating operations ************************************************/ @@ -1266,11 +1169,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_CLR(d); - disp = dseg_addfloat(cd, 0.0); + disp = dseg_add_float(cd, 0.0); M_FLD(REG_FTMP2, REG_PV, disp); M_FCMPU(s1, REG_FTMP2); M_BNAN(4); - disp = dseg_adds4(cd, 0); + disp = dseg_add_unique_s4(cd, 0); M_CVTDL_C(s1, REG_FTMP1); M_LDA(REG_ITMP1, REG_PV, disp); M_STFIWX(REG_FTMP1, 0, REG_ITMP1); @@ -1334,8 +1237,7 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); M_BNAN(1); - M_BEQ(0); - codegen_addreference(cd, iptr->dst.block); + emit_beq(cd, iptr->dst.block); break; case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */ @@ -1344,10 +1246,8 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); - M_BNAN(0); - codegen_addreference(cd, iptr->dst.block); - M_BNE(0); - codegen_addreference(cd, iptr->dst.block); + emit_bnan(cd, iptr->dst.block); + emit_bne(cd, iptr->dst.block); break; @@ -1357,10 +1257,8 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); - M_BNAN(0); - codegen_addreference(cd, iptr->dst.block); - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); + emit_bnan(cd, iptr->dst.block); + emit_blt(cd, iptr->dst.block); break; case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */ @@ -1370,8 +1268,7 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); M_BNAN(1); - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); + emit_bgt(cd, iptr->dst.block); break; case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */ @@ -1380,10 +1277,8 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); - M_BNAN(0); - codegen_addreference(cd, iptr->dst.block); - M_BLE(0); - codegen_addreference(cd, iptr->dst.block); + emit_bnan(cd, iptr->dst.block); + emit_ble(cd, iptr->dst.block); break; case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */ @@ -1393,8 +1288,7 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); M_BNAN(1); - M_BGE(0); - codegen_addreference(cd, iptr->dst.block); + emit_bge(cd, iptr->dst.block); break; case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */ @@ -1404,8 +1298,7 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); M_BNAN(1); - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); + emit_blt(cd, iptr->dst.block); break; case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */ @@ -1414,10 +1307,8 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); - M_BNAN(0); - codegen_addreference(cd, iptr->dst.block); - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); + emit_bnan(cd, iptr->dst.block); + emit_bgt(cd, iptr->dst.block); break; case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */ @@ -1427,8 +1318,7 @@ bool codegen(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); M_BNAN(1); - M_BLE(0); - codegen_addreference(cd, iptr->dst.block); + emit_ble(cd, iptr->dst.block); break; case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */ @@ -1437,10 +1327,8 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); M_FCMPU(s1, s2); - M_BNAN(0); - codegen_addreference(cd, iptr->dst.block); - M_BGE(0); - codegen_addreference(cd, iptr->dst.block); + emit_bnan(cd, iptr->dst.block); + emit_bge(cd, iptr->dst.block); break; @@ -1450,7 +1338,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - gen_nullptr_check(s1); + emit_nullpointer_check(cd, iptr, s1); M_ILD(d, s1, OFFSET(java_arrayheader, size)); emit_store_dst(jd, iptr, d); break; @@ -1460,11 +1348,9 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } - M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); + M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2); + /* implicit null-pointer check */ M_LBZX(d, s1, REG_ITMP2); M_BSEXT(d, d); emit_store_dst(jd, iptr, d); @@ -1475,13 +1361,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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_LHAX(d, s1, REG_ITMP2); + /* implicit null-pointer check */ + M_LHZX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); break; @@ -1490,12 +1374,10 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_LHAX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); break; @@ -1505,13 +1387,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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_LWZX(d, s1, REG_ITMP2); + /* implicit null-pointer check */ + M_LWAX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); break; @@ -1519,13 +1399,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - d = codegen_reg_of_var(rd, iptr->opc, iptr->dst.var, PACK_REGS(REG_ITMP2, REG_ITMP1)); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + d = codegen_reg_of_dst(jd, iptr, PACK_REGS(REG_ITMP2, REG_ITMP1)); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); 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])); emit_store_dst(jd, iptr, d); break; @@ -1535,12 +1413,10 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_LFSX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); break; @@ -1550,12 +1426,10 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_LFDX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); break; @@ -1565,12 +1439,10 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_ALDX(d, s1, REG_ITMP2); emit_store_dst(jd, iptr, d); break; @@ -1580,12 +1452,10 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_STBX(s3, s1, REG_ITMP2); break; @@ -1593,13 +1463,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_STHX(s3, s1, REG_ITMP2); break; @@ -1607,10 +1475,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); @@ -1621,13 +1486,11 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_STWX(s3, s1, REG_ITMP2); break; @@ -1635,27 +1498,23 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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_LST(s3, s1, REG_ITMP2); + /* implicit null-pointer check */ + M_LSTX(s3, s1, REG_ITMP2); break; case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_STFSX(s3, s1, REG_ITMP2); break; @@ -1663,44 +1522,38 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } + 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); + /* implicit null-pointer check */ M_STFDX(s3, s1, REG_ITMP2); break; case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */ - s1 = emit_load_s1(jd, iptr, rd->argintregs[0]); + s1 = emit_load_s1(jd, iptr, REG_A0); s2 = emit_load_s2(jd, iptr, REG_ITMP2); - if (INSTRUCTION_MUST_CHECK(iptr)) { - gen_nullptr_check(s1); - gen_bound_check; - } - s3 = emit_load_s3(jd, iptr, rd->argintregs[1]); + emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); + s3 = emit_load_s3(jd, iptr, REG_A1); - disp = dseg_addaddress(cd, BUILTIN_canstore); + disp = dseg_add_functionptr(cd, BUILTIN_canstore); M_ALD(REG_ITMP3, REG_PV, disp); M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ M_MTCTR(REG_ITMP3); - M_INTMOVE(s1, rd->argintregs[0]); - M_INTMOVE(s3, rd->argintregs[1]); + M_INTMOVE(s1, REG_A0); + M_INTMOVE(s3, REG_A1); M_JSR; - M_TST(REG_RESULT); - M_BEQ(0); - codegen_add_arraystoreexception_ref(cd); + emit_exception_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); + /* implicit null-pointer check */ M_ASTX(s3, s1, REG_ITMP2); break; @@ -1708,28 +1561,22 @@ bool codegen(jitdata *jd) 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_addaddress(cd, NULL); + disp = dseg_add_unique_address(cd, NULL); codegen_addpatchref(cd, PATCHER_get_putstatic, iptr->sx.s23.s3.uf, disp); - if (opt_showdisassemble) - M_NOP; - } else { fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = dseg_addaddress(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 (opt_showdisassemble) - M_NOP; } } @@ -1740,9 +1587,8 @@ bool codegen(jitdata *jd) M_ILD_INTERN(d, REG_ITMP1, 0); break; case TYPE_LNG: - d = codegen_reg_of_var(rd, iptr->opc, iptr->dst.var, PACK_REGS(REG_ITMP2, REG_ITMP1)); - M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */ - M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */ + d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); + M_LLD(d, REG_ITMP1, 0); break; case TYPE_ADR: d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); @@ -1764,28 +1610,21 @@ bool codegen(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 = dseg_addaddress(cd, NULL); + disp = dseg_add_unique_address(cd, NULL); codegen_addpatchref(cd, PATCHER_get_putstatic, iptr->sx.s23.s3.uf, disp); - - if (opt_showdisassemble) - M_NOP; - } else { fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = dseg_addaddress(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 (opt_showdisassemble) - M_NOP; } } @@ -1818,28 +1657,20 @@ bool codegen(jitdata *jd) case ICMD_GETFIELD: /* ... ==> ..., value */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - gen_nullptr_check(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; - - codegen_addpatchref(cd, PATCHER_get_putfield, - iptr->sx.s23.s3.uf, 0); - - if (opt_showdisassemble) - M_NOP; - disp = 0; + codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = fi->offset; } + /* implicit null-pointer check */ switch (fieldtype) { case TYPE_INT: d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); @@ -1868,34 +1699,30 @@ bool codegen(jitdata *jd) case ICMD_PUTFIELD: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); - gen_nullptr_check(s1); - - if (!IS_FLT_DBL_TYPE(fieldtype)) { - s2 = emit_load_s2(jd, iptr, REG_ITMP2); - } else { - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - } 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 { + fi = iptr->sx.s23.s3.fmiref->p.field; + fieldtype = fi->type; + disp = fi->offset; + } - codegen_addpatchref(cd, PATCHER_get_putfield, - iptr->sx.s23.s3.uf, 0); - - if (opt_showdisassemble) - M_NOP; - - disp = 0; - - } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; + if (IS_INT_LNG_TYPE(fieldtype)) { + s2 = emit_load_s2(jd, iptr, REG_ITMP2); + } + else + s2 = emit_load_s2(jd, iptr, REG_FTMP2); - fieldtype = fi->type; - disp = fi->offset; + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); } + + /* implicit null-pointer check */ switch (fieldtype) { case TYPE_INT: M_IST(s2, s1, disp); @@ -1927,13 +1754,10 @@ bool codegen(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { codegen_addpatchref(cd, PATCHER_athrow_areturn, iptr->sx.s23.s2.uc, 0); - - if (opt_showdisassemble) - M_NOP; } #endif /* ENABLE_VERIFIER */ - disp = dseg_addaddress(cd, asm_handle_exception); + disp = dseg_add_functionptr(cd, asm_handle_exception); M_ALD(REG_ITMP2, REG_PV, disp); M_MTCTR(REG_ITMP2); @@ -1947,35 +1771,15 @@ bool codegen(jitdata *jd) break; case ICMD_GOTO: /* ... ==> ... */ - M_BR(0); - codegen_addreference(cd, iptr->dst.block); + case ICMD_RET: /* ... ==> ... */ + + emit_br(cd, iptr->dst.block); ALIGNCODENOP; break; case ICMD_JSR: /* ... ==> ... */ - if (jd->isleafmethod) - M_MFLR(REG_ITMP2); - M_BL(0); - M_MFLR(REG_ITMP1); - M_IADD_IMM(REG_ITMP1, jd->isleafmethod ? 4*4 : 3*4, REG_ITMP1); - if (jd->isleafmethod) - M_MTLR(REG_ITMP2); - M_BR(0); - codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block); - break; - - case ICMD_RET: /* ... ==> ... */ - /* s1.localindex = local variable */ - - var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]); - if (var->flags & INMEMORY) { - M_ALD(REG_ITMP1, REG_SP, var->regoff * 4); - M_MTCTR(REG_ITMP1); - } else { - M_MTCTR(var->regoff); - } - M_RTS; + emit_br(cd, iptr->sx.s23.s3.jsrtarget.block); ALIGNCODENOP; break; @@ -1983,16 +1787,14 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); M_TST(s1); - M_BEQ(0); - codegen_addreference(cd, iptr->dst.block); + emit_beq(cd, iptr->dst.block); break; case ICMD_IFNONNULL: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); M_TST(s1); - M_BNE(0); - codegen_addreference(cd, iptr->dst.block); + emit_bne(cd, iptr->dst.block); break; case ICMD_IFLT: @@ -2009,181 +1811,46 @@ bool codegen(jitdata *jd) ICONST(REG_ITMP2, iptr->sx.val.i); M_CMP(s1, REG_ITMP2); } - switch (iptr->opc) { - case ICMD_IFLT: - M_BLT(0); - break; - case ICMD_IFLE: - M_BLE(0); - break; - case ICMD_IFNE: - M_BNE(0); - break; - case ICMD_IFGT: - M_BGT(0); - break; - case ICMD_IFGE: - M_BGE(0); - break; - case ICMD_IFEQ: - M_BEQ(0); - break; - } - codegen_addreference(cd, iptr->dst.block); + emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE); break; - - #if 0 + case ICMD_IF_LEQ: /* ..., value ==> ... */ - - s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); - s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); - if (iptr->sx.val.l == 0) { - M_OR_TST(s1, s2, REG_ITMP3); - } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) { - M_XOR_IMM(s2, 0, REG_ITMP2); - M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1); - M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3); - } else { - ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); - M_XOR(s1, REG_ITMP3, REG_ITMP1); - ICONST(REG_ITMP3, iptr->sx.val.l >> 32); - M_XOR(s2, REG_ITMP3, REG_ITMP2); - M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3); - } - M_BEQ(0); - codegen_addreference(cd, iptr->dst.block); + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); + emit_beq(cd, iptr->dst.block); break; - case ICMD_IF_LLT: /* ..., value ==> ... */ - s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); - s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); - if (iptr->sx.val.l == 0) { - /* if high word is less than zero, the whole long is too */ - M_CMPI(s2, 0); - } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) { - M_CMPI(s2, 0); - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); - M_BGT(2); - M_CMPUI(s1, iptr->sx.val.l & 0xffff); - } else { - ICONST(REG_ITMP3, iptr->sx.val.l >> 32); - M_CMP(s2, REG_ITMP3); - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); - M_BGT(3); - ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); - M_CMPU(s1, REG_ITMP3); - } - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); + emit_blt(cd, iptr->dst.block); break; - case ICMD_IF_LLE: /* ..., value ==> ... */ + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); + emit_ble(cd, iptr->dst.block); + break; - s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); - s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); -/* if (iptr->sx.val.l == 0) { */ -/* M_OR(s1, s2, REG_ITMP3); */ -/* M_CMPI(REG_ITMP3, 0); */ - -/* } else */ - if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) { - M_CMPI(s2, 0); - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); - M_BGT(2); - M_CMPUI(s1, iptr->sx.val.l & 0xffff); - } else { - ICONST(REG_ITMP3, iptr->sx.val.l >> 32); - M_CMP(s2, REG_ITMP3); - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); - M_BGT(3); - ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); - M_CMPU(s1, REG_ITMP3); - } - M_BLE(0); - codegen_addreference(cd, iptr->dst.block); - break; - - case ICMD_IF_LNE: /* ..., value ==> ... */ - - s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); - s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); - if (iptr->sx.val.l == 0) { - M_OR_TST(s1, s2, REG_ITMP3); - } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) { - M_XOR_IMM(s2, 0, REG_ITMP2); - M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1); - M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3); - } else { - ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); - M_XOR(s1, REG_ITMP3, REG_ITMP1); - ICONST(REG_ITMP3, iptr->sx.val.l >> 32); - M_XOR(s2, REG_ITMP3, REG_ITMP2); - M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3); - } - M_BNE(0); - codegen_addreference(cd, iptr->dst.block); + case ICMD_IF_LNE: /* ..., value ==> ... */ + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); + emit_bne(cd, iptr->dst.block); + break; + case ICMD_IF_LGE: /* ..., value ==> ... */ + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); + emit_bge(cd, iptr->dst.block); break; - case ICMD_IF_LGT: /* ..., value ==> ... */ - - s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); - s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); -/* if (iptr->sx.val.l == 0) { */ -/* M_OR(s1, s2, REG_ITMP3); */ -/* M_CMPI(REG_ITMP3, 0); */ - -/* } else */ - if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) { - M_CMPI(s2, 0); - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); - M_BLT(2); - M_CMPUI(s1, iptr->sx.val.l & 0xffff); - } else { - ICONST(REG_ITMP3, iptr->sx.val.l >> 32); - M_CMP(s2, REG_ITMP3); - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); - M_BLT(3); - ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); - M_CMPU(s1, REG_ITMP3); - } - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); + emit_bgt(cd, iptr->dst.block); break; - - case ICMD_IF_LGE: /* ..., value ==> ... */ - - /* TODO, remove me */ - s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); - s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); - if (iptr->sx.val.l == 0) { - /* if high word is greater equal zero, the whole long is too */ - M_CMPI(s2, 0); - } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) { - M_CMPI(s2, 0); - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); - M_BLT(2); - M_CMPUI(s1, iptr->sx.val.l & 0xffff); - } else { - ICONST(REG_ITMP3, iptr->sx.val.l >> 32); - M_CMP(s2, REG_ITMP3); - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); - M_BLT(3); - ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff); - M_CMPU(s1, REG_ITMP3); - } - M_BGE(0); - codegen_addreference(cd, iptr->dst.block); - break; - #endif - case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */ case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */ case ICMD_IF_LCMPEQ: @@ -2191,8 +1858,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMP(s1, s2); - M_BEQ(0); - codegen_addreference(cd, iptr->dst.block); + emit_beq(cd, iptr->dst.block); break; case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */ @@ -2202,8 +1868,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMP(s1, s2); - M_BNE(0); - codegen_addreference(cd, iptr->dst.block); + emit_bne(cd, iptr->dst.block); break; @@ -2213,8 +1878,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMP(s1, s2); - M_BLT(0); - codegen_addreference(cd, iptr->dst.block); + emit_blt(cd, iptr->dst.block); break; case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */ @@ -2223,8 +1887,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMP(s1, s2); - M_BGT(0); - codegen_addreference(cd, iptr->dst.block); + emit_bgt(cd, iptr->dst.block); break; case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */ @@ -2233,8 +1896,7 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMP(s1, s2); - M_BLE(0); - codegen_addreference(cd, iptr->dst.block); + emit_ble(cd, iptr->dst.block); break; case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */ @@ -2243,20 +1905,21 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); M_CMP(s1, s2); - M_BGE(0); - codegen_addreference(cd, iptr->dst.block); + emit_bge(cd, iptr->dst.block); break; case ICMD_LRETURN: /* ..., retvalue ==> ... */ case ICMD_IRETURN: /* ..., retvalue ==> ... */ + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_RESULT); M_LNGMOVE(s1, REG_RESULT); goto nowperformreturn; case ICMD_ARETURN: /* ..., retvalue ==> ... */ + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_RESULT); M_LNGMOVE(s1, REG_RESULT); @@ -2264,9 +1927,6 @@ bool codegen(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { codegen_addpatchref(cd, PATCHER_athrow_areturn, iptr->sx.s23.s2.uc, 0); - - if (opt_showdisassemble) - M_NOP; } #endif /* ENABLE_VERIFIER */ @@ -2275,17 +1935,20 @@ bool codegen(jitdata *jd) case ICMD_FRETURN: /* ..., retvalue ==> ... */ case ICMD_DRETURN: + REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_FRESULT); M_FLTMOVE(s1, REG_FRESULT); goto nowperformreturn; case ICMD_RETURN: /* ... ==> ... */ + REPLACEMENT_POINT_RETURN(cd, iptr); + nowperformreturn: { s4 i, p; - p = stackframesize; + p = cd->stackframesize; /* call trace function */ @@ -2297,7 +1960,7 @@ nowperformreturn: #if defined(ENABLE_THREADS) if (checksync && (m->flags & ACC_SYNCHRONIZED)) { - disp = dseg_addaddress(cd, LOCK_monitor_exit); + disp = dseg_add_functionptr(cd, LOCK_monitor_exit); M_ALD(REG_ITMP3, REG_PV, disp); M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ M_MTCTR(REG_ITMP3); @@ -2319,7 +1982,7 @@ nowperformreturn: break; } - M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); + M_ALD(REG_A0, REG_SP, rd->memuse * 8); M_JSR; /* and now restore the proper return value */ @@ -2362,8 +2025,8 @@ nowperformreturn: /* deallocate stack */ - if (stackframesize) - M_LDA(REG_SP, REG_SP, stackframesize * 8); + if (cd->stackframesize) + M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); M_RET; ALIGNCODENOP; @@ -2397,27 +2060,26 @@ nowperformreturn: /* range check */ M_CMPUI(REG_ITMP1, i - 1); - M_BGT(0); - codegen_addreference(cd, table[0].block); + emit_bgt(cd, table[0].block); /* build jump table top down and use address of lowest entry */ table += i; while (--i >= 0) { - dseg_addtarget(cd, table->block); + dseg_add_target(cd, table->block); --table; - } } - /* length of dataseg after last dseg_addtarget is used by load */ + /* length of dataseg after last dseg_add_unique_target is used by load */ - M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1); + M_SLL_IMM(REG_ITMP1, 3, REG_ITMP1); M_IADD(REG_ITMP1, REG_PV, REG_ITMP2); M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen)); M_MTCTR(REG_ITMP2); M_RTS; ALIGNCODENOP; + } break; @@ -2436,18 +2098,17 @@ nowperformreturn: val = lookup->value; if ((val >= -32768) && (val <= 32767)) { M_CMPI(s1, val); + } else { - a = dseg_adds4(cd, val); + a = dseg_add_s4(cd, val); M_ILD(REG_ITMP2, REG_PV, a); M_CMP(s1, REG_ITMP2); } - M_BEQ(0); - codegen_addreference(cd, lookup->target.block); + emit_beq(cd, lookup->target.block); ++lookup; } - M_BR(0); - codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block); + emit_br(cd, iptr->sx.s23.s3.lookupdefault.block); ALIGNCODENOP; break; @@ -2461,17 +2122,20 @@ nowperformreturn: goto gen_method; case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */ - case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */ case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */ case ICMD_INVOKEINTERFACE: + REPLACEMENT_POINT_INVOKE(cd, iptr); + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - md = iptr->sx.s23.s3.um->methodref->parseddesc.md; lm = NULL; + um = iptr->sx.s23.s3.um; + md = um->methodref->parseddesc.md; } else { lm = iptr->sx.s23.s3.fmiref->p.method; + um = NULL; md = lm->parseddesc; } @@ -2483,162 +2147,141 @@ gen_method: /* copy arguments to registers or stack location */ for (s3 = s3 - 1; s3 >= 0; s3--) { - src = iptr->sx.s23.s2.args[s3]; + var = VAR(iptr->sx.s23.s2.args[s3]); + d = md->params[s3].regoff; - if (src->varkind == ARGVAR) + if (var->flags & PREALLOC) continue; - if (IS_INT_LNG_TYPE(src->type)) { + + if (IS_INT_LNG_TYPE(var->type)) { if (!md->params[s3].inmemory) { - s1 = rd->argintregs[md->params[s3].regoff]; - d = emit_load(jd, iptr, src, s1); - M_LNGMOVE(d, s1); - } else { - d = emit_load(jd, iptr, src, REG_ITMP1); - M_LST(d, REG_SP, md->params[s3].regoff * 8); + s1 = emit_load(jd, iptr, var, d); + M_LNGMOVE(s1, d); } - } else { + else { + s1 = emit_load(jd, iptr, var, REG_ITMP1); + M_LST(s1, REG_SP, d * 8); + } + } + else { if (!md->params[s3].inmemory) { - s1 = rd->argfltregs[md->params[s3].regoff]; - d = emit_load(jd, iptr, src, s1); - M_FLTMOVE(d, s1); - } else { - d = emit_load(jd, iptr, src, REG_FTMP1); - if (IS_2_WORD_TYPE(src->type)) - M_DST(d, REG_SP, md->params[s3].regoff * 8); - else - M_FST(d, REG_SP, md->params[s3].regoff * 8); + s1 = emit_load(jd, iptr, var, d); + M_FLTMOVE(s1, d); + } + else { + s1 = emit_load(jd, iptr, var, REG_FTMP1); + M_DST(s1, REG_SP, d * 8); } } - } /* end of for */ + } switch (iptr->opc) { case ICMD_BUILTIN: - disp = dseg_addaddress(cd, bte->fp); - d = md->returntype.type; + disp = dseg_add_functionptr(cd, bte->fp); + M_ALD(REG_PV, REG_PV, disp); + M_ALD(REG_PV, REG_PV, 0); /* TOC */ - M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function descriptor */ - M_ALD(REG_ITMP1, REG_PV, 0); /* function entry point address, what about TOC */ - M_MTCTR(REG_ITMP1); + /* 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); - - if (INSTRUCTION_MUST_CHECK(iptr)) { - M_CMPI(REG_RESULT, 0); - M_BEQ(0); - codegen_add_fillinstacktrace_ref(cd); - } + emit_exception_check(cd, iptr); break; + case ICMD_INVOKESPECIAL: - gen_nullptr_check(rd->argintregs[0]); - M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */ + emit_nullpointer_check(cd, iptr, REG_A0); /* fall through */ case ICMD_INVOKESTATIC: if (lm == NULL) { - unresolved_method *um = iptr->sx.s23.s3.um; - - disp = dseg_addaddress(cd, NULL); + disp = dseg_add_unique_address(cd, um); codegen_addpatchref(cd, PATCHER_invokestatic_special, um, disp); - - if (opt_showdisassemble) - M_NOP; - - d = md->returntype.type; - } else { - disp = dseg_addaddress(cd, lm->stubroutine); - d = md->returntype.type; + disp = dseg_add_address(cd, lm->stubroutine); } - - M_NOP; M_ALD(REG_PV, REG_PV, disp); + + /* generate the actual call */ + 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); - break; + break; case ICMD_INVOKEVIRTUAL: - gen_nullptr_check(rd->argintregs[0]); - if (lm == NULL) { - unresolved_method *um = iptr->sx.s23.s3.um; - codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0); - - if (opt_showdisassemble) - M_NOP; - s1 = 0; - d = md->returntype.type; - } else { s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex; - d = md->returntype.type; } - M_ALD(REG_METHODPTR, rd->argintregs[0], - OFFSET(java_objectheader, vftbl)); + /* implicit null-pointer check */ + M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl)); M_ALD(REG_PV, REG_METHODPTR, s1); + + /* generate the actual call */ + 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); break; case ICMD_INVOKEINTERFACE: - gen_nullptr_check(rd->argintregs[0]); - if (lm == NULL) { - unresolved_method *um = iptr->sx.s23.s3.um; - codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0); - if (opt_showdisassemble) - M_NOP; - s1 = 0; s2 = 0; - d = md->returntype.type; } else { s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index; s2 = sizeof(methodptr) * (lm - lm->class->methods); - - d = md->returntype.type; } - M_ALD(REG_METHODPTR, rd->argintregs[0], - OFFSET(java_objectheader, vftbl)); + /* implicit null-pointer check */ + M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl)); M_ALD(REG_METHODPTR, REG_METHODPTR, s1); M_ALD(REG_PV, REG_METHODPTR, s2); + + /* generate the actual call */ + 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); + break; } + /* store return value */ - /* d contains return type */ + d = md->returntype.type; if (d != TYPE_VOID) { if (IS_INT_LNG_TYPE(d)) { s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT); M_MOV(REG_RESULT, s1); - } else { + } + else { s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT); M_FLTMOVE(REG_FRESULT, s1); } @@ -2646,7 +2289,6 @@ gen_method: } break; - case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */ /* val.a: (classinfo*) superclass */ @@ -2667,163 +2309,147 @@ gen_method: /* object type cast-check */ classinfo *super; - vftbl_t *supervftbl; s4 superindex; if (INSTRUCTION_IS_UNRESOLVED(iptr)) { super = NULL; superindex = 0; - supervftbl = NULL; - } - else { + } else { super = iptr->sx.s23.s3.c.cls; superindex = super->index; - supervftbl = super->vftbl; } - -#if defined(ENABLE_THREADS) - codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase); -#endif - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - - /* calculate interface checkcast code size */ - - s2 = 7; - if (!super) - s2 += (opt_showdisassemble ? 1 : 0); - - /* calculate class checkcast code size */ + + if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { + CODEGEN_CRITICAL_SECTION_NEW; + } - s3 = 8 + (s1 == REG_ITMP1); - if (!super) - s3 += (opt_showdisassemble ? 1 : 0); + s1 = emit_load_s1(jd, iptr, REG_ITMP1); /* if class is not resolved, check which code to call */ - if (!super) { + if (super == NULL) { M_TST(s1); - M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3); - - disp = dseg_adds4(cd, 0); /* super->flags */ + emit_label_beq(cd, BRANCH_LABEL_1); + disp = dseg_add_unique_s4(cd, 0); /* super->flags */ codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags, iptr->sx.s23.s3.c.ref, disp); - if (opt_showdisassemble) - M_NOP; - M_ILD(REG_ITMP2, REG_PV, disp); M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2); - M_BEQ(s2 + 1); + + emit_label_beq(cd, BRANCH_LABEL_2); } /* interface checkcast code */ - if (!super || (super->flags & ACC_INTERFACE)) { - if (super) { - M_TST(s1); - M_BEQ(s2); - - } else { + if ((super == NULL) || (super->flags & ACC_INTERFACE)) { + if (super == NULL) { codegen_addpatchref(cd, - PATCHER_checkcast_instanceof_interface, + PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0); - - if (opt_showdisassemble) - M_NOP; + } else { + M_TST(s1); + emit_label_beq(cd, BRANCH_LABEL_3); } M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength)); M_LDATST(REG_ITMP3, REG_ITMP3, -superindex); - M_BLE(0); - codegen_add_classcastexception_ref(cd, s1); /*XXX s1?? */ + emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1); M_ALD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); M_TST(REG_ITMP3); - M_BEQ(0); - codegen_add_classcastexception_ref(cd, s1); /*XXX s1??*/ + emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1); - if (!super) - M_BR(s3); + if (super == NULL) { + emit_label_br(cd, BRANCH_LABEL_4); + } else { + emit_label(cd, BRANCH_LABEL_3); + } } /* class checkcast code */ - if (!super || !(super->flags & ACC_INTERFACE)) { - disp = dseg_addaddress(cd, supervftbl); - - if (super) { - M_TST(s1); - M_BEQ(s3); + if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { + if (super == NULL) { + emit_label(cd, BRANCH_LABEL_2); - } else { + disp = dseg_add_unique_address(cd, NULL); codegen_addpatchref(cd, PATCHER_checkcast_class, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; + } else { + disp = dseg_add_address(cd, super->vftbl); + M_TST(s1); + emit_label_beq(cd, BRANCH_LABEL_5); } M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); -#if defined(ENABLE_THREADS) - codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase); -#endif + + CODEGEN_CRITICAL_SECTION_START; + M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ALD(REG_ITMP2, REG_PV, disp); if (s1 != REG_ITMP1) { M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); -#if defined(ENABLE_THREADS) - codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); -#endif + + CODEGEN_CRITICAL_SECTION_END; + M_SUB(REG_ITMP3, REG_ITMP1, REG_ITMP3); + M_EXTSW(REG_ITMP3, REG_ITMP3); } else { M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_SUB(REG_ITMP3, REG_ITMP2, REG_ITMP3); + M_EXTSW(REG_ITMP3, REG_ITMP3); M_ALD(REG_ITMP2, REG_PV, disp); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); -#if defined(ENABLE_THREADS) - codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); -#endif + + CODEGEN_CRITICAL_SECTION_END; + } - M_CMP(REG_ITMP3, REG_ITMP2); - M_BGT(0); - codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */ + M_CMPU(REG_ITMP3, REG_ITMP2); + emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1); + + if (super != NULL) + emit_label(cd, BRANCH_LABEL_5); + } + + if (super == NULL) { + emit_label(cd, BRANCH_LABEL_1); + emit_label(cd, BRANCH_LABEL_4); } d = codegen_reg_of_dst(jd, iptr, s1); } else { /* array type cast-check */ - s1 = emit_load_s1(jd, iptr, rd->argintregs[0]); - M_INTMOVE(s1, rd->argintregs[0]); + s1 = emit_load_s1(jd, iptr, REG_A0); + M_INTMOVE(s1, REG_A0); - disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + disp = dseg_add_unique_address(cd, NULL); codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; + } else { + disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); } - M_ALD(rd->argintregs[1], REG_PV, disp); - disp = dseg_addaddress(cd, BUILTIN_arraycheckcast); + M_ALD(REG_A1, REG_PV, disp); + disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast); M_ALD(REG_ITMP2, REG_PV, disp); M_ALD(REG_ITMP2, REG_ITMP2, 0); /* TOC */ M_MTCTR(REG_ITMP2); M_JSR; M_TST(REG_RESULT); - M_BEQ(0); - codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */ + emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1); s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, s1); @@ -2832,6 +2458,7 @@ gen_method: emit_store_dst(jd, iptr, d); break; + case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */ /* val.a: (classinfo*) superclass */ @@ -2856,17 +2483,16 @@ gen_method: if (INSTRUCTION_IS_UNRESOLVED(iptr)) { super = NULL; superindex = 0; - supervftbl = NULL; } else { super = iptr->sx.s23.s3.c.cls; superindex = super->index; - supervftbl = super->vftbl; } -#if defined(ENABLE_THREADS) - codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase); -#endif + 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) { @@ -2874,53 +2500,34 @@ gen_method: s1 = REG_ITMP1; } - /* calculate interface instanceof code size */ - - s2 = 8; - if (!super) - s2 += (opt_showdisassemble ? 1 : 0); - - /* calculate class instanceof code size */ - - s3 = 10; - if (!super) - s3 += (opt_showdisassemble ? 1 : 0); - M_CLR(d); /* if class is not resolved, check which code to call */ - if (!super) { + if (super == NULL) { M_TST(s1); - M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3); - - disp = dseg_adds4(cd, 0); /* super->flags */ + emit_label_beq(cd, BRANCH_LABEL_1); + disp = dseg_add_unique_s4(cd, 0); /* super->flags */ codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags, iptr->sx.s23.s3.c.ref, disp); - if (opt_showdisassemble) - M_NOP; - M_ILD(REG_ITMP3, REG_PV, disp); M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3); - M_BEQ(s2 + 1); + emit_label_beq(cd, BRANCH_LABEL_2); } /* interface instanceof code */ - if (!super || (super->flags & ACC_INTERFACE)) { - if (super) { - M_TST(s1); - M_BEQ(s2); - - } else { + if ((super == NULL) || (super->flags & ACC_INTERFACE)) { + if (super == NULL) { codegen_addpatchref(cd, - PATCHER_checkcast_instanceof_interface, + PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0); - if (opt_showdisassemble) - M_NOP; + } else { + M_TST(s1); + emit_label_beq(cd, BRANCH_LABEL_3); } M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl)); @@ -2934,46 +2541,58 @@ gen_method: M_BEQ(1); M_IADD_IMM(REG_ZERO, 1, d); - if (!super) - M_BR(s3); + if (super == NULL) { + emit_label_br(cd, BRANCH_LABEL_4); + } else { + emit_label(cd, BRANCH_LABEL_3); + } } /* class instanceof code */ - if (!super || !(super->flags & ACC_INTERFACE)) { - disp = dseg_addaddress(cd, supervftbl); + if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { - if (super) { - M_TST(s1); - M_BEQ(s3); + if (super == NULL) { + emit_label(cd, BRANCH_LABEL_2); - } else { + disp = dseg_add_unique_address(cd, NULL); codegen_addpatchref(cd, PATCHER_instanceof_class, iptr->sx.s23.s3.c.ref, disp); - if (opt_showdisassemble) { - M_NOP; - } + } else { + disp = dseg_add_address(cd, super->vftbl); + M_TST(s1); + emit_label_beq(cd, BRANCH_LABEL_5); } M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl)); M_ALD(REG_ITMP2, REG_PV, disp); -#if defined(ENABLE_THREADS) - codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase); -#endif + + 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)); -#if defined(ENABLE_THREADS) - codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); -#endif + + CODEGEN_CRITICAL_SECTION_END; + M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); + M_EXTSW(REG_ITMP1, REG_ITMP1); M_CMPU(REG_ITMP1, REG_ITMP2); M_CLR(d); M_BGT(1); M_IADD_IMM(REG_ZERO, 1, d); + + if (super != NULL) + emit_label(cd, BRANCH_LABEL_5); } + + if (super == NULL) { + emit_label(cd, BRANCH_LABEL_1); + emit_label(cd, BRANCH_LABEL_4); + } + emit_store_dst(jd, iptr, d); } break; @@ -2986,61 +2605,55 @@ gen_method: for (s1 = iptr->s1.argcount; --s1 >= 0; ) { - src = iptr->sx.s23.s2.args[s1]; + var = VAR(iptr->sx.s23.s2.args[s1]); /* copy SAVEDVAR sizes to stack */ - if (src->varkind != ARGVAR) { - s2 = emit_load(jd, iptr, src, REG_ITMP1); + if (!(var->flags & PREALLOC)) { + s2 = emit_load(jd, iptr, var, REG_ITMP1); #if defined(__DARWIN__) - M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4); + M_LST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 8); #else - M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4); + M_LST(s2, REG_SP, LA_SIZE + (s1 + 3) * 8); #endif } } /* a0 = dimension count */ - ICONST(rd->argintregs[0], iptr->s1.argcount); + ICONST(REG_A0, iptr->s1.argcount); /* is patcher function set? */ if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - disp = dseg_addaddress(cd, NULL); + disp = dseg_add_unique_address(cd, NULL); codegen_addpatchref(cd, PATCHER_builtin_multianewarray, iptr->sx.s23.s3.c.ref, disp); - - if (opt_showdisassemble) - M_NOP; - } else { - disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls); + disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); } /* a1 = arraydescriptor */ - M_ALD(rd->argintregs[1], REG_PV, disp); + M_ALD(REG_A1, REG_PV, disp); /* a2 = pointer to dimensions = stack pointer */ #if defined(__DARWIN__) - M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 4); + M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 8); #else - M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 4); + M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 8); #endif - disp = dseg_addaddress(cd, BUILTIN_multianewarray); + disp = dseg_add_functionptr(cd, BUILTIN_multianewarray); M_ALD(REG_ITMP3, REG_PV, disp); + M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ M_MTCTR(REG_ITMP3); M_JSR; /* check for exception before result assignment */ - - M_CMPI(REG_RESULT, 0); - M_BEQ(0); - codegen_add_fillinstacktrace_ref(cd); + emit_exception_check(cd, iptr); d = codegen_reg_of_dst(jd, iptr, REG_RESULT); M_INTMOVE(REG_RESULT, d); @@ -3048,270 +2661,22 @@ gen_method: break; default: - *exceptionptr = - new_internalerror("Unknown ICMD %d during code generation", - iptr->opc); + exceptions_throw_internalerror("Unknown ICMD %d during code generation", + iptr->opc); return false; } /* switch */ } /* for instruction */ - /* copy values to interface registers */ - - len = bptr->outdepth; - MCODECHECK(64 + len); -#if defined(ENABLE_LSRA) - if (!opt_lsra) -#endif - while (len) { - len--; - src = bptr->outvars[len]; - if ((src->varkind != STACKVAR)) { - s2 = src->type; - if (IS_FLT_DBL_TYPE(s2)) { - s1 = emit_load(jd, iptr, src, REG_FTMP1); - if (!(rd->interfaces[len][s2].flags & INMEMORY)) - M_FLTMOVE(s1, rd->interfaces[len][s2].regoff); - else - M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4); - - } else { - s1 = emit_load(jd, iptr, src, REG_ITMP1); - if (!(rd->interfaces[len][s2].flags & INMEMORY)) { - if (IS_2_WORD_TYPE(s2)) - M_LNGMOVE(s1, rd->interfaces[len][s2].regoff); - else - M_INTMOVE(s1, rd->interfaces[len][s2].regoff); - - } else { - if (IS_2_WORD_TYPE(s2)) - M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4); - else - M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4); - } - } - } - } } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ dseg_createlinenumbertable(cd); + /* generate stubs */ - /* generate exception and patcher stubs */ - - { - exceptionref *eref; - patchref *pref; - u4 mcode; - u1 *savedmcodeptr; - u1 *tmpmcodeptr; - - savedmcodeptr = NULL; - - /* generate exception stubs */ - - for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) { - gen_resolvebranch(cd->mcodebase + eref->branchpos, - eref->branchpos, cd->mcodeptr - cd->mcodebase); - - MCODECHECK(100); - - /* Check if the exception is an - ArrayIndexOutOfBoundsException. If so, move index register - into REG_ITMP1. */ - - if (eref->reg != -1) - M_MOV(eref->reg, REG_ITMP1); - - /* calcuate exception address */ - - M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4); - - /* move function to call into REG_ITMP3 */ - - disp = dseg_addaddress(cd, eref->function); - M_ALD(REG_ITMP3, REG_PV, disp); - M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ - - if (savedmcodeptr != NULL) { - disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1); - M_BR(disp); - - } else { - savedmcodeptr = cd->mcodeptr; - - if (jd->isleafmethod) { - M_MFLR(REG_ZERO); - M_AST(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET); - } - - M_MOV(REG_PV, rd->argintregs[0]); - M_MOV(REG_SP, rd->argintregs[1]); - - if (jd->isleafmethod) - M_MOV(REG_ZERO, rd->argintregs[2]); - else - M_ALD(rd->argintregs[2], - REG_SP, stackframesize * 8 + LA_LR_OFFSET); - - M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); - M_MOV(REG_ITMP1, rd->argintregs[4]); - - M_STDU(REG_SP, REG_SP, -(LA_SIZE + 6 * 8)); - M_AST(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8); - - M_MTCTR(REG_ITMP3); - M_JSR; - M_MOV(REG_RESULT, REG_ITMP1_XPTR); - - M_ALD(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8); - M_LADD_IMM(REG_SP, LA_SIZE + 6 * 8, REG_SP); - - if (jd->isleafmethod) { - /* XXX FIXME: REG_ZERO can cause problems here! */ - assert(stackframesize * 8 <= 32767); - - M_ALD(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET); - M_MTLR(REG_ZERO); - } - - disp = dseg_addaddress(cd, asm_handle_exception); - M_ALD(REG_ITMP3, REG_PV, disp); - M_MTCTR(REG_ITMP3); - M_RTS; - } - } - - - /* generate code patching stub call code */ - - for (pref = cd->patchrefs; pref != NULL; pref = pref->next) { - /* check code segment size */ - - MCODECHECK(16); - - /* Get machine code which is patched back in later. The - call is 1 instruction word long. */ - - tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos); - - mcode = *((u4 *) tmpmcodeptr); - - /* Patch in the call to call the following code (done at - compile time). */ - - savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */ - cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */ - - disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1); - M_BR(disp); - - cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */ - - /* create stack frame - keep stack 16-byte aligned */ - - M_AADD_IMM(REG_SP, -8 * 8, REG_SP); - - /* calculate return address and move it onto the stack */ - - M_LDA(REG_ITMP3, REG_PV, pref->branchpos); - M_AST_INTERN(REG_ITMP3, REG_SP, 5 * 8); - - /* move pointer to java_objectheader onto stack */ - -#if defined(ENABLE_THREADS) - /* order reversed because of data segment layout */ - - (void) dseg_addaddress(cd, NULL); /* flcword */ - (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */ - disp = dseg_addaddress(cd, NULL); /* vftbl */ - - M_LDA(REG_ITMP3, REG_PV, disp); - M_AST_INTERN(REG_ITMP3, REG_SP, 4 * 8); -#else - /* do nothing */ -#endif - - /* move machine code onto stack */ - - disp = dseg_adds4(cd, mcode); - M_ILD(REG_ITMP3, REG_PV, disp); - M_IST_INTERN(REG_ITMP3, REG_SP, 3 * 8); - - /* move class/method/field reference onto stack */ - - disp = dseg_addaddress(cd, pref->ref); - M_ALD(REG_ITMP3, REG_PV, disp); - M_AST_INTERN(REG_ITMP3, REG_SP, 2 * 8); - - /* move data segment displacement onto stack */ - - disp = dseg_addaddress(cd, pref->disp); - M_LLD(REG_ITMP3, REG_PV, disp); - M_IST_INTERN(REG_ITMP3, REG_SP, 1 * 8); - - /* move patcher function pointer onto stack */ - - disp = dseg_addaddress(cd, pref->patcher); - M_ALD(REG_ITMP3, REG_PV, disp); - M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 8); - - disp = dseg_addaddress(cd, asm_patcher_wrapper); - M_ALD(REG_ITMP3, REG_PV, disp); - M_MTCTR(REG_ITMP3); - M_RTS; - } - - /* generate replacement-out stubs */ - -#if 0 - { - int i; - - replacementpoint = jd->code->rplpoints; - - for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) { - /* check code segment size */ - - MCODECHECK(100); - - /* note start of stub code */ - - replacementpoint->outcode = (u1 *) (cd->mcodeptr - cd->mcodebase); - - /* make machine code for patching */ - - tmpmcodeptr = cd->mcodeptr; - cd->mcodeptr = (u1 *) &(replacementpoint->mcode) + 1 /* big-endian */; - - disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1; - M_BR(disp); - - cd->mcodeptr = tmpmcodeptr; - - /* create stack frame - keep 16-byte aligned */ - - M_AADD_IMM(REG_SP, -4 * 4, REG_SP); - - /* push address of `rplpoint` struct */ - - disp = dseg_addaddress(cd, replacementpoint); - M_ALD(REG_ITMP3, REG_PV, disp); - M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 4); - - /* jump to replacement function */ - - disp = dseg_addaddress(cd, asm_replacement_out); - M_ALD(REG_ITMP3, REG_PV, disp); - M_MTCTR(REG_ITMP3); - M_RTS; - } - } -#endif - } - - codegen_finish(jd); + emit_patcher_stubs(jd); + REPLACEMENT_EMIT_STUBS(jd); /* everything's ok */ @@ -3319,95 +2684,54 @@ gen_method: } -/* createcompilerstub ********************************************************** +/* codegen_emit_stub_compiler ************************************************** - Creates a stub routine which calls the compiler. + Emits a stub routine which calls the compiler. *******************************************************************************/ -#define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P -#define COMPILERSTUB_CODESIZE 4 * 4 - -#define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE - - -u1 *createcompilerstub(methodinfo *m) +void codegen_emit_stub_compiler(jitdata *jd) { - u1 *s; /* memory to hold the stub */ - ptrint *d; - codeinfo *code; + methodinfo *m; codegendata *cd; - s4 dumpsize; - - s = CNEW(u1, COMPILERSTUB_SIZE); - - /* set data pointer and code pointer */ - - d = (ptrint *) s; - s = s + COMPILERSTUB_DATASIZE; - - /* mark start of dump memory area */ - dumpsize = dump_size(); - - cd = DNEW(codegendata); - cd->mcodeptr = s; - - /* Store the codeinfo pointer in the same place as in the - methodheader for compiled methods. */ + /* get required compiler data */ - code = code_codeinfo_new(m); + m = jd->m; + cd = jd->cd; - d[0] = (ptrint) asm_call_jit_compiler; - d[1] = (ptrint) m; - d[2] = (ptrint) code; + /* 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; - - md_cacheflush((u1 *) d, COMPILERSTUB_SIZE); - -#if defined(ENABLE_STATISTICS) - if (opt_stat) - count_cstub_len += COMPILERSTUB_SIZE; -#endif - - /* release dump area */ - - dump_release(dumpsize); - - return s; } -/* createnativestub ************************************************************ +/* codegen_emit_stub_native **************************************************** - Creates a stub routine which calls a native method. + Emits a stub routine which calls a native method. *******************************************************************************/ -u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) +void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) { - methodinfo *m; - codeinfo *code; - codegendata *cd; - registerdata *rd; - s4 stackframesize; /* size of stackframe if needed */ - methoddesc *md; - s4 nativeparams; - s4 i, j; /* count variables */ - s4 t; - s4 s1, s2, disp; - s4 funcdisp; + methodinfo *m; + codeinfo *code; + codegendata *cd; + methoddesc *md; + s4 nativeparams; + s4 i, j; + s4 t; + s4 s1, s2, disp; + s4 funcdisp; /* get required compiler data */ m = jd->m; code = jd->code; cd = jd->cd; - rd = jd->rd; /* set some variables */ @@ -3416,31 +2740,31 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) /* calculate stackframe size */ - stackframesize = + cd->stackframesize = sizeof(stackframeinfo) / SIZEOF_VOID_P + sizeof(localref_table) / SIZEOF_VOID_P + 4 + /* 4 stackframeinfo arguments (darwin)*/ nmd->paramcount + nmd->memuse; - stackframesize = (stackframesize + 3) & ~3; /* keep stack 16-byte aligned */ +/* cd->stackframesize = (cd->stackframesize + 3) & ~3;*/ /* keep stack 16-byte aligned */ /* create method header */ - (void) dseg_addaddress(cd, code); /* CodeinfoPointer */ - (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */ - (void) dseg_adds4(cd, 0); /* IsSync */ - (void) dseg_adds4(cd, 0); /* IsLeaf */ - (void) dseg_adds4(cd, 0); /* IntSave */ - (void) dseg_adds4(cd, 0); /* FltSave */ + (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_adds4(cd, 0); /* ExTableSize */ + (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */ /* generate code */ M_MFLR(REG_ZERO); M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET); - M_STDU(REG_SP, REG_SP, -(stackframesize * 8)); + M_STDU(REG_SP, REG_SP, -(cd->stackframesize * 8)); #if !defined(NDEBUG) if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { @@ -3449,14 +2773,11 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) #endif /* get function address (this must happen before the stackframeinfo) */ - funcdisp = dseg_addaddress(cd, f); + funcdisp = dseg_add_functionptr(cd, f); #if !defined(WITH_STATIC_CLASSPATH) if (f == NULL) { codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp); - - if (opt_showdisassemble) - M_NOP; } #endif @@ -3470,7 +2791,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (IS_INT_LNG_TYPE(t)) { if (!md->params[i].inmemory) { s1 = md->params[i].regoff; - M_LST(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); + M_LST(s1, REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8); j++; } } @@ -3480,7 +2801,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) { if (!md->params[i].inmemory) { s1 = md->params[i].regoff; - M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); + M_DST(s1, REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8); j++; } } @@ -3488,11 +2809,11 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) /* create native stack info */ - M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]); - M_MOV(REG_PV, rd->argintregs[1]); - M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]); - M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 + LA_LR_OFFSET); - disp = dseg_addaddress(cd, codegen_start_native_call); + M_AADD_IMM(REG_SP, cd->stackframesize * 8, 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 */ @@ -3509,7 +2830,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (IS_INT_LNG_TYPE(t)) { if (!md->params[i].inmemory) { s1 = md->params[i].regoff; - M_LLD(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); + M_LLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); j++; } } @@ -3519,7 +2840,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) { if (!md->params[i].inmemory) { s1 = md->params[i].regoff; - M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); + M_DLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); j++; } } @@ -3532,40 +2853,36 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) if (IS_INT_LNG_TYPE(t)) { if (!md->params[i].inmemory) { - s1 = rd->argintregs[md->params[i].regoff]; + s1 = md->params[i].regoff; + s2 = nmd->params[j].regoff; - if (!nmd->params[j].inmemory) { - s2 = rd->argintregs[nmd->params[j].regoff]; + if (!nmd->params[j].inmemory) M_INTMOVE(s1, s2); - } else { - s2 = nmd->params[j].regoff; + else M_LST(s1, REG_SP, s2 * 8); - } - - } else { - s1 = md->params[i].regoff + stackframesize; + } + else { + s1 = md->params[i].regoff + cd->stackframesize; s2 = nmd->params[j].regoff; M_LLD(REG_ITMP1, REG_SP, s1 * 8); M_LST(REG_ITMP1, REG_SP, s2 * 8); } - - } else { + } + else { /* We only copy spilled float arguments, as the float argument registers keep unchanged. */ if (md->params[i].inmemory) { - s1 = md->params[i].regoff + stackframesize; + s1 = md->params[i].regoff + cd->stackframesize; s2 = nmd->params[j].regoff; - if (IS_2_WORD_TYPE(t)) { - M_DLD(REG_FTMP1, REG_SP, s1 * 8); - M_DST(REG_FTMP1, REG_SP, s2 * 8); + M_DLD(REG_FTMP1, REG_SP, s1 * 8); - } else { - M_FLD(REG_FTMP1, REG_SP, s1 * 8); - M_FST(REG_FTMP1, REG_SP, s2 * 8); - } + if (IS_2_WORD_TYPE(t)) + M_DST(REG_FTMP1, REG_SP, s2 * 8); + else + M_FST(REG_FTMP1, REG_SP, s2 * 8 + 4); } } } @@ -3573,14 +2890,14 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) /* put class into second argument register */ if (m->flags & ACC_STATIC) { - disp = dseg_addaddress(cd, m->class); - M_ALD(rd->argintregs[1], REG_PV, disp); + disp = dseg_add_unique_address(cd, m->class); + M_ALD(REG_A1, REG_PV, disp); } /* put env into first argument register */ - disp = dseg_addaddress(cd, _Jv_env); - M_ALD(rd->argintregs[0], REG_PV, disp); + disp = dseg_add_unique_address(cd, _Jv_env); + M_ALD(REG_A0, REG_PV, disp); /* generate the actual native call */ /* native functions have a different TOC for sure */ @@ -3593,10 +2910,6 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) M_JSR; M_ALD(REG_TOC, REG_SP, 40); /* restore TOC */ - M_NOP; - M_NOP; - M_NOP; - /* save return value */ if (md->returntype.type != TYPE_VOID) { @@ -3604,10 +2917,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); } else { - if (IS_2_WORD_TYPE(md->returntype.type)) - M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); - else - M_FST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); /* FIXME, needed ?*/ + M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); } } @@ -3619,12 +2929,8 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) #endif /* remove native stackframe info */ - M_NOP; - M_NOP; - M_NOP; - - M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]); - disp = dseg_addaddress(cd, codegen_finish_native_call); + M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A0); + 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? */ M_MTCTR(REG_ITMP1); @@ -3638,16 +2944,17 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); } else { - if (IS_2_WORD_TYPE(md->returntype.type)) +/* 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); +/* else + M_FLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); F XXX + */ } } - M_ALD(REG_ITMP2_XPC, REG_SP, stackframesize * 8 + LA_LR_OFFSET); + M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET); M_MTLR(REG_ITMP2_XPC); - M_LDA(REG_SP, REG_SP, stackframesize * 8); /* remove stackframe */ + M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe */ /* check for exception */ @@ -3660,96 +2967,14 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) M_LADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */ - disp = dseg_addaddress(cd, asm_handle_nat_exception); + disp = dseg_add_functionptr(cd, asm_handle_nat_exception); M_ALD(REG_ITMP3, REG_PV, disp); M_MTCTR(REG_ITMP3); M_RTS; /* generate patcher stub call code */ - { - patchref *pref; - u4 mcode; - u1 *savedmcodeptr; - u1 *tmpmcodeptr; - - for (pref = cd->patchrefs; pref != NULL; pref = pref->next) { - /* Get machine code which is patched back in later. The - call is 1 instruction word long. */ - - tmpmcodeptr = cd->mcodebase + pref->branchpos; - - mcode = *((u4 *) tmpmcodeptr); - - /* Patch in the call to call the following code (done at - compile time). */ - - savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */ - cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */ - - disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1); - M_BL(disp); - - cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */ - - /* create stack frame - keep stack 16-byte aligned */ - - M_AADD_IMM(REG_SP, -8 * 8, REG_SP); - - /* move return address onto stack */ - - M_MFLR(REG_ZERO); - M_AST(REG_ZERO, REG_SP, 5 * 8); - - /* move pointer to java_objectheader onto stack */ - -#if defined(ENABLE_THREADS) - /* order reversed because of data segment layout */ - - (void) dseg_addaddress(cd, NULL); /* flcword */ - (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */ - disp = dseg_addaddress(cd, NULL); /* vftbl */ - - M_LDA(REG_ITMP3, REG_PV, disp); - M_AST(REG_ITMP3, REG_SP, 4 * 8); -#else - /* do nothing */ -#endif - - /* move machine code onto stack */ - - disp = dseg_adds4(cd, mcode); - M_ILD(REG_ITMP3, REG_PV, disp); - M_IST(REG_ITMP3, REG_SP, 3 * 8); - - /* move class/method/field reference onto stack */ - - disp = dseg_addaddress(cd, pref->ref); - M_ALD(REG_ITMP3, REG_PV, disp); - M_AST(REG_ITMP3, REG_SP, 2 * 8); - - /* move data segment displacement onto stack */ - - disp = dseg_adds4(cd, pref->disp); - M_ILD(REG_ITMP3, REG_PV, disp); - M_IST(REG_ITMP3, REG_SP, 1 * 8); - - /* move patcher function pointer onto stack */ - - disp = dseg_addaddress(cd, pref->patcher); - M_ALD(REG_ITMP3, REG_PV, disp); - M_AST(REG_ITMP3, REG_SP, 0 * 8); - - disp = dseg_addaddress(cd, asm_patcher_wrapper); - M_ALD(REG_ITMP3, REG_PV, disp); - M_MTCTR(REG_ITMP3); - M_RTS; - } - } - - codegen_finish(jd); - - return code->entrypoint; + emit_patcher_stubs(jd); }