{REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 0, 0},
{REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 0, 0},
{REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 0, 0},
- {REG_CND, CND_IDX, REG_GPR, "C", "C", "xreg", 0, 0, 0},
+ {REG_CND, CND_IDX, REG_GPR, "C", "psw", "xreg", 0, 0, 0},
+ {0, DPL1_IDX, 0, "dpl1", "dpl1", "dpl1", 0, 0, 0},
+ {0, DPH1_IDX, 0, "dph1", "dph1", "dph1", 0, 0, 0},
+ {0, DPX1_IDX, 0, "dpx1", "dpx1", "dpx1", 0, 0, 0},
+ {0, DPS_IDX, 0, "dps", "dps", "dps", 0, 0, 0},
+ {0, A_IDX, 0, "a", "acc", "acc", 0, 0, 0},
+ {0, AP_IDX, 0, "ap", "ap", "ap", 0, 0, 0},
};
int ds390_nRegs = 13;
static void spillThis (symbol *);
{
int i;
- for (i = 0; i < ds390_nRegs; i++)
+ for (i = 0; i < sizeof(regs390)/sizeof(regs); i++)
if (regs390[i].rIdx == idx)
return ®s390[i];
}
- setToNull ((void **) &sset);
+ setToNull ((void *) &sset);
sym->blockSpil = 0;
return sym;
}
sym->regs[i] = NULL;
}
- /* if spilt on stack then free up r0 & r1
+ /* if spilt on stack then free up r0 & r1
if they could have been assigned to some
LIVE ranges */
- if (!ds390_ptrRegReq && isSpiltOnStack (sym))
+ if (!ds390_ptrRegReq && isSpiltOnStack (sym) && !options.stack10bit)
{
- ds390_ptrRegReq += !options.stack10bit;
+ ds390_ptrRegReq ++;
spillLRWithPtrReg (sym);
}
getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
{
regs *reg;
+ int j;
tryAgain:
/* try for a ptr type */
if (!spilSomething (ic, ebp, sym))
return NULL;
+ /* make sure partially assigned registers aren't reused */
+ for (j=0; j<=sym->nRegs; j++)
+ if (sym->regs[j])
+ sym->regs[j]->isFree = 0;
+
/* this looks like an infinite loop but
in really selectSpil will abort */
goto tryAgain;
getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
{
regs *reg;
+ int j;
tryAgain:
/* try for gpr type */
if (!spilSomething (ic, ebp, sym))
return NULL;
+ /* make sure partially assigned registers aren't reused */
+ for (j=0; j<=sym->nRegs; j++)
+ if (sym->regs[j])
+ sym->regs[j]->isFree = 0;
+
/* this looks like an infinite loop but
in really selectSpil will abort */
goto tryAgain;
}
}
+/*------------------------------------------------------------------*/
+/* verifyRegsAssigned - make sure an iTemp is properly initialized; */
+/* it should either have registers or have beed spilled. Otherwise, */
+/* there was an uninitialized variable, so just spill this to get */
+/* the operand in a valid state. */
+/*------------------------------------------------------------------*/
+static void
+verifyRegsAssigned (operand *op, iCode * ic)
+{
+ symbol * sym;
+
+ if (!op) return;
+ if (!IS_ITEMP (op)) return;
+
+ sym = OP_SYMBOL (op);
+ if (sym->isspilt) return;
+ if (!sym->nRegs) return;
+ if (sym->regs[0]) return;
+
+ werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
+ sym->prereqv ? sym->prereqv->name : sym->name);
+ spillThis (sym);
+}
+
+
/*-----------------------------------------------------------------*/
/* serialRegAssign - serially allocate registers to the variables */
/*-----------------------------------------------------------------*/
if (!sym->regs[j])
break;
}
- /* if it shares registers with operands make sure
+
+ /* if it shares registers with operands make sure
that they are in the same position */
- if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_LEFT (ic)));
- /* do the same for the right operand */
- if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->nRegs)
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_RIGHT (ic)));
+ if (!POINTER_SET(ic) && !POINTER_GET(ic))
+ {
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->nRegs)
+ {
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_LEFT (ic)));
+ }
+ /* do the same for the right operand */
+ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->nRegs)
+ {
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_RIGHT (ic)));
+ }
+ }
if (ptrRegSet)
{
}
reassignUnusedLRs(unusedLRs);
}
+
+ /* Check for and fix any problems with uninitialized operands */
+ for (i = 0; i < count; i++)
+ {
+ iCode *ic;
+
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
+
+ for (ic = ebbs[i]->sch; ic; ic = ic->next)
+ {
+ if (SKIP_IC2 (ic))
+ continue;
+
+ if (ic->op == IFX)
+ {
+ verifyRegsAssigned (IC_COND (ic), ic);
+ continue;
+ }
+
+ if (ic->op == JUMPTABLE)
+ {
+ verifyRegsAssigned (IC_JTCOND (ic), ic);
+ continue;
+ }
+
+ verifyRegsAssigned (IC_RESULT (ic), ic);
+ verifyRegsAssigned (IC_LEFT (ic), ic);
+ verifyRegsAssigned (IC_RIGHT (ic), ic);
+ }
+ }
+
}
/*-----------------------------------------------------------------*/
symbol *sym =NULL;
int key =0;
int loop = 0, change;
+ int pass;
if (getenv("DISABLE_FILL_GAPS")) return;
sym->regs[i] = getRegGprNoSpil ();
}
- /* for all its definitions & uses check if the registers
+ /* For all its definitions check if the registers
allocated needs positioning NOTE: we can position
only ONCE if more than One positioning required
- then give up */
+ then give up.
+ We may need to perform the checks twice; once to
+ position the registers as needed, the second to
+ verify any register repositioning is still
+ compatible.
+ */
sym->isspilt = 0;
- for (i = 0 ; i < sym->defs->size ; i++ ) {
- if (bitVectBitValue(sym->defs,i)) {
- iCode *ic;
- if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
- if (SKIP_IC(ic)) continue;
- assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
- /* if left is assigned to registers */
- if (IS_SYMOP(IC_LEFT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
- }
- if (IS_SYMOP(IC_RIGHT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
+ for (pass=0; pass<2; pass++) {
+ for (i = 0 ; i < sym->defs->size ; i++ ) {
+ if (bitVectBitValue(sym->defs,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ if (SKIP_IC(ic)) continue;
+ assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+ /* if left is assigned to registers */
+ if (IS_SYMOP(IC_LEFT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
+ }
+ if (IS_SYMOP(IC_RIGHT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+ }
+ if (pdone > 1) break;
}
- if (pdone > 1) break;
- }
- }
- for (i = 0 ; i < sym->uses->size ; i++ ) {
- if (bitVectBitValue(sym->uses,i)) {
- iCode *ic;
- if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
- if (SKIP_IC(ic)) continue;
- if (!IS_ASSIGN_ICODE(ic)) continue ;
-
- /* if result is assigned to registers */
- if (IS_SYMOP(IC_RESULT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
+ }
+ for (i = 0 ; i < sym->uses->size ; i++ ) {
+ if (bitVectBitValue(sym->uses,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ if (SKIP_IC(ic)) continue;
+ if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
+
+ /* if result is assigned to registers */
+ if (IS_SYMOP(IC_RESULT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
+ }
+ if (pdone > 1) break;
}
- if (pdone > 1) break;
- }
- }
+ }
+ if (pdone == 0) break; /* second pass only if regs repositioned */
+ if (pdone > 1) break;
+ }
/* had to position more than once GIVE UP */
if (pdone > 1) {
/* UNDO all the changes we made to try this */
"createRegMask cannot find live range");
exit (0);
}
-
+#if 0
/* special case for ruonly */
if (sym->ruonly && sym->liveFrom != sym->liveTo) {
int size = getSize(sym->type);
ic->rMask = bitVectSetBit (ic->rMask, j++);
continue ;
}
+#endif
/* if no register assigned to it */
if (!sym->nRegs || sym->isspilt)
continue;
(ic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (sym->defs))) &&
POINTER_GET (ic) &&
- !sym->noSpilLoc &&
- !IS_BITVAR (sym->etype))
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
{
- /* and that pointer is remat in data space */
- if (IS_SYMOP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
- DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
- {
- /* create a psuedo symbol & force a spil */
- symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
- psym->type = sym->type;
- psym->etype = sym->etype;
- strncpyz (psym->rname, psym->name, sizeof(psym->rname));
- sym->isspilt = 1;
- sym->usl.spillLoc = psym;
+ if (ptrPseudoSymSafe (sym, ic))
+ {
+ ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
continue;
}
remiCodeFromeBBlock (ebp, ic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
+ OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
return 1;
}
nfs++;
}
+ // Check that no other ops in this range have been assigned to dptr1.
+ // I don't understand why this is not caught by the first check, above.
+ // But it isn't always, see bug 769624.
+ if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
+ (OP_SYMBOL(IC_RESULT(ic))->dptr == 1))
+ {
+ //fprintf(stderr, "dptr1 already in use in live range #1\n");
+ return 0;
+ }
+
+ if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
+ (OP_SYMBOL(IC_LEFT(ic))->dptr == 1))
+ {
+ //fprintf(stderr, "dptr1 already in use in live range # 2\n");
+ return 0;
+ }
+
+ if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
+ (OP_SYMBOL(IC_RIGHT(ic))->dptr == 1))
+ {
+ //fprintf(stderr, "dptr1 already in use in live range # 3\n");
+ return 0;
+ }
+
if (nfs && IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
OP_SYMBOL(IC_RESULT(ic))->ruonly) return 0;
if (bitVectBitValue(dbv,lic->key)) return ;
}
/* make sure they have the same type */
+ if (IS_SPEC(operandType(IC_LEFT(ic))))
{
sym_link *itype=operandType(IC_LEFT(ic));
sym_link *ditype=operandType(IC_RIGHT(dic));
{
/* if we are using a symbol on the stack
then we should say ds390_ptrRegReq */
+ if (options.useXstack && ic->parmPush
+ && (ic->op == IPUSH || ic->op == IPOP))
+ ds390_ptrRegReq++;
if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ? !options.stack10bit : 0) +
- OP_SYMBOL (IC_COND (ic))->iaccess);
+ OP_SYMBOL (IC_COND (ic))->iaccess +
+ (SPEC_OCLS(OP_SYMBOL (IC_COND (ic))->etype) == idata));
else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ? !options.stack10bit : 0) +
- OP_SYMBOL (IC_JTCOND (ic))->iaccess);
+ OP_SYMBOL (IC_JTCOND (ic))->iaccess +
+ (SPEC_OCLS(OP_SYMBOL (IC_JTCOND (ic))->etype) == idata));
else
{
if (IS_SYMOP (IC_LEFT (ic)))
ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ? !options.stack10bit : 0) +
- OP_SYMBOL (IC_LEFT (ic))->iaccess);
+ OP_SYMBOL (IC_LEFT (ic))->iaccess +
+ (SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata));
if (IS_SYMOP (IC_RIGHT (ic)))
ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ? !options.stack10bit : 0) +
- OP_SYMBOL (IC_RIGHT (ic))->iaccess);
+ OP_SYMBOL (IC_RIGHT (ic))->iaccess +
+ (SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata));
if (IS_SYMOP (IC_RESULT (ic)))
ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ? !options.stack10bit : 0) +
- OP_SYMBOL (IC_RESULT (ic))->iaccess);
+ OP_SYMBOL (IC_RESULT (ic))->iaccess +
+ (SPEC_OCLS(OP_SYMBOL (IC_RESULT (ic))->etype) == idata));
}
}
remiCodeFromeBBlock (ebp, ic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
+ OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
ic = ic->prev;
}
else
remiCodeFromeBBlock (ebp, ic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
+ OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
ic = ic->prev;
}
}
for (i = 0; i < count; i++)
packRegisters (ebbs[i]);
+ /* liveranges probably changed by register packing
+ so we compute them again */
+ recomputeLiveRanges (ebbs, count);
+
if (options.dump_pack)
dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
createRegMask (ebbs, count);
/* redo that offsets for stacked automatic variables */
- redoStackOffsets ();
+ if (currFunc)
+ redoStackOffsets ();
+ /* make sure r0 & r1 are flagged as used if they might be used */
+ /* as pointers */
+ if (currFunc && ds390_ptrRegReq)
+ {
+ currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R0_IDX);
+ currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R1_IDX);
+ }
+
if (options.dump_rassgn) {
dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
dumpLiveRanges (DUMP_LRANGE, liveRanges);
/* free up any _G.stackSpil locations allocated */
applyToSet (_G.stackSpil, deallocStackSpil);
_G.slocNum = 0;
- setToNull ((void **) &_G.stackSpil);
- setToNull ((void **) &_G.spiltSet);
+ setToNull ((void *) &_G.stackSpil);
+ setToNull ((void *) &_G.spiltSet);
/* mark all registers as free */
ds390_nRegs = 8;
freeAllRegs ();