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 $
*/
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;
rplpoint *replacementpoint;
s4 fieldtype;
s4 varindex;
+ unresolved_field *uf;
+ fieldinfo *fi;
/* get required compiler data */
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 */
/* 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
/* 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
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);
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);
}
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;
}
}
}
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);
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);
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));
}
}
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;
MCODECHECK(64); /* an instruction usually needs < 64 words */
- /* M_NOP; M_NOP; XXX */
switch (iptr->opc) {
case ICMD_NOP: /* ... ==> ... */
case ICMD_INLINE_START:
/* 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 */
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;
ICONST(REG_ITMP2, iptr->sx.val.i);
M_SUB(s1, REG_ITMP2, d);
}
+ M_EXTSW(d, d);
emit_store_dst(jd, iptr, d);
break;
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);
break;
case ICMD_IDIV:
+ sign_ext = true;
case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
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;
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;
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;
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;
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);
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;
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 ************************************************/
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 ==> ... */
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);
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);
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);
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;
}
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);
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);
}
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:
{
s4 i, p;
- p = stackframesize;
+ p = cd->stackframesize;
/* call trace function */
/* 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;
/* 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);
/* 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)
/* 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);
/* 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));
/* 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));
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? */
}
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);
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
}
}
/* 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);
/* 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;
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]);
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]);
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);
}
codeinfo *code;
codegendata *cd;
registerdata *rd;
- s4 stackframesize; /* size of stackframe if needed */
methoddesc *md;
s4 nativeparams;
s4 i, j; /* count variables */
/* 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 */
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)) {
/* 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);
}
} 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);
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_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) {
#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? */
}
}
- 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 */