bitVect *funcrUsed; /* registers used in a function */
int stackExtend;
int dataExtend;
+ bitVect *allBitregs; /* all bit registers */
}
_G;
regs regs8051[] =
{
- {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1},
- {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1},
- {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1},
- {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1},
- {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1},
- {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1},
- {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1},
- {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1},
- {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1},
- {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1},
+ {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1},
+ {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1},
+ {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1},
+ {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1},
+ {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1},
+ {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1},
+ {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1},
+ {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1},
+ {REG_BIT, B0_IDX, REG_BIT, "b0", "b0", "bits", 0, 1},
+ {REG_BIT, B1_IDX, REG_BIT, "b1", "b1", "bits", 1, 1},
+ {REG_BIT, B2_IDX, REG_BIT, "b2", "b2", "bits", 2, 1},
+ {REG_BIT, B3_IDX, REG_BIT, "b3", "b3", "bits", 3, 1},
+ {REG_BIT, B4_IDX, REG_BIT, "b4", "b4", "bits", 4, 1},
+ {REG_BIT, B5_IDX, REG_BIT, "b5", "b5", "bits", 5, 1},
+ {REG_BIT, B6_IDX, REG_BIT, "b6", "b6", "bits", 6, 1},
+ {REG_BIT, B7_IDX, REG_BIT, "b7", "b7", "bits", 7, 1},
+ {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1},
+ {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1},
{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", "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},
+ {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 = 17;
+int mcs51_nRegs = 16;
static void spillThis (symbol *);
static void freeAllRegs ();
}
+/*-----------------------------------------------------------------*/
+/* bitType - will return 1 if the symbol has type REG_BIT */
+/*-----------------------------------------------------------------*/
+static int
+bitType (symbol * sym, eBBlock * ebp, iCode * ic)
+{
+ return (sym->regType == REG_BIT ? 1 : 0);
+}
+
/*-----------------------------------------------------------------*/
/* noSpilLoc - return true if a variable has no spil location */
/*-----------------------------------------------------------------*/
}
/*-----------------------------------------------------------------*/
-/* directSpilLoc - will return 1 if the splilocation is in direct */
+/* directSpilLoc - will return 1 if the spillocation is in direct */
/*-----------------------------------------------------------------*/
static int
directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
{
/* if usage is the same then prefer
- the spill the smaller of the two */
+ to spill the smaller of the two */
if (lsym->used == sym->used)
if (getSize (lsym->type) < getSize (sym->type))
sym = lsym;
/* set the type to the spilling symbol */
sloc->type = copyLinkChain (sym->type);
sloc->etype = getSpec (sloc->type);
- SPEC_SCLS (sloc->etype) = S_DATA;
+ if (!IS_BIT (sloc->etype))
+ {
+ SPEC_SCLS (sloc->etype) = S_DATA;
+ }
+ else if (SPEC_SCLS (sloc->etype) == S_SBIT)
+ {
+ SPEC_SCLS (sloc->etype) = S_BIT;
+ }
SPEC_EXTR (sloc->etype) = 0;
SPEC_STAT (sloc->etype) = 0;
SPEC_VOLATILE(sloc->etype) = 0;
SPEC_ABSA(sloc->etype) = 0;
- /* we don't allow it to be allocated`
+ /* we don't allow it to be allocated
onto the external stack since : so we
temporarily turn it off ; we also
turn off memory model to prevent
/*-----------------------------------------------------------------*/
/* isSpiltOnStack - returns true if the spil location is on stack */
+/* or otherwise needs a pointer register */
/*-----------------------------------------------------------------*/
static bool
isSpiltOnStack (symbol * sym)
if (!sym->usl.spillLoc)
return FALSE;
+ if (sym->usl.spillLoc->onStack || sym->usl.spillLoc->iaccess)
+ return TRUE;
+
etype = getSpec (sym->usl.spillLoc->type);
if (IN_STACK (etype))
return TRUE;
/* get the spillable live ranges */
lrcs = computeSpillable (ic);
- /* get all live ranges that are rematerizable */
- if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
+ /* remove incompatible registers */
+ if ((forSym->regType == REG_PTR) || (forSym->regType == REG_GPR))
{
+ selectS = liveRangesWith (lrcs, bitType, ebp, ic);
+
+ for (sym = setFirstItem (selectS); sym; sym = setNextItem (selectS))
+ {
+ bitVectUnSetBit (lrcs, sym->key);
+ }
+ }
+ /* get all live ranges that are rematerializable */
+ if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
+ {
/* return the least used of these */
return leastUsedLR (selectS);
}
/* if the symbol is local to the block then */
if (forSym->liveTo < ebp->lSeq)
{
-
/* check if there are any live ranges allocated
to registers that are not used in this block */
if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
/* find live ranges with spillocation && not used as pointers */
if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
{
-
sym = leastUsedLR (selectS);
/* mark this as allocation required */
sym->usl.spillLoc->allocreq++;
/* find live ranges with spillocation */
if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
{
-
sym = leastUsedLR (selectS);
sym->usl.spillLoc->allocreq++;
return sym;
used ofcourse */
if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
{
-
/* return a created spil location */
sym = createStackSpil (leastUsedLR (selectS));
sym->usl.spillLoc->allocreq++;
}
/*-----------------------------------------------------------------*/
-/* getRegPtrNoSpil - get it cannot split */
+/* getRegBit - will try for Bit if not spill this */
+/*-----------------------------------------------------------------*/
+static regs *getRegBit (symbol * sym)
+{
+ regs *reg;
+
+ /* try for a bit type */
+ if ((reg = allocReg (REG_BIT)))
+ return reg;
+
+ spillThis (sym);
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* getRegPtrNoSpil - get it cannot be spilt */
/*-----------------------------------------------------------------*/
static regs *getRegPtrNoSpil()
{
}
/*-----------------------------------------------------------------*/
-/* getRegGprNoSpil - get it cannot split */
+/* getRegGprNoSpil - get it cannot be spilt */
/*-----------------------------------------------------------------*/
static regs *getRegGprNoSpil()
{
return 0;
}
+/*-----------------------------------------------------------------*/
+/* getRegBitNoSpil - get it cannot be spilt */
+/*-----------------------------------------------------------------*/
+static regs *getRegBitNoSpil()
+{
+ regs *reg;
+
+ /* try for a ptr type */
+ if ((reg = allocReg (REG_BIT)))
+ return reg;
+
+ /* try for gpr type */
+ if ((reg = allocReg (REG_GPR)))
+ return reg;
+
+ assert(0);
+
+ /* just to make the compiler happy */
+ return 0;
+}
+
/*-----------------------------------------------------------------*/
/* symHasReg - symbol has a given register */
/*-----------------------------------------------------------------*/
return FALSE;
}
+/*-----------------------------------------------------------------*/
+/* updateRegUsage - update the registers in use at the start of */
+/* this icode */
+/*-----------------------------------------------------------------*/
+static void
+updateRegUsage (iCode * ic)
+{
+ int reg;
+
+ for (reg=0; reg<mcs51_nRegs; reg++)
+ {
+ if (regs8051[reg].isFree)
+ {
+ ic->riu &= ~(1<<regs8051[reg].offset);
+ }
+ else
+ {
+ ic->riu |= (1<<regs8051[reg].offset);
+ BitBankUsed |= (reg >= 8);
+ }
+ }
+}
+
/*-----------------------------------------------------------------*/
/* deassignLRs - check the live to and if they have registers & are */
/* not spilt then free up the registers */
static int
willCauseSpill (int nr, int rt)
{
- /* first check if there are any avlb registers
- of te type required */
+ /* first check if there are any available registers
+ of the type required */
if (rt == REG_PTR)
{
/* special case for pointer type
if (nFreeRegs (REG_GPR) >= nr)
return 0;
}
+ else if (rt == REG_BIT)
+ {
+ if (nFreeRegs (rt) >= nr)
+ return 0;
+ }
else
{
if (mcs51_ptrRegReq)
ebbs[i]->entryLabel != returnLabel))
continue;
- /* of all instructions do */
+ /* for 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
+ updateRegUsage(ic);
+
/* if this is an ipop that means some live
range will have to be assigned again */
if (ic->op == IPOP)
int j;
int ptrRegSet = 0;
+ /* Make sure any spill location is definitely allocated */
+ if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+ !sym->usl.spillLoc->allocreq)
+ {
+ sym->usl.spillLoc->allocreq++;
+ }
+
/* if it does not need or is spilt
or is already assigned to registers
or will not live beyond this instructions */
spillThis (sym);
continue;
}
+
+ willCS = willCauseSpill (sym->nRegs, sym->regType);
+ /* if this is a bit variable then don't use precious registers
+ along with expensive bit-to-char conversions but just spill
+ it */
+ if (willCS && SPEC_NOUN(sym->etype) == V_BIT) {
+ spillThis (sym);
+ continue;
+ }
+
/* if trying to allocate this will cause
a spill and there is nothing to spill
or this one is rematerializable then
spill this one */
- willCS = willCauseSpill (sym->nRegs, sym->regType);
spillable = computeSpillable (ic);
if (sym->remat || (willCS && bitVectIsZero (spillable))) {
spillThis (sym);
sym->regs[j] = NULL;
if (sym->regType == REG_PTR)
sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
+ else if (sym->regType == REG_BIT)
+ sym->regs[j] = getRegBit (sym);
else
{
if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic)))
{
symbol * right = OP_SYMBOL (IC_RIGHT (ic));
- if (right->regs[j])
+ if (right->regs[j] && (right->regType != REG_BIT))
sym->regs[j] = allocThisReg (right->regs[j]);
}
if (!sym->regs[j])
this was spilt then break */
if (!sym->regs[j])
{
+ int i;
for (i=0; i < sym->nRegs ; i++ )
sym->regs[i] = NULL;
break;
if (!sym->spillA || !sym->clashes || sym->remat) continue ;
+ /* if spilt in direct space the original rname is lost */
+ if (sym->usl.spillLoc && (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
+ continue;
+
/* find the liveRanges this one clashes with, that are
still assigned to registers & mark the registers as used*/
for ( i = 0 ; i < sym->clashes->size ; i ++) {
}
}
- D(printf("Atemping fillGaps on %s: [",sym->name));
+ D(printf("Attempting 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 if (sym->regType == REG_BIT)
+ sym->regs[i] = getRegBitNoSpil ();
else
{
sym->regs[i] = NULL;
}
}
+/*-----------------------------------------------------------------*/
+/* findAllBitregs :- returns bit vector of all bit registers */
+/*-----------------------------------------------------------------*/
+static bitVect *
+findAllBitregs (void)
+{
+ bitVect *rmask = newBitVect (mcs51_nRegs);
+ int j;
+
+ for (j = 0; j < mcs51_nRegs; j++)
+ {
+ if (regs8051[j].type == REG_BIT)
+ rmask = bitVectSetBit (rmask, regs8051[j].rIdx);
+ }
+
+ return rmask;
+}
+
+/*-----------------------------------------------------------------*/
+/* mcs51_allBitregs :- returns bit vector of all bit registers */
+/*-----------------------------------------------------------------*/
+bitVect *
+mcs51_allBitregs (void)
+{
+ return _G.allBitregs;
+}
+
/*-----------------------------------------------------------------*/
/* rUmaskForOp :- returns register mask for an operand */
/*-----------------------------------------------------------------*/
for (j = 0; j < sym->nRegs; j++)
{
if (sym->regs[j]) /* EEP - debug */
- rumask = bitVectSetBit (rumask,
- sym->regs[j]->rIdx);
+ rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx);
}
return rumask;
static char *
rematStr (symbol * sym)
{
- char *s = buffer;
iCode *ic = sym->rematiCode;
-
- *s = 0;
+ int offset = 0;
while (1)
{
+ /* if plus adjust offset to right hand side */
+ if (ic->op == '+')
+ {
+ offset += (int) operandLitValue (IC_RIGHT (ic));
+ ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+ continue;
+ }
- /* if plus or minus print the right hand side */
- if (ic->op == '+' || ic->op == '-')
+ /* if minus adjust offset to right hand side */
+ if (ic->op == '-')
{
- SNPRINTF (s, sizeof(buffer) - strlen(buffer),
- "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
- ic->op);
- s += strlen (s);
+ offset -= (int) operandLitValue (IC_RIGHT (ic));
ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
continue;
}
continue;
}
/* we reached the end */
- SNPRINTF (s, sizeof(buffer) - strlen(buffer),
- "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
break;
}
+ if (offset)
+ {
+ SNPRINTF (buffer, sizeof(buffer),
+ "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ic))->rname,
+ offset >= 0 ? '+' : '-',
+ abs (offset) & 0xffff);
+ }
+ else
+ {
+ strncpyz (buffer, OP_SYMBOL (IC_LEFT (ic))->rname, sizeof(buffer));
+ }
return buffer;
}
{
if (IS_AGGREGATE (sym->type) || sym->isptr)
sym->type = aggrToPtr (sym->type, FALSE);
+ else if (IS_BIT(sym->type))
+ sym->regType = REG_CND;
continue;
}
}
/* determine the type of register required */
- if (sym->nRegs == 1 &&
- IS_PTR (sym->type) &&
- sym->uptr)
+ if (sym->nRegs == 1 && IS_PTR (sym->type) && sym->uptr)
sym->regType = REG_PTR;
+ else if (IS_BIT(sym->type))
+ sym->regType = REG_BIT;
else
sym->regType = REG_GPR;
-
}
else
/* for the first run we don't provide */
}
}
+ /* Don't move an assignment out of a critical block */
+ if (dic->op == CRITICAL)
+ {
+ dic = NULL;
+ break;
+ }
+
if (SKIP_IC2 (dic))
continue;
}
}
}
-#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))
- {
- /* 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 ||
return 0;
}
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
/*-----------------------------------------------------------------*/
/* packRegsForOneuse : - will reduce some registers for single Use */
if (ic->op == SEND && ic->argreg != 1) return NULL;
- /* this routine will mark the a symbol as used in one
- instruction use only && if the defintion is local
+ /* this routine will mark the symbol as used in one
+ instruction use only && if the definition is local
(ie. within the basic block) && has only one definition &&
- that definiion is either a return value from a
+ that definition is either a return value from a
function or does not contain any variables in
far space */
if (bitVectnBitsOn (OP_USES (op)) > 1)
return NULL;
- /* if it has only one defintion */
+ /* if it has only one definition */
if (bitVectnBitsOn (OP_DEFS (op)) > 1)
return NULL; /* has more than one definition */
}
else
{
- /* otherwise check that the definition does
- not contain any symbols in far space */
- if (isOperandInFarSpace (IC_LEFT (dic)) ||
- isOperandInFarSpace (IC_RIGHT (dic)) ||
- IS_OP_RUONLY (IC_LEFT (ic)) ||
- IS_OP_RUONLY (IC_RIGHT (ic)))
- {
- return NULL;
- }
+ /* otherwise check that the definition does
+ not contain any symbols in far space */
+ if (isOperandInFarSpace (IC_LEFT (dic)) ||
+ isOperandInFarSpace (IC_RIGHT (dic)) ||
+ IS_OP_RUONLY (IC_LEFT (ic)) ||
+ IS_OP_RUONLY (IC_RIGHT (ic)))
+ {
+ return NULL;
+ }
- /* if pointer set then make sure the pointer
- is one byte */
- if (POINTER_SET (dic) &&
- !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
- return NULL;
+ /* if pointer set then make sure the pointer
+ is one byte */
+ if (POINTER_SET (dic) &&
+ !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
+ return NULL;
- if (POINTER_GET (dic) &&
- !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
- return NULL;
+ if (POINTER_GET (dic) &&
+ !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
+ return NULL;
}
/* Make sure no overlapping liverange is already assigned to DPTR */
sic = dic;
- /* also make sure the intervenening instructions
- don't have any thing in far space */
+ /* also make sure the intervening instructions
+ don't have anything in far space */
for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
{
-
/* if there is an intervening function call then no */
if (dic->op == CALL || dic->op == PCALL)
return NULL;
/* operandUsesAcc - determines whether the code generated for this */
/* operand will have to use the accumulator */
/*-----------------------------------------------------------------*/
-bool operandUsesAcc(operand *op)
+bool operandUsesAcc(operand *op, bool allowBitspace)
{
if (!op)
return FALSE;
if (sym->iaccess && symspace->paged)
return TRUE; /* must fetch paged indirect sym via accumulator */
- if (IN_BITSPACE(symspace))
+ if (!allowBitspace && IN_BITSPACE(symspace))
return TRUE; /* fetching bit vars uses the accumulator */
if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace))
getSize (operandType (IC_RESULT (ic))) > 1)
return;
-
/* has only one definition */
if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
return;
getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
return;
- /* if the usage is not is an assignment
+ /* if the usage is not an assignment
or an arithmetic / bitwise / shift operation then not */
if (uic->op != '=' &&
!IS_ARITHMETIC_OP (uic) &&
goto accuse;
/* if the other operand uses the accumulator then we cannot */
- if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
- operandUsesAcc(IC_RIGHT(uic))) ||
+ if ( (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
+ operandUsesAcc (IC_RIGHT (uic), IS_BIT (operandType (IC_LEFT (uic))))) ||
(IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
- operandUsesAcc(IC_LEFT(uic))) )
+ operandUsesAcc (IC_LEFT (uic), IS_BIT (operandType (IC_RIGHT (uic))))) )
return;
/* make sure this is on the left side if not commutative */
}
/*-----------------------------------------------------------------*/
-/* packForPush - hueristics to reduce iCode for pushing */
+/* packForPush - heuristics to reduce iCode for pushing */
/*-----------------------------------------------------------------*/
static void
packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
IS_SYMOP (IC_RIGHT (ic)) &&
OP_SYMBOL (IC_RIGHT (ic))->remat &&
!IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
+ !isOperandGlobal(IC_RESULT(ic)) && /* due to bug 1618050 */
bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
{
OP_SYMBOL (IC_RESULT (ic))->remat =
}
/* mark the pointer usages */
- if (POINTER_SET (ic))
+ if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)))
OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
- if (POINTER_GET (ic) &&
- IS_SYMOP(IC_LEFT (ic)))
+ if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic)))
OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
if (!SKIP_IC2 (ic))
/* if pointer set & left has a size more than
one and right is not in far space */
if (POINTER_SET (ic) &&
+ IS_SYMOP (IC_RESULT (ic)) &&
!isOperandInFarSpace (IC_RIGHT (ic)) &&
!OP_SYMBOL (IC_RESULT (ic))->remat &&
!IS_OP_RUONLY (IC_RIGHT (ic)) &&
getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
/* if this is a cast for intergral promotion then
check if it's the only use of the definition of the
operand being casted/ if yes then replace
}
else
{
-
/* if the type from and type to are the same
then if this is the only use then packit */
if (compareType (operandType (IC_RIGHT (ic)),
/* pack registers for accumulator use, when the
result of an arithmetic or bit wise operation
has only one use, that use is immediately following
- the defintion and the using iCode has only one
+ the definition and the using iCode has only one
operand or has two operands but one is literal &
the result of that operation is not on stack then
we can leave the result of this operation in acc:b
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-mcs51_assignRegisters (eBBlock ** ebbs, int count)
+mcs51_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
setToNull ((void *) &_G.regAssigned);
setToNull ((void *) &_G.totRegAssigned);
mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
- mcs51_nRegs = 8;
+ if ((currFunc && IFFUNC_ISREENT (currFunc->type)) || options.stackAuto)
+ {
+ mcs51_nRegs = 16;
+ }
+ else
+ {
+ mcs51_nRegs = 8;
+ }
+ _G.allBitregs = findAllBitregs ();
+
/* change assignments this will remove some
live ranges reducing some register pressure */
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
if (options.dump_rassgn)
{
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
dumpLiveRanges (DUMP_LRANGE, liveRanges);
}