X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc64%2Fcodegen.c;h=f131e30ce5c3f8e438480b1a0f53993e1a599da8;hb=14116781d3d6ce83e5c549afd155f9dc4e0fbcdc;hp=62ed26322ed1362f2850eead6152cadf2041804d;hpb=570368d70c6cc296e8cf850b2f72d3d218549b80;p=cacao.git diff --git a/src/vm/jit/powerpc64/codegen.c b/src/vm/jit/powerpc64/codegen.c index 62ed26322..f131e30ce 100644 --- a/src/vm/jit/powerpc64/codegen.c +++ b/src/vm/jit/powerpc64/codegen.c @@ -30,8 +30,9 @@ Changes: Christian Thalinger Christian Ullrich Edwin Steiner + Roland Lezuo - $Id: codegen.c 5632 2006-10-02 13:43:15Z edwin $ + $Id: codegen.c 5928 2006-11-06 16:38:31Z tbfg $ */ @@ -88,11 +89,10 @@ bool codegen(jitdata *jd) registerdata *rd; s4 len, s1, s2, s3, d, disp; ptrint a; - s4 stackframesize; varinfo *var; basicblock *bptr; instruction *iptr; - exceptiontable *ex; + exception_entry *ex; u2 currentline; methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ builtintable_entry *bte; @@ -100,6 +100,8 @@ bool codegen(jitdata *jd) rplpoint *replacementpoint; s4 fieldtype; s4 varindex; + unresolved_field *uf; + fieldinfo *fi; /* get required compiler data */ @@ -125,7 +127,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 +136,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 +145,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_adds4(cd, cd->stackframesize * 8); /* FrameSize */ #if defined(ENABLE_THREADS) /* IsSync contains the offset relative to the stack pointer for the @@ -171,11 +174,11 @@ bool codegen(jitdata *jd) dseg_addlinenumbertablesize(cd); - (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */ + (void) dseg_adds4(cd, jd->exceptiontablelength); /* ExTableSize */ /* create exception table */ - for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) { + for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) { dseg_addtarget(cd, ex->start); dseg_addtarget(cd, ex->end); dseg_addtarget(cd, ex->handler); @@ -189,12 +192,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,92 +211,45 @@ 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; + var = VAR(varindex); 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); - + s2 = rd->argintregs[s1]; + if (!IS_INMEMORY(var->flags)) { + M_INTMOVE(s2, var->vv.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); - } - + M_LST(s2, REG_SP, var->vv.regoff * 8); + } } 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); + if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */ + M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); } 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 + var->vv.regoff = cd->stackframesize + s1; } } } 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); - + if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */ + M_FLTMOVE(s2, var->vv.regoff); } else { /* reg arg -> spilled */ - if (IS_2_WORD_TYPE(t)) - M_DST(s2, REG_SP, var->regoff * 4); - else - M_FST(s2, REG_SP, var->regoff * 4); + M_DST(s2, REG_SP, var->vv.regoff * 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); - + M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8); } 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 + var->vv.regoff = cd->stackframesize + s1; } } } @@ -367,7 +323,7 @@ bool codegen(jitdata *jd) replacementpoint = jd->code->rplpoints; /* 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); @@ -404,10 +360,10 @@ bool codegen(jitdata *jd) while (len) { len--; var = VAR(bptr->invars[len]); - if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) { + if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) { /* d = reg_of_var(m, var, REG_ITMP1); */ if (!(var->flags & INMEMORY)) - d = var->regoff; + d = var->vv.regoff; else d = REG_ITMP1; M_INTMOVE(REG_ITMP1, d); @@ -419,13 +375,13 @@ bool codegen(jitdata *jd) while (len) { len--; var = VAR(bptr->invars[len]); - if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) { + 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, var, d); } else { - assert((var->flags & OUTVAR)); + assert((var->flags & INOUT)); } } @@ -438,6 +394,7 @@ bool codegen(jitdata *jd) currentline = 0; for (iptr = bptr->iinstr; len > 0; len--, iptr++) { + bool sign_ext = false; if (iptr->line != currentline) { dseg_addlinenumber(cd, iptr->line); currentline = iptr->line; @@ -445,7 +402,6 @@ 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: @@ -542,20 +498,15 @@ bool codegen(jitdata *jd) /* integer operations *************************************************/ case ICMD_INEG: /* ..., value ==> ..., - value */ - + sign_ext = true; + case ICMD_LNEG: s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_NEG(s1, d); + if (sign_ext) M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; - case ICMD_LNEG: /* ..., value ==> ..., - value */ - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); - M_NEG(s1, d); /* XXX */ - emit_store_dst(jd, iptr, d); - break; case ICMD_I2L: /* ..., value ==> ..., value */ @@ -608,17 +559,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; @@ -666,6 +618,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; @@ -684,7 +637,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); @@ -694,6 +647,7 @@ bool codegen(jitdata *jd) break; case ICMD_IDIV: + sign_ext = true; case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); @@ -704,32 +658,54 @@ bool codegen(jitdata *jd) codegen_add_arithmeticexception_ref(cd); 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 */ + if (!sign_ext) { + 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 */ + } + if (sign_ext) M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; case ICMD_IREM: + sign_ext = true; 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); - /* 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); - emit_store_dst(jd, iptr, d); + 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 */ + if (!sign_ext) { + 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); + + M_MOV(REG_ITMP3, d); + emit_store_dst(jd, iptr, REG_ITMP1); break; + case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */ - + sign_ext = true; + 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); M_MUL(s1, s2, d); + if (sign_ext) M_EXTSW(d, d); emit_store_dst(jd, iptr, d); break; @@ -744,6 +720,18 @@ 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; @@ -763,6 +751,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; @@ -772,6 +761,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; @@ -868,7 +858,6 @@ 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); M_MOV(s1, REG_ITMP2); @@ -888,6 +877,7 @@ 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; @@ -978,19 +968,6 @@ bool codegen(jitdata *jd) break; break; - case ICMD_IINC: /* ..., value ==> ..., value + constant */ - /* s1.localindex = variable, sx.val.i = constant*/ - - d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - - /* XXX implement me more efficiently */ - ICONST(REG_ITMP2, iptr->sx.val.i); - M_IADD(s1, REG_ITMP2, d); - - emit_store_dst(jd, iptr, d); - break; - /* floating operations ************************************************/ @@ -1464,7 +1441,7 @@ bool codegen(jitdata *jd) 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); + M_LSTX(s3, s1, REG_ITMP2); break; case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */ @@ -1530,7 +1507,7 @@ 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); @@ -1562,9 +1539,8 @@ bool codegen(jitdata *jd) M_ILD_INTERN(d, REG_ITMP1, 0); break; case TYPE_LNG: - d = codegen_reg_of_dst(jd, iptr, 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); @@ -1586,7 +1562,7 @@ 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); @@ -1643,21 +1619,17 @@ bool codegen(jitdata *jd) 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; + disp = 0; - codegen_addpatchref(cd, PATCHER_get_putfield, - iptr->sx.s23.s3.uf, 0); + codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); if (opt_showdisassemble) M_NOP; - disp = 0; - } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = fi->offset; } @@ -1692,32 +1664,31 @@ bool codegen(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ITMP1); gen_nullptr_check(s1); - if (!IS_FLT_DBL_TYPE(fieldtype)) { + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + 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; + } + + if (IS_INT_LNG_TYPE(fieldtype)) { s2 = emit_load_s2(jd, iptr, REG_ITMP2); - } else { - s2 = emit_load_s2(jd, iptr, REG_FTMP2); } + else + s2 = emit_load_s2(jd, iptr, REG_FTMP2); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - unresolved_field *uf = iptr->sx.s23.s3.uf; - - fieldtype = uf->fieldref->parseddesc.fd->type; - - codegen_addpatchref(cd, PATCHER_get_putfield, - iptr->sx.s23.s3.uf, 0); + codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); if (opt_showdisassemble) M_NOP; - - disp = 0; - - } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; - - fieldtype = fi->type; - disp = fi->offset; } + switch (fieldtype) { case TYPE_INT: M_IST(s2, s1, disp); @@ -1778,17 +1749,11 @@ bool codegen(jitdata *jd) 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); + ALIGNCODENOP; break; - + case ICMD_IFNULL: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); @@ -1841,159 +1806,50 @@ bool codegen(jitdata *jd) } codegen_addreference(cd, iptr->dst.block); 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); - } + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); M_BEQ(0); codegen_addreference(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); - } + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); M_BLT(0); codegen_addreference(cd, iptr->dst.block); break; - case ICMD_IF_LLE: /* ..., 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_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); - } + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); 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); - } + 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); M_BNE(0); codegen_addreference(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); + 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); + M_BGE(0); codegen_addreference(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); + case ICMD_IF_LGT: /* ..., value ==> ... */ + s1 = emit_load_s1(jd, iptr, REG_ITMP1); + LCONST(REG_ITMP2, iptr->sx.val.l); + M_CMP(s1, REG_ITMP2); + M_BGT(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: @@ -2095,7 +1951,7 @@ nowperformreturn: { s4 i, p; - p = stackframesize; + p = cd->stackframesize; /* call trace function */ @@ -2172,8 +2028,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; @@ -2222,7 +2078,7 @@ nowperformreturn: /* length of dataseg after last dseg_addtarget 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); @@ -2478,18 +2334,14 @@ 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) @@ -2500,18 +2352,18 @@ gen_method: /* calculate interface checkcast code size */ s2 = 7; - if (!super) + if (super == NULL) s2 += (opt_showdisassemble ? 1 : 0); /* calculate class checkcast code size */ - s3 = 8 + (s1 == REG_ITMP1); - if (!super) + s3 = 9 + (s1 == REG_ITMP1); + if (super == NULL) s3 += (opt_showdisassemble ? 1 : 0); /* 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); @@ -2532,19 +2384,18 @@ gen_method: /* 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, iptr->sx.s23.s3.c.ref, 0); - if (opt_showdisassemble) M_NOP; + + } else { + M_TST(s1); + M_BEQ(s2); } M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); @@ -2565,20 +2416,18 @@ gen_method: /* class checkcast code */ - if (!super || !(super->flags & ACC_INTERFACE)) { - disp = dseg_addaddress(cd, supervftbl); - - if (super) { - M_TST(s1); - M_BEQ(s3); - - } else { + if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { + if (super == NULL) { + 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_addaddress(cd, super->vftbl); + M_TST(s1); + M_BEQ(s3); } M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); @@ -2594,16 +2443,18 @@ gen_method: codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); #endif 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 } - M_CMP(REG_ITMP3, REG_ITMP2); + M_CMPU(REG_ITMP3, REG_ITMP2); M_BGT(0); codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */ } @@ -2615,15 +2466,17 @@ gen_method: s1 = emit_load_s1(jd, iptr, rd->argintregs[0]); M_INTMOVE(s1, rd->argintregs[0]); - disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + disp = dseg_addaddress(cd, NULL); codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast, iptr->sx.s23.s3.c.ref, disp); if (opt_showdisassemble) M_NOP; + } else { + disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls); } M_ALD(rd->argintregs[1], REG_PV, disp); @@ -2804,9 +2657,9 @@ gen_method: 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 } } @@ -2818,7 +2671,7 @@ gen_method: /* 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); @@ -2837,13 +2690,14 @@ gen_method: /* a2 = pointer to dimensions = stack pointer */ #if defined(__DARWIN__) - M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 4); + M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 8); #else - M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 4); + M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 8); #endif disp = dseg_addaddress(cd, BUILTIN_multianewarray); M_ALD(REG_ITMP3, REG_PV, disp); + M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ M_MTCTR(REG_ITMP3); M_JSR; @@ -2918,7 +2772,7 @@ gen_method: if (jd->isleafmethod) { M_MFLR(REG_ZERO); - M_AST(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET); + M_AST(REG_ZERO, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET); } M_MOV(REG_PV, rd->argintregs[0]); @@ -2928,7 +2782,7 @@ gen_method: M_MOV(REG_ZERO, rd->argintregs[2]); else M_ALD(rd->argintregs[2], - REG_SP, stackframesize * 8 + LA_LR_OFFSET); + REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET); M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); M_MOV(REG_ITMP1, rd->argintregs[4]); @@ -2945,9 +2799,9 @@ gen_method: if (jd->isleafmethod) { /* XXX FIXME: REG_ZERO can cause problems here! */ - assert(stackframesize * 8 <= 32767); + assert(cd->stackframesize * 8 <= 32767); - M_ALD(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET); + M_ALD(REG_ZERO, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET); M_MTLR(REG_ZERO); } @@ -3169,7 +3023,6 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) codeinfo *code; codegendata *cd; registerdata *rd; - s4 stackframesize; /* size of stackframe if needed */ methoddesc *md; s4 nativeparams; s4 i, j; /* count variables */ @@ -3191,19 +3044,19 @@ 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, cd->stackframesize * 8); /* FrameSize */ (void) dseg_adds4(cd, 0); /* IsSync */ (void) dseg_adds4(cd, 0); /* IsLeaf */ (void) dseg_adds4(cd, 0); /* IntSave */ @@ -3215,7 +3068,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) 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)) { @@ -3263,10 +3116,10 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) /* create native stack info */ - M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]); + M_AADD_IMM(REG_SP, cd->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); + M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[2]); + M_ALD(rd->argintregs[3], REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET); disp = dseg_addaddress(cd, codegen_start_native_call); M_ALD(REG_ITMP1, REG_PV, disp); @@ -3318,7 +3171,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) } } else { - s1 = md->params[i].regoff + stackframesize; + s1 = md->params[i].regoff + cd->stackframesize; s2 = nmd->params[j].regoff; M_LLD(REG_ITMP1, REG_SP, s1 * 8); @@ -3330,7 +3183,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) 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)) { @@ -3368,10 +3221,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) { @@ -3394,11 +3243,7 @@ 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]); + M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[0]); disp = dseg_addaddress(cd, codegen_finish_native_call); M_ALD(REG_ITMP1, REG_PV, disp); M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */ @@ -3420,9 +3265,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) } } - 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 */