Christian Ullrich
Edwin Steiner
- $Id: codegen.c 5576 2006-09-28 22:33:48Z edwin $
+ $Id: codegen.c 5618 2006-10-01 23:37:04Z edwin $
*/
s4 len, s1, s2, s3, d, disp;
ptrint a;
s4 stackframesize;
- stackptr src;
varinfo *var;
basicblock *bptr;
instruction *iptr;
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_STD)) {
+ /* d = reg_of_var(m, var, REG_ITMP1); */
+ if (!(var->flags & INMEMORY))
+ d = var->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_STD)) {
+ d = codegen_reg_of_var(rd, 0, var, REG_ITMP1);
M_INTMOVE(REG_ITMP1, d);
- emit_store(jd, NULL, src, d);
+ emit_store(jd, NULL, var, 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);
- }
- }
+ assert((var->flags & OUTVAR));
+ /* will be done directly in simplereg lateron */
+ /* for now codegen_reg_of_var has to be called here to */
+ /* set the regoff and flags for all bptr->invars[] */
+ d = codegen_reg_of_var(0, var, REG_IFTMP);
}
}
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_ISTORE: /* ..., value ==> ... */
case ICMD_ASTORE: /* dst.localindex = local variable */
case ICMD_LSTORE:
-
- 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 */
+ case ICMD_COPY:
+ case ICMD_MOVE:
+ case ICMD_DUP: /* ..., a ==> ..., a, a */
- 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);
- }
+ M_COPY(iptr->s1.varindex, iptr->dst.varindex);
break;
- /* pop/dup/swap operations ********************************************/
+ /* pop 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]);
- 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]);
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;
+ 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, s1);
+ M_IADD(s1, REG_ITMP2, d);
- if (var->flags & INMEMORY)
- M_LST(s1, REG_SP, var->regoff * 8);
+ emit_store_dst(jd, iptr, d);
break;
break;
case ICMD_GOTO: /* ... ==> ... */
+ case ICMD_RET: /* ... ==> ... */
M_BR(0);
codegen_addreference(cd, iptr->dst.block);
ALIGNCODENOP;
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;
- ALIGNCODENOP;
- break;
-
case ICMD_IFNULL: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
/* 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]);
- 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);
+ d = emit_load(jd, iptr, var, s1);
M_LNGMOVE(d, s1);
} else {
- d = emit_load(jd, iptr, src, REG_ITMP1);
+ d = emit_load(jd, iptr, var, REG_ITMP1);
M_LST(d, REG_SP, md->params[s3].regoff * 8);
}
} else {
if (!md->params[s3].inmemory) {
s1 = rd->argfltregs[md->params[s3].regoff];
- d = emit_load(jd, iptr, src, s1);
+ d = emit_load(jd, iptr, var, s1);
M_FLTMOVE(d, s1);
} else {
- d = emit_load(jd, iptr, src, REG_FTMP1);
- if (IS_2_WORD_TYPE(src->type))
+ d = emit_load(jd, iptr, var, REG_FTMP1);
+ if (IS_2_WORD_TYPE(var->type))
M_DST(d, REG_SP, md->params[s3].regoff * 8);
else
M_FST(d, REG_SP, md->params[s3].regoff * 8);
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);
#else
} /* 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 */