#include "common.h"
#include "ralloc.h"
+#include "gen.h"
/*-----------------------------------------------------------------*/
/* At this point we start getting processor specific although */
static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
{
return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
- allDefsOutOfRange (sym->defs,ic->seq,ebp->lSeq));
+ allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
}
/*-----------------------------------------------------------------*/
{
symbol *sloc= NULL;
int useXstack, model, noOverlay;
- int stackAuto;
+
+ char slocBuffer[30];
/* first go try and find a free one that is already
existing on the stack */
we need to allocate this on the stack : this is really a
hack!! but cannot think of anything better at this time */
- sprintf(buffer,"sloc%d",_G.slocNum++);
- sloc = newiTemp(buffer);
+ if (sprintf(slocBuffer,"sloc%d",_G.slocNum++) >= sizeof(slocBuffer))
+ {
+ fprintf(stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
+ __FILE__, __LINE__);
+ exit(1);
+ }
+
+ sloc = newiTemp(slocBuffer);
/* set the type to the spilling symbol */
sloc->type = copyLinkChain(sym->type);
sloc->etype = getSpec(sloc->type);
- SPEC_SCLS(sloc->etype) = S_AUTO ;
+ SPEC_SCLS(sloc->etype) = S_DATA ;
SPEC_EXTR(sloc->etype) = 0;
/* we don't allow it to be allocated`
temporarily turn it off ; we also
turn off memory model to prevent
the spil from going to the external storage
- and turn off overlaying
*/
useXstack = options.useXstack;
model = options.model;
- noOverlay = options.noOverlay;
- stackAuto = options.stackAuto;
- options.noOverlay = 1;
+/* noOverlay = options.noOverlay; */
+/* options.noOverlay = 1; */
options.model = options.useXstack = 0;
allocLocal(sloc);
options.useXstack = useXstack;
options.model = model;
- options.noOverlay = noOverlay;
- options.stackAuto = stackAuto;
+/* options.noOverlay = noOverlay; */
sloc->isref = 1; /* to prevent compiler warning */
/* if it is on the stack then update the stack */
return sym;
}
- /* if the symbol is local to the block then */
- if (forSym->liveTo < ebp->lSeq ) {
+ /* 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 */
used in the remainder of the block */
if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
sym = leastUsedLR (selectS);
- if (!sym->remat) {
- sym->remainSpil = 1;
- _G.blockSpil++;
+ if (sym != forSym) {
+ if (!sym->remat) {
+ sym->remainSpil = 1;
+ _G.blockSpil++;
+ }
+ return sym;
}
- return sym;
}
}
/*-----------------------------------------------------------------*/
/* getRegPtr - will try for PTR if not a GPR type if not spil */
/*-----------------------------------------------------------------*/
-regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
+static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
{
regs *reg;
if (!mcs51_ptrRegReq)
if ((reg = allocReg(REG_PTR)))
return reg ;
-
+
/* we have to spil */
if (!spilSomething (ic,ebp,sym))
return NULL ;
sym->nRegs) >= result->nRegs)
) {
- for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
+ for (i = 0 ; i < result->nRegs ; i++)
if (i < sym->nRegs )
result->regs[i] = sym->regs[i] ;
else
/* if we need ptr regs for the right side
then mark it */
- if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) {
+ if (POINTER_GET(ic) && IS_SYMOP(IC_LEFT(ic))
+ && getSize(OP_SYMBOL(IC_LEFT(ic))->type)
+ <= PTRSIZE)
+ {
mcs51_ptrRegReq++;
ptrRegSet = 1;
}
OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
/* do the same for the right operand */
if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
- OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=')
+ OP_SYMBOL(IC_RIGHT(ic))->nRegs)
positionRegs(OP_SYMBOL(IC_RESULT(ic)),
OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
rumask = newBitVect(mcs51_nRegs);
- for (j = 0; j < sym->nRegs; j++) {
+ for (j = 0; j < sym->nRegs; j++) {
rumask = bitVectSetBit(rumask,
sym->regs[j]->rIdx);
}
/*-----------------------------------------------------------------*/
static int packRegsForAssign (iCode *ic,eBBlock *ebp)
{
- iCode *dic, *sic;
-
- if (
-/* !IS_TRUE_SYMOP(IC_RESULT(ic)) || */
- !IS_ITEMP(IC_RIGHT(ic)) ||
+ iCode *dic, *sic;
+ link *etype = operandType(IC_RIGHT(ic));
+
+ if (!IS_ITEMP(IC_RIGHT(ic)) ||
+ OP_SYMBOL(IC_RIGHT(ic))->isind ||
OP_LIVETO(IC_RIGHT(ic)) > ic->seq ||
- OP_SYMBOL(IC_RIGHT(ic))->isind)
+ IS_BITFIELD(etype)) {
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))) {
if (SKIP_IC2(dic))
continue;
-
+
+ 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))
if (!dic)
return 0 ; /* did not find */
-
+
+ /* if assignment then check that right is not a bit */
+ if (ASSIGNMENT(dic) && !POINTER_SET(dic)) {
+ link *etype = operandType(IC_RIGHT(dic));
+ if (IS_BITFIELD(etype)) return 0;
+ }
/* 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 ||
(IC_RIGHT(dic) &&
IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
return 0;
- }
+ }
pack:
/* found the definition */
/* replace the result with the result of */
}
remiCodeFromeBBlock(ebp,ic);
+ hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
+ OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
return 1;
}
IC_LEFT(ic)->operand.symOperand =
IC_RIGHT(dic)->operand.symOperand;
IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
- remiCodeFromeBBlock(ebp,dic);
+ remiCodeFromeBBlock(ebp,dic);
+ hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
change++;
}
IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
remiCodeFromeBBlock(ebp,dic);
+ hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
change ++;
}
/* only upto 2 bytes since we cannot predict
the usage of b, & acc */
- if (getSize(operandType(op)) > 2 &&
+ if (getSize(operandType(op)) > (fReturnSize - 2) &&
ic->op != RETURN &&
- ic->op != SEND)
+ ic->op != SEND &&
+ !POINTER_SET(ic) &&
+ !POINTER_GET(ic))
return NULL;
/* this routine will mark the a symbol as used in one
/* also make sure the intervenening instructions
don't have any thing in far space */
- for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
+ 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)
operation is a '*','/' or '%' then 'b' may
cause a problem */
if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
- getSize(aggrToPtr(operandType(op),FALSE)) >= 3)
+ getSize(operandType(op)) >= 3)
return NULL;
/* if left or right or result is in far space */
- if (isOperandInFarSpace(IC_LEFT(dic)) ||
+ if (isOperandInFarSpace(IC_LEFT(dic)) ||
isOperandInFarSpace(IC_RIGHT(dic)) ||
isOperandInFarSpace(IC_RESULT(dic)) ||
IS_OP_RUONLY(IC_LEFT(dic)) ||
getSize(operandType(IC_RESULT(ic))) > 1))
return ;
+ if (IS_BITWISE_OP(ic) &&
+ getSize(operandType(IC_RESULT(ic))) > 1)
+ return ;
+
/* has only one definition */
if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
return ;
- if (dic->op != '=' || POINTER_SET(dic) || IS_ITEMP(IC_RESULT(dic)))
+ if (dic->op != '=' || POINTER_SET(dic))
return;
/* we now we know that it has one & only one def & use
and the that the definition is an assignment */
IC_LEFT(ic) = IC_RIGHT(dic);
- remiCodeFromeBBlock(ebp,dic);
+ remiCodeFromeBBlock(ebp,dic);
+ hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
}
/*-----------------------------------------------------------------*/
}
/* if this is a +/- operation with a rematerizable
- then mark this as rematerializable as well only
- if the literal value is within the range -255 and + 255
- the assembler cannot handle it other wise */
+ then mark this as rematerializable as well */
if ((ic->op == '+' || ic->op == '-') &&
-
(IS_SYMOP(IC_LEFT(ic)) &&
IS_ITEMP(IC_RESULT(ic)) &&
OP_SYMBOL(IC_LEFT(ic))->remat &&
IS_OP_LITERAL(IC_RIGHT(ic))) ) {
int i = operandLitValue(IC_RIGHT(ic));
- if ( i < 255 && i > -255) {
- OP_SYMBOL(IC_RESULT(ic))->remat = 1;
- OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
- OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
- }
+ OP_SYMBOL(IC_RESULT(ic))->remat = 1;
+ OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
+ OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
}
/* mark the pointer usages */
can be eliminated for return statements */
if ((ic->op == RETURN || ic->op == SEND) &&
!isOperandInFarSpace(IC_LEFT(ic)) &&
- !options.model)
+ options.model == MODEL_SMALL)
packRegsForOneuse (ic,IC_LEFT(ic),ebp);
/* if pointer set & left has a size more than
link *toType = operandType(IC_LEFT(ic));
if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
- getSize(fromType) != getSize(toType) ) {
+ getSize(fromType) != getSize(toType) &&
+ SPEC_USIGN(fromType) == SPEC_USIGN(toType)) {
iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
if (dic) {
if (IS_ARITHMETIC_OP(dic)) {
IC_RESULT(dic) = IC_RESULT(ic);
remiCodeFromeBBlock(ebp,ic);
+ hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
+ OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
ic = ic->prev;
} else
OP_SYMBOL(IC_RIGHT(ic))->ruonly = 0;
if (dic) {
IC_RESULT(dic) = IC_RESULT(ic);
remiCodeFromeBBlock(ebp,ic);
+ hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
+ OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
ic = ic->prev;
}
}
the result of that operation is not on stack then
we can leave the result of this operation in acc:b
combination */
- if ((IS_ARITHMETIC_OP(ic)
-
- || IS_BITWISE_OP(ic)
-
+ if ((IS_ARITHMETIC_OP(ic)
+ || IS_BITWISE_OP(ic)
|| ic->op == LEFT_OP || ic->op == RIGHT_OP
-
+ || (ic->op == ADDRESS_OF && isOperandOnStack(IC_LEFT(ic)))
) &&
IS_ITEMP(IC_RESULT(ic)) &&
getSize(operandType(IC_RESULT(ic))) <= 2)
/* redo that offsets for stacked automatic variables */
redoStackOffsets ();
- if (options.dump_rassgn)
+ if (options.dump_rassgn) {
dumpEbbsToFileExt(".dumprassgn",ebbs,count);
+ dumpLiveRanges(".lrange",liveRanges);
+ }
+
+ /* do the overlaysegment stuff SDCCmem.c */
+ doOverlays(ebbs,count);
/* now get back the chain */
ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));