}
+/*-----------------------------------------------------------------*/
+/* 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;
/* 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++;
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;
}
}
}
+ /* 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 definition is either a return value from a
function or does not contain any variables in
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;
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) &&
if (POINTER_SET (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))
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)),
}
else
{
- mcs51_nRegs = 8;
+ mcs51_nRegs = 8;
}
_G.allBitregs = findAllBitregs ();