-//#define LIVERANGEHUNT
-#ifdef LIVERANGEHUNT
- #define LRH(x) x
-#else
- #define LRH(x)
-#endif
/*------------------------------------------------------------------------
SDCCralloc.c - source file for register allocation. (8051) specific
{REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1},
{REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 1},
{REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 1},
- {REG_CND, CND_IDX, REG_CND, "C", "C", "xreg", 0, 1},
+ {REG_CND, CND_IDX, REG_CND, "C", "psw", "0xd0", 0, 1},
+ {0, DPL_IDX, 0, "dpl", "dpl", "0x82", 0, 0},
+ {0, DPH_IDX, 0, "dph", "dph", "0x83", 0, 0},
+ {0, B_IDX, 0, "b", "b", "0xf0", 0, 0},
+ {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0},
};
-int mcs51_nRegs = 13;
+int mcs51_nRegs = 17;
static void spillThis (symbol *);
static void freeAllRegs ();
{
int i;
- for (i = 0; i < mcs51_nRegs; i++)
+ for (i = 0; i < sizeof(regs8051)/sizeof(regs); i++)
if (regs8051[i].rIdx == idx)
return ®s8051[i];
}
- setToNull ((void **) &sset);
+ setToNull ((void *) &sset);
sym->blockSpil = 0;
return sym;
}
if (!(sym->remat || sym->usl.spillLoc))
createStackSpil (sym);
- LRH(printf("spillThis: %s\n", sym->name));
/* mark it has spilt & put it in the spilt set */
sym->isspilt = sym->spillA = 1;
_G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
/* get something we can spil */
ssym = selectSpil (ic, ebp, forSym);
- LRH(printf("spilSomething: spilled %s for %s\n", ssym->name, forSym->name));
/* mark it as spilt */
ssym->isspilt = ssym->spillA = 1;
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 ((reg = allocReg (REG_GPR)))
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;
return change;
}
+
+/*------------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
/* of all instructions do */
for (ic = ebbs[i]->sch; ic; ic = ic->next) {
+#if 1
+ int reg;
+
+ // update the registers in use at the start of this icode
+ for (reg=0; reg<mcs51_nRegs; reg++) {
+ if (regs8051[reg].isFree) {
+ ic->riu &= ~(1<<regs8051[reg].offset);
+ } else {
+ ic->riu |= (1<<regs8051[reg].offset);
+ }
+ }
+#endif
/* if this is an ipop that means some live
range will have to be assigned again */
mcs51_ptrRegReq++;
ptrRegSet = 1;
}
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))
+ && SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) {
+ mcs51_ptrRegReq++;
+ ptrRegSet = 1;
+ }
+ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))
+ && SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) {
+ mcs51_ptrRegReq++;
+ ptrRegSet = 1;
+ }
+
/* else we assign registers to it */
_G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
_G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
}
}
- /* 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 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) {
+ 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) {
mcs51_ptrRegReq--;
}
}
}
+
+ /* 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);
+ }
+ }
}
/*-----------------------------------------------------------------*/
static void fillGaps()
{
symbol *sym =NULL;
- int key =0;
+ int key =0;
+ int pass;
if (getenv("DISABLE_FILL_GAPS")) return;
continue ;
}
+ D(printf("Atemping fillGaps on %s: [",sym->name));
/* THERE IS HOPE !!!! */
for (i=0; i < sym->nRegs ; i++ ) {
if (sym->regType == REG_PTR)
sym->regs[i] = getRegPtrNoSpil ();
else
sym->regs[i] = getRegGprNoSpil ();
+ D(printf("%s ", sym->regs[i]->name));
}
+ D(printf("]\n"));
- /* for all its definitions 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++) {
+ D(printf(" checking definitions\n"));
+ for (i = 0 ; i < sym->defs->size ; i++ ) {
+ if (bitVectBitValue(sym->defs,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ D(printf(" ic->seq = %d\n", ic->seq));
+ 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)))
+ {
+ D(printf(" left = "));
+ D(printOperand(IC_LEFT(ic),NULL));
+ }
+ 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)))
+ {
+ D(printf(" right = "));
+ D(printOperand(IC_RIGHT(ic),NULL));
+ }
+ if (IS_SYMOP(IC_RIGHT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+ }
+ D(printf(" pdone = %d\n", pdone));
+ 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)));
+ D(printf(" checking uses\n"));
+ for (i = 0 ; i < sym->uses->size ; i++ ) {
+ if (bitVectBitValue(sym->uses,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ D(printf(" ic->seq = %d\n", ic->seq));
+ 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)))
+ {
+ D(printf(" result = "));
+ D(printOperand(IC_RESULT(ic),NULL));
+ }
+ if (IS_SYMOP(IC_RESULT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
+ }
+ D(printf(" pdone = %d\n", pdone));
+ if (pdone > 1) break;
}
- if (pdone > 1) break;
}
- }
+ if (pdone == 0) break; /* second pass only if regs repositioned */
+ if (pdone > 1) break;
+ }
+ D(printf(" sym->regs = ["));
+ for (i=0; i < sym->nRegs ; i++ )
+ D(printf("%s ", sym->regs[i]->name));
+ D(printf("]\n"));
/* had to position more than once GIVE UP */
if (pdone > 1) {
/* UNDO all the changes we made to try this */
for (j = 0; j < sym->nRegs; j++)
{
+ if (sym->regs[j]) /* EEP - debug */
rumask = bitVectSetBit (rumask,
sym->regs[j]->rIdx);
}
if (sym->ruonly || sym->accuse)
{
if (IS_AGGREGATE (sym->type) || sym->isptr)
- sym->type = aggrToPtr (sym->type, FALSE);
+ sym->type = aggrToPtr (sym->type, FALSE);
continue;
}
-#ifdef RANGEHUNT
- /* if this symbol has only one usage and that is an assignment
- to a ruonly, we don't need registers */
- // if this symbol has only one def
- if (bitVectnBitsOn (sym->defs)==1) {
- printf ("sym: %s has only one usage", sym->name);
- // find that usage
- if ((ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs)))) {
- if (ic->op==CALL) {
- printf (" for a call ");
- // if this is only assigned to a ruonly
- if ((ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs)))) {
- if (ic->op=='=') {
- if (OP_SYMBOL(IC_RESULT(ic))->ruonly) {
- printf("regTypeNum: %s assigned to %s\n", \
- sym->name, OP_SYMBOL(IC_RESULT(ic))->name);
- }
- }
- }
- }
- }
- }
-#endif
-
/* if the symbol has only one definition &
that definition is a get_pointer */
if (bitVectnBitsOn (sym->defs) == 1 &&
/* and that pointer is remat in data space */
- if (IS_SYMOP (IC_LEFT (ic)) &&
+ 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)
symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
psym->type = sym->type;
psym->etype = sym->etype;
+
strcpy (psym->rname, psym->name);
sym->isspilt = 1;
sym->usl.spillLoc = psym;
getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
return NULL;
- /* if any three is a true symbol in far space */
- if (IC_RESULT (dic) &&
- IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- isOperandInFarSpace (IC_RESULT (dic)))
- return NULL;
+ if (dic->op == IFX)
+ {
+ if (IC_COND (dic) &&
+ IS_TRUE_SYMOP (IC_COND (dic)) &&
+ isOperandInFarSpace (IC_COND (dic)))
+ return NULL;
+ }
+ else if (dic->op == JUMPTABLE)
+ {
+ if (IC_JTCOND (dic) &&
+ IS_TRUE_SYMOP (IC_JTCOND (dic)) &&
+ isOperandInFarSpace (IC_JTCOND (dic)))
+ return NULL;
+ }
+ else
+ {
+ /* if any three is a true symbol in far space */
+ if (IC_RESULT (dic) &&
+ IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ isOperandInFarSpace (IC_RESULT (dic)))
+ return NULL;
- if (IC_RIGHT (dic) &&
- IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
- isOperandInFarSpace (IC_RIGHT (dic)) &&
- !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
- return NULL;
+ if (IC_RIGHT (dic) &&
+ IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+ isOperandInFarSpace (IC_RIGHT (dic)) &&
+ !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+ return NULL;
- if (IC_LEFT (dic) &&
- IS_TRUE_SYMOP (IC_LEFT (dic)) &&
- isOperandInFarSpace (IC_LEFT (dic)) &&
- !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
- return NULL;
+ if (IC_LEFT (dic) &&
+ IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+ isOperandInFarSpace (IC_LEFT (dic)) &&
+ !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+ return NULL;
+ }
if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
{
return 0;
}
-
/* if the true symbol is defined in far space or on stack
then we should not since this will increase register pressure */
if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
we cannot */
for (dic = ic->prev; dic; dic = dic->prev)
{
- /* if there is a function call then don't pack it */
+ int crossedCall = 0;
+
+ /* We can pack across a function call only if it's a local */
+ /* variable or our parameter. Never pack global variables */
+ /* or parameters to a function we call. */
if ((dic->op == CALL || dic->op == PCALL))
{
- dic = NULL;
- break;
+ if (!OP_SYMBOL (IC_RESULT (ic))->ismyparm
+ && !OP_SYMBOL (IC_RESULT (ic))->islocal)
+ {
+ crossedCall = 1;
+ }
}
if (SKIP_IC2 (dic))
continue;
- if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- IS_OP_VOLATILE (IC_RESULT (dic)))
- {
- dic = NULL;
- break;
- }
+ if (dic->op == IFX)
+ {
+ if (IS_SYMOP (IC_COND (dic)) &&
+ (IC_COND (dic)->key == IC_RESULT (ic)->key ||
+ IC_COND (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
+ }
+ else
+ {
+ if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ IS_OP_VOLATILE (IC_RESULT (dic)))
+ {
+ dic = NULL;
+ break;
+ }
- if (IS_SYMOP (IC_RESULT (dic)) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- {
- if (POINTER_SET (dic))
- dic = NULL;
+ if (IS_SYMOP (IC_RESULT (dic)) &&
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ {
+ if (POINTER_SET (dic))
+ dic = NULL;
- break;
- }
+ break;
+ }
- if (IS_SYMOP (IC_RIGHT (dic)) &&
- (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
- IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
- {
- dic = NULL;
- break;
- }
+ if (IS_SYMOP (IC_RIGHT (dic)) &&
+ (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+ IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
- if (IS_SYMOP (IC_LEFT (dic)) &&
- (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
- IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
- {
- dic = NULL;
- break;
- }
+ if (IS_SYMOP (IC_LEFT (dic)) &&
+ (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+ IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
- if (POINTER_SET (dic) &&
- IC_RESULT (dic)->key == IC_RESULT (ic)->key)
- {
- dic = NULL;
- break;
+ if (IS_SYMOP (IC_RESULT (dic)) &&
+ IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+ {
+ dic = NULL;
+ break;
+ }
+
+ if (crossedCall)
+ {
+ dic = NULL;
+ break;
+ }
+
}
}
if (!dic)
return 0; /* did not find */
+ /* if assignment then check that right is not a bit */
+ if (ASSIGNMENT (ic) && !POINTER_SET (ic))
+ {
+ sym_link *etype = operandType (IC_RESULT (dic));
+ if (IS_BITFIELD (etype))
+ {
+ /* if result is a bit too then it's ok */
+ etype = operandType (IC_RESULT (ic));
+ if (!IS_BITFIELD (etype))
+ {
+ return 0;
+ }
+ }
+ }
+#if 0
/* if assignment then check that right is not a bit */
if (ASSIGNMENT (dic) && !POINTER_SET (dic))
{
sym_link *etype = operandType (IC_RIGHT (dic));
if (IS_BITFIELD (etype))
- return 0;
+ {
+ /* if result is a bit too then it's ok */
+ etype = operandType (IC_RESULT (dic));
+ if (!IS_BITFIELD (etype))
+ return 0;
+ }
}
+#endif
/* if the result is on stack or iaccess then it must be
the same atleast one of the operands */
if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
{
OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
}
- // jwk: and the otherway around?
+ // TODO: and the otherway around?
/* delete from liverange table also
delete from all the points inbetween and the new
other uses.
*/
-
for (dic = ic->prev; dic; dic = dic->prev)
{
break; /* found where this temp was defined */
/* if we find an usage then we cannot delete it */
- if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
- return NULL;
+
+ if (dic->op == IFX)
+ {
+ if (IC_COND (dic) && IC_COND (dic)->key == op->key)
+ return NULL;
+ }
+ else if (dic->op == JUMPTABLE)
+ {
+ if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
+ return NULL;
+ }
+ else
+ {
+ if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
+ return NULL;
- if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
- return NULL;
+ if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
+ return NULL;
- if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
- return NULL;
+ if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
+ return NULL;
+ }
}
if (!dic)
return NULL; /* didn't find any assignment to op */
- LRH(printf ("findAssignToSym: %s\n", OP_SYMBOL(IC_RESULT(dic))->name));
/* we are interested only if defined in far space */
/* or in stack space in case of + & - */
/* update the sym of the used operand */
OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
op->key = OP_SYMBOL(op)->key;
-
+ OP_SYMBOL(op)->accuse = 0;
+
/* update the sym's liverange */
if ( OP_LIVETO(op) < ic->seq )
setToRange(op, ic->seq, FALSE);
bitVectFirstBit (OP_DEFS (op)))))
return NULL;
- LRH(printf ("packRegsForOneUse: %s\n", OP_SYMBOL(op)->name));
/* if that only usage is a cast */
if (dic->op == CAST) {
/* to a bigger type */
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));
cast is remat, then we can remat this cast as well */
if (ic->op == CAST &&
IS_SYMOP(IC_RIGHT(ic)) &&
- OP_SYMBOL(IC_RIGHT(ic))->remat ) {
+ OP_SYMBOL(IC_RIGHT(ic))->remat &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
sym_link *to_type = operandType(IC_LEFT(ic));
sym_link *from_type = operandType(IC_RIGHT(ic));
if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
{
/* if we are using a symbol on the stack
then we should say mcs51_ptrRegReq */
+ if (options.useXstack && ic->parmPush
+ && (ic->op == IPUSH || ic->op == IPOP))
+ mcs51_ptrRegReq++;
if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
- OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
+ OP_SYMBOL (IC_COND (ic))->iaccess ||
+ SPEC_OCLS(OP_SYMBOL (IC_COND (ic))->etype) == idata) ? 1 : 0);
else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
- OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
+ OP_SYMBOL (IC_JTCOND (ic))->iaccess ||
+ SPEC_OCLS(OP_SYMBOL (IC_JTCOND (ic))->etype) == idata) ? 1 : 0);
else
{
if (IS_SYMOP (IC_LEFT (ic)))
mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
- OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
+ OP_SYMBOL (IC_LEFT (ic))->iaccess ||
+ SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) ? 1 : 0);
if (IS_SYMOP (IC_RIGHT (ic)))
mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
- OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
+ OP_SYMBOL (IC_RIGHT (ic))->iaccess ||
+ SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) ? 1 : 0);
if (IS_SYMOP (IC_RESULT (ic)))
mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
- OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
+ OP_SYMBOL (IC_RESULT (ic))->iaccess ||
+ SPEC_OCLS(OP_SYMBOL (IC_RESULT (ic))->etype) == idata) ? 1 : 0);
+ if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
+ && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE)
+ mcs51_ptrRegReq ++;
+ if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic))
+ && getSize (OP_SYMBOL (IC_RESULT (ic))->type) <= (unsigned int) PTRSIZE)
+ mcs51_ptrRegReq ++;
}
}
int i;
setToNull ((void *) &_G.funcrUsed);
+ setToNull ((void *) &_G.regAssigned);
setToNull ((void *) &_G.totRegAssigned);
mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
mcs51_nRegs = 8;
/* change assignments this will remove some
live ranges reducing some register pressure */
+
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);
serialRegAssign (ebbs, count);
freeAllRegs ();
+ //setToNull ((void *) &_G.regAssigned);
+ //setToNull ((void *) &_G.totRegAssigned);
fillGaps();
/* if stack was extended then tell the user */
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 && mcs51_ptrRegReq)
+ {
+ currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R0_IDX);
+ currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R1_IDX);
+ }
if (options.dump_rassgn)
{
/* 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 */
freeAllRegs ();