You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
-#include <stdio.h>
-#include <stdlib.h>
-#include "SDCCglobl.h"
-#include "SDCCast.h"
-#include "SDCCmem.h"
-#include "SDCCy.h"
-#include "SDCChasht.h"
-#include "SDCCbitv.h"
-#include "SDCCset.h"
-#include "SDCCicode.h"
-#include "SDCClabel.h"
-#include "SDCCBBlock.h"
-#include "SDCCloop.h"
-#include "SDCCcse.h"
-#include "SDCCcflow.h"
-#include "SDCCdflow.h"
-#include "SDCClrange.h"
-#include "SDCCralloc.h"
+
+#include "common.h"
+#include "ralloc.h"
+#include "gen.h"
/*-----------------------------------------------------------------*/
/* At this point we start getting processor specific although */
/* since the pack the registers depending strictly on the MCU */
/*-----------------------------------------------------------------*/
-bitVect *spiltSet = NULL ;
-set *stackSpil = NULL;
-bitVect *regAssigned = NULL;
-short blockSpil = 0;
-int slocNum = 0 ;
extern void gen51Code(iCode *);
-int ptrRegReq = 0; /* one byte pointer register required */
-bitVect *funcrUsed = NULL; /* registers used in a function */
-int stackExtend = 0;
-int dataExtend = 0;
+
+/* Global data */
+static struct {
+ bitVect *spiltSet;
+ set *stackSpil;
+ bitVect *regAssigned;
+ short blockSpil;
+ int slocNum;
+ bitVect *funcrUsed; /* registers used in a function */
+ int stackExtend;
+ int dataExtend;
+} _G;
+
+/* Shared with gen.c */
+int mcs51_ptrRegReq; /* one byte pointer register required */
/* 8051 registers */
regs regs8051[] =
{ REG_GPR ,X12_IDX,REG_GPR , "x12", "x12", "xreg", 4, 1 },
{ REG_CND ,CND_IDX,REG_CND , "C" , "C" , "xreg", 0, 1 },
};
-int nRegs = 13;
-void spillThis (symbol *);
+int mcs51_nRegs = 13;
+static void spillThis (symbol *);
/*-----------------------------------------------------------------*/
/* allocReg - allocates register of given type */
/*-----------------------------------------------------------------*/
-regs *allocReg (short type)
+static regs *allocReg (short type)
{
int i;
- for ( i = 0 ; i < nRegs ; i++ ) {
+ for ( i = 0 ; i < mcs51_nRegs ; i++ ) {
/* if type is given as 0 then any
free register will do */
}
/*-----------------------------------------------------------------*/
-/* regWithIdx - returns pointer to register wit index number */
+/* mcs51_regWithIdx - returns pointer to register wit index number */
/*-----------------------------------------------------------------*/
-regs *regWithIdx (int idx)
+regs *mcs51_regWithIdx (int idx)
{
int i ;
- for (i=0;i < nRegs;i++)
+ for (i=0;i < mcs51_nRegs;i++)
if (regs8051[i].rIdx == idx)
return ®s8051[i];
/*-----------------------------------------------------------------*/
/* freeReg - frees a register */
/*-----------------------------------------------------------------*/
-void freeReg (regs *reg)
+static void freeReg (regs *reg)
{
reg->isFree = 1;
}
/*-----------------------------------------------------------------*/
/* nFreeRegs - returns number of free registers */
/*-----------------------------------------------------------------*/
-int nFreeRegs (int type)
+static int nFreeRegs (int type)
{
int i;
int nfr=0;
- for (i = 0 ; i < nRegs; i++ )
+ for (i = 0 ; i < mcs51_nRegs; i++ )
if (regs8051[i].isFree && regs8051[i].type == type)
nfr++;
return nfr;
/*-----------------------------------------------------------------*/
/* nfreeRegsType - free registers with type */
/*-----------------------------------------------------------------*/
-int nfreeRegsType (int type)
+static int nfreeRegsType (int type)
{
int nfr ;
if (type == REG_PTR) {
/*-----------------------------------------------------------------*/
/* allDefsOutOfRange - all definitions are out of a range */
/*-----------------------------------------------------------------*/
-bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq)
+static bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq)
{
int i ;
/*-----------------------------------------------------------------*/
/* computeSpillable - given a point find the spillable live ranges */
/*-----------------------------------------------------------------*/
-bitVect *computeSpillable (iCode *ic)
+static bitVect *computeSpillable (iCode *ic)
{
bitVect *spillable ;
spillable = bitVectCopy(ic->rlive);
spillable =
- bitVectCplAnd(spillable,spiltSet); /* those already spilt */
+ bitVectCplAnd(spillable,_G.spiltSet); /* those already spilt */
spillable =
bitVectCplAnd(spillable,ic->uses); /* used in this one */
bitVectUnSetBit(spillable,ic->defKey);
- spillable = bitVectIntersect(spillable,regAssigned);
+ spillable = bitVectIntersect(spillable,_G.regAssigned);
return spillable;
}
/*-----------------------------------------------------------------*/
/* noSpilLoc - return true if a variable has no spil location */
/*-----------------------------------------------------------------*/
-int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
+static int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
{
return (sym->usl.spillLoc ? 0 : 1);
}
/*-----------------------------------------------------------------*/
/* hasSpilLoc - will return 1 if the symbol has spil location */
/*-----------------------------------------------------------------*/
-int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
+static int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
{
return (sym->usl.spillLoc ? 1 : 0);
}
/*-----------------------------------------------------------------*/
/* directSpilLoc - will return 1 if the splilocation is in direct */
/*-----------------------------------------------------------------*/
-int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
+static int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
{
if ( sym->usl.spillLoc &&
(IN_DIRSPACE(SPEC_OCLS(sym->usl.spillLoc->etype))))
/* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/
/* but is not used as a pointer */
/*-----------------------------------------------------------------*/
-int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
+static int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
{
return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
}
/*-----------------------------------------------------------------*/
/* rematable - will return 1 if the remat flag is set */
/*-----------------------------------------------------------------*/
-int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
+static int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
{
return sym->remat;
}
/*-----------------------------------------------------------------*/
/* notUsedInBlock - not used in this block */
/*-----------------------------------------------------------------*/
-int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
+static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
{
return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) &&
allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
/*-----------------------------------------------------------------*/
/* notUsedInRemaining - not used or defined in remain of the block */
/*-----------------------------------------------------------------*/
-int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
+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));
}
/*-----------------------------------------------------------------*/
/* allLRs - return true for all */
/*-----------------------------------------------------------------*/
-int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
+static int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
{
return 1;
}
/*-----------------------------------------------------------------*/
/* liveRangesWith - applies function to a given set of live range */
/*-----------------------------------------------------------------*/
-set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
+static set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
eBBlock *ebp, iCode *ic)
{
set *rset = NULL;
exit(1);
}
- if (func(sym,ebp,ic) && bitVectBitValue(regAssigned,sym->key))
+ if (func(sym,ebp,ic) && bitVectBitValue(_G.regAssigned,sym->key))
addSetHead(&rset,sym);
}
/*-----------------------------------------------------------------*/
/* leastUsedLR - given a set determines which is the least used */
/*-----------------------------------------------------------------*/
-symbol *leastUsedLR (set *sset)
+static symbol *leastUsedLR (set *sset)
{
symbol *sym = NULL, *lsym = NULL ;
/*-----------------------------------------------------------------*/
/* noOverLap - will iterate through the list looking for over lap */
/*-----------------------------------------------------------------*/
-int noOverLap (set *itmpStack, symbol *fsym)
+static int noOverLap (set *itmpStack, symbol *fsym)
{
symbol *sym;
/*-----------------------------------------------------------------*/
/* isFree - will return 1 if the a free spil location is found */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(isFree)
+static DEFSETFUNC(isFree)
{
symbol *sym = item;
V_ARG(symbol **,sloc);
/*-----------------------------------------------------------------*/
/* spillLRWithPtrReg :- will spil those live ranges which use PTR */
/*-----------------------------------------------------------------*/
-void spillLRWithPtrReg (symbol *forSym)
+static void spillLRWithPtrReg (symbol *forSym)
{
symbol *lrsym;
regs *r0,*r1;
int k;
- if (!regAssigned ||
- bitVectIsZero(regAssigned))
+ if (!_G.regAssigned ||
+ bitVectIsZero(_G.regAssigned))
return;
- r0 = regWithIdx(R0_IDX);
- r1 = regWithIdx(R1_IDX);
+ r0 = mcs51_regWithIdx(R0_IDX);
+ r1 = mcs51_regWithIdx(R1_IDX);
/* for all live ranges */
for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ;
/*-----------------------------------------------------------------*/
/* createStackSpil - create a location on the stack to spil */
/*-----------------------------------------------------------------*/
-symbol *createStackSpil (symbol *sym)
+static symbol *createStackSpil (symbol *sym)
{
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 */
- if (applyToSet(stackSpil,isFree,&sloc, sym)) {
+ if (applyToSet(_G.stackSpil,isFree,&sloc, sym)) {
/* found a free one : just update & return */
sym->usl.spillLoc = sloc;
sym->stackSpil= 1;
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",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 */
if (IN_STACK(sloc->etype)) {
currFunc->stack += getSize(sloc->type);
- stackExtend += getSize(sloc->type);
+ _G.stackExtend += getSize(sloc->type);
} else
- dataExtend += getSize(sloc->type);
+ _G.dataExtend += getSize(sloc->type);
- /* add it to the stackSpil set */
- addSetHead(&stackSpil,sloc);
+ /* add it to the _G.stackSpil set */
+ addSetHead(&_G.stackSpil,sloc);
sym->usl.spillLoc = sloc;
sym->stackSpil = 1;
/*-----------------------------------------------------------------*/
/* isSpiltOnStack - returns true if the spil location is on stack */
/*-----------------------------------------------------------------*/
-bool isSpiltOnStack (symbol *sym)
+static bool isSpiltOnStack (symbol *sym)
{
link *etype;
if (!sym->isspilt)
return FALSE ;
-/* if (sym->stackSpil) */
+/* if (sym->_G.stackSpil) */
/* return TRUE; */
if (!sym->usl.spillLoc)
/*-----------------------------------------------------------------*/
/* spillThis - spils a specific operand */
/*-----------------------------------------------------------------*/
-void spillThis (symbol *sym)
+static void spillThis (symbol *sym)
{
int i;
/* if this is rematerializable or has a spillLocation
/* mark it has spilt & put it in the spilt set */
sym->isspilt = 1;
- spiltSet = bitVectSetBit(spiltSet,sym->key);
+ _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key);
- bitVectUnSetBit(regAssigned,sym->key);
+ bitVectUnSetBit(_G.regAssigned,sym->key);
for (i = 0 ; i < sym->nRegs ; i++)
/* if spilt on stack then free up r0 & r1
if they could have been assigned to some
LIVE ranges */
- if (!ptrRegReq && isSpiltOnStack(sym)) {
- ptrRegReq++ ;
+ if (!mcs51_ptrRegReq && isSpiltOnStack(sym)) {
+ mcs51_ptrRegReq++ ;
spillLRWithPtrReg(sym);
}
/*-----------------------------------------------------------------*/
/* selectSpil - select a iTemp to spil : rather a simple procedure */
/*-----------------------------------------------------------------*/
-symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
+static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
{
bitVect *lrcs= NULL ;
set *selectS ;
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 */
- if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
+ if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
sym = leastUsedLR(selectS);
/* if this is not rematerializable */
if (!sym->remat) {
- blockSpil++;
+ _G.blockSpil++;
sym->blockSpil = 1;
}
return sym;
/* check if there are any live ranges that not
used in the remainder of the block */
- if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
+ if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
sym = leastUsedLR (selectS);
- if (!sym->remat) {
- sym->remainSpil = 1;
- blockSpil++;
+ if (sym != forSym) {
+ if (!sym->remat) {
+ sym->remainSpil = 1;
+ _G.blockSpil++;
+ }
+ return sym;
}
- return sym;
}
}
/*-----------------------------------------------------------------*/
/* spilSomething - spil some variable & mark registers as free */
/*-----------------------------------------------------------------*/
-bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
+static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
{
symbol *ssym;
int i ;
/* mark it as spilt */
ssym->isspilt = 1;
- spiltSet = bitVectSetBit(spiltSet,ssym->key);
+ _G.spiltSet = bitVectSetBit(_G.spiltSet,ssym->key);
/* mark it as not register assigned &
take it away from the set */
- bitVectUnSetBit(regAssigned,ssym->key);
+ bitVectUnSetBit(_G.regAssigned,ssym->key);
/* mark the registers as free */
for (i = 0 ; i < ssym->nRegs ;i++ )
/* if spilt on stack then free up r0 & r1
if they could have been assigned to as gprs */
- if (!ptrRegReq && isSpiltOnStack(ssym) ) {
- ptrRegReq++ ;
+ if (!mcs51_ptrRegReq && isSpiltOnStack(ssym) ) {
+ mcs51_ptrRegReq++ ;
spillLRWithPtrReg(ssym);
}
/*-----------------------------------------------------------------*/
/* 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;
/*-----------------------------------------------------------------*/
/* getRegGpr - will try for GPR if not spil */
/*-----------------------------------------------------------------*/
-regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
+static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
{
regs *reg;
if ((reg = allocReg(REG_GPR)))
return reg;
- if (!ptrRegReq)
+ if (!mcs51_ptrRegReq)
if ((reg = allocReg(REG_PTR)))
return reg ;
-
+
/* we have to spil */
if (!spilSomething (ic,ebp,sym))
return NULL ;
/* deassignLRs - check the live to and if they have registers & are*/
/* not spilt then free up the registers */
/*-----------------------------------------------------------------*/
-void deassignLRs (iCode *ic, eBBlock *ebp)
+static void deassignLRs (iCode *ic, eBBlock *ebp)
{
symbol *sym;
int k;
continue ;
}
- if (!bitVectBitValue(regAssigned,sym->key))
+ if (!bitVectBitValue(_G.regAssigned,sym->key))
continue;
/* special case check if this is an IFX &
if (sym->nRegs) {
int i = 0;
- bitVectUnSetBit(regAssigned,sym->key);
+ bitVectUnSetBit(_G.regAssigned,sym->key);
/* if the result of this one needs registers
and does not have it then assign it right
result->nRegs && /* which needs registers */
! result->isspilt && /* and does not already have them */
! result->remat &&
- ! bitVectBitValue(regAssigned,result->key) &&
+ ! bitVectBitValue(_G.regAssigned,result->key) &&
/* the number of free regs + number of regs in this LR
can accomodate the what result Needs */
((nfreeRegsType(result->regType) +
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
result->regs[i] = getRegGpr (ic,ebp,result);
- regAssigned = bitVectSetBit(regAssigned,result->key);
+ _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
}
/*-----------------------------------------------------------------*/
/* reassignLR - reassign this to registers */
/*-----------------------------------------------------------------*/
-void reassignLR (operand *op)
+static void reassignLR (operand *op)
{
symbol *sym = OP_SYMBOL(op);
int i;
/* not spilt any more */
sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
- bitVectUnSetBit(spiltSet,sym->key);
+ bitVectUnSetBit(_G.spiltSet,sym->key);
- regAssigned = bitVectSetBit(regAssigned,sym->key);
+ _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
- blockSpil--;
+ _G.blockSpil--;
for (i=0;i<sym->nRegs;i++)
sym->regs[i]->isFree = 0;
/*-----------------------------------------------------------------*/
/* willCauseSpill - determines if allocating will cause a spill */
/*-----------------------------------------------------------------*/
-int willCauseSpill ( int nr, int rt)
+static int willCauseSpill ( int nr, int rt)
{
/* first check if there are any avlb registers
of te type required */
if (nFreeRegs(REG_GPR) >= nr)
return 0;
} else {
- if (ptrRegReq) {
+ if (mcs51_ptrRegReq) {
if (nFreeRegs(rt) >= nr)
return 0;
} else {
/*-----------------------------------------------------------------*/
/* serialRegAssign - serially allocate registers to the variables */
/*-----------------------------------------------------------------*/
-void serialRegAssign (eBBlock **ebbs, int count)
+static void serialRegAssign (eBBlock **ebbs, int count)
{
int i;
or will not live beyond this instructions */
if (!sym->nRegs ||
sym->isspilt ||
- bitVectBitValue(regAssigned,sym->key) ||
+ bitVectBitValue(_G.regAssigned,sym->key) ||
sym->liveTo <= ic->seq)
continue ;
/* if some liverange has been spilt at the block level
and this one live beyond this block then spil this
to be safe */
- if (blockSpil && sym->liveTo > ebbs[i]->lSeq) {
+ if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
spillThis (sym);
continue ;
}
/* if we need ptr regs for the right side
then mark it */
- if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) {
- ptrRegReq++;
+ if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type)
+ <= PTRSIZE)
+ {
+ mcs51_ptrRegReq++;
ptrRegSet = 1;
}
/* else we assign registers to it */
- regAssigned = bitVectSetBit(regAssigned,sym->key);
+ _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
for (j = 0 ; j < sym->nRegs ;j++ ) {
if (sym->regType == REG_PTR)
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);
if (ptrRegSet) {
- ptrRegReq--;
+ mcs51_ptrRegReq--;
ptrRegSet = 0;
}
/*-----------------------------------------------------------------*/
/* rUmaskForOp :- returns register mask for an operand */
/*-----------------------------------------------------------------*/
-bitVect *rUmaskForOp (operand *op)
+static bitVect *rUmaskForOp (operand *op)
{
bitVect *rumask;
symbol *sym;
if (sym->isspilt || !sym->nRegs)
return NULL;
- rumask = newBitVect(nRegs);
+ 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);
}
/*-----------------------------------------------------------------*/
/* regsUsedIniCode :- returns bit vector of registers used in iCode*/
/*-----------------------------------------------------------------*/
-bitVect *regsUsedIniCode (iCode *ic)
+static bitVect *regsUsedIniCode (iCode *ic)
{
- bitVect *rmask = newBitVect(nRegs);
+ bitVect *rmask = newBitVect(mcs51_nRegs);
/* do the special cases first */
if (ic->op == IFX ) {
/*-----------------------------------------------------------------*/
/* createRegMask - for each instruction will determine the regsUsed*/
/*-----------------------------------------------------------------*/
-void createRegMask (eBBlock **ebbs, int count)
+static void createRegMask (eBBlock **ebbs, int count)
{
int i;
/* first mark the registers used in this
instruction */
ic->rUsed = regsUsedIniCode(ic);
- funcrUsed = bitVectUnion(funcrUsed,ic->rUsed);
+ _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
/* now create the register mask for those
registers that are in use : this is a
super set of ic->rUsed */
- ic->rMask = newBitVect(nRegs+1);
+ ic->rMask = newBitVect(mcs51_nRegs+1);
/* for all live Ranges alive at this point */
for (j = 1; j < ic->rlive->size; j++ ) {
/*-----------------------------------------------------------------*/
/* rematStr - returns the rematerialized string for a remat var */
/*-----------------------------------------------------------------*/
-char *rematStr (symbol *sym)
+static char *rematStr (symbol *sym)
{
char *s = buffer;
iCode *ic = sym->rematiCode;
/*-----------------------------------------------------------------*/
/* regTypeNum - computes the type & number of registers required */
/*-----------------------------------------------------------------*/
-void regTypeNum ()
+static void regTypeNum ()
{
symbol *sym;
int k;
/*-----------------------------------------------------------------*/
/* freeAllRegs - mark all registers as free */
/*-----------------------------------------------------------------*/
-void freeAllRegs()
+static void freeAllRegs()
{
int i;
- for (i=0;i< nRegs;i++ )
+ for (i=0;i< mcs51_nRegs;i++ )
regs8051[i].isFree = 1;
}
/*-----------------------------------------------------------------*/
/* deallocStackSpil - this will set the stack pointer back */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(deallocStackSpil)
+static DEFSETFUNC(deallocStackSpil)
{
symbol *sym = item;
/*-----------------------------------------------------------------*/
/* packRegsForAssign - register reduction for assignment */
/*-----------------------------------------------------------------*/
-int packRegsForAssign (iCode *ic,eBBlock *ebp)
+static int packRegsForAssign (iCode *ic,eBBlock *ebp)
{
iCode *dic, *sic;
- if (
-/* !IS_TRUE_SYMOP(IC_RESULT(ic)) || */
- !IS_ITEMP(IC_RIGHT(ic)) ||
- OP_LIVETO(IC_RIGHT(ic)) > ic->seq ||
- OP_SYMBOL(IC_RIGHT(ic))->isind)
+ if (!IS_ITEMP(IC_RIGHT(ic)) ||
+ OP_SYMBOL(IC_RIGHT(ic))->isind ||
+ OP_LIVETO(IC_RIGHT(ic)) > ic->seq) {
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))
}
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;
}
/*-----------------------------------------------------------------*/
/* findAssignToSym : scanning backwards looks for first assig found*/
/*-----------------------------------------------------------------*/
-iCode *findAssignToSym (operand *op,iCode *ic)
+static iCode *findAssignToSym (operand *op,iCode *ic)
{
iCode *dic;
/*-----------------------------------------------------------------*/
/* packRegsForSupport :- reduce some registers for support calls */
/*-----------------------------------------------------------------*/
-int packRegsForSupport (iCode *ic, eBBlock *ebp)
+static int packRegsForSupport (iCode *ic, eBBlock *ebp)
{
int change = 0 ;
/* for the left & right operand :- look to see if the
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)) ||
/*-----------------------------------------------------------------*/
/* packRegsForAccUse - pack registers for acc use */
/*-----------------------------------------------------------------*/
-void packRegsForAccUse (iCode *ic)
+static void packRegsForAccUse (iCode *ic)
{
iCode *uic;
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)
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 */
if (!SKIP_IC2(ic)) {
/* if we are using a symbol on the stack
- then we should say ptrRegReq */
+ then we should say mcs51_ptrRegReq */
if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
- ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
+ mcs51_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
else
if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
- ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
+ mcs51_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
else {
if (IS_SYMOP(IC_LEFT(ic)))
- ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
+ mcs51_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
if (IS_SYMOP(IC_RIGHT(ic)))
- ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
+ mcs51_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
if (IS_SYMOP(IC_RESULT(ic)))
- ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
+ mcs51_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);
}
}
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)
/*-----------------------------------------------------------------*/
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
-void assignRegisters (eBBlock **ebbs, int count)
+void mcs51_assignRegisters (eBBlock **ebbs, int count)
{
iCode *ic;
int i ;
- setToNull((void *)&funcrUsed);
- ptrRegReq = stackExtend = dataExtend = 0;
+ setToNull((void *)&_G.funcrUsed);
+ mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
/* if not register extentions then reduce number
of registers */
if (options.regExtend)
- nRegs = 13;
+ mcs51_nRegs = 13;
else
- nRegs = 8;
+ mcs51_nRegs = 8;
/* change assignments this will remove some
live ranges reducing some register pressure */
serialRegAssign(ebbs,count);
/* if stack was extended then tell the user */
- if (stackExtend) {
+ if (_G.stackExtend) {
/* werror(W_TOOMANY_SPILS,"stack", */
-/* stackExtend,currFunc->name,""); */
- stackExtend = 0 ;
+/* _G.stackExtend,currFunc->name,""); */
+ _G.stackExtend = 0 ;
}
- if (dataExtend) {
+ if (_G.dataExtend) {
/* werror(W_TOOMANY_SPILS,"data space", */
-/* dataExtend,currFunc->name,""); */
- dataExtend = 0 ;
+/* _G.dataExtend,currFunc->name,""); */
+ _G.dataExtend = 0 ;
}
/* after that create the register mask
/* 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));
gen51Code(ic);
- /* free up any stackSpil locations allocated */
- applyToSet(stackSpil,deallocStackSpil);
- slocNum = 0;
- setToNull((void **)&stackSpil);
- setToNull((void **)&spiltSet);
+ /* free up any _G.stackSpil locations allocated */
+ applyToSet(_G.stackSpil,deallocStackSpil);
+ _G.slocNum = 0;
+ setToNull((void **)&_G.stackSpil);
+ setToNull((void **)&_G.spiltSet);
/* mark all registers as free */
freeAllRegs();