#define OP_LIVEFROM(op) op->operand.symOperand->liveFrom
#define OP_LIVETO(op) op->operand.symOperand->liveTo
#define OP_REQV(op) op->operand.symOperand->reqv
+#define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
/* typedef for operand */
typedef struct operand {
unsigned int isParm :1 ; /* is a parameter */
unsigned int isLiteral:1 ; /* operand is literal */
unsigned int noSpilLoc:1 ; /* cannot be assigned a spil location */
-
+
unsigned key ;
int parmBytes;
union {
for ( lrange = hTabFirstItem(liveRanges,&k); lrange;
lrange = hTabNextItem(liveRanges,&k)) {
+ /* if it is live then add the lrange to ic->rlive */
if (lrange->liveFrom <= ic->seq &&
- lrange->liveTo >= ic->seq )
- ic->rlive = bitVectSetBit(ic->rlive,lrange->key);
+ lrange->liveTo >= ic->seq ) {
+ lrange->isLiveFcall = (ic->op == CALL || ic->op == PCALL);
+ ic->rlive = bitVectSetBit(ic->rlive,lrange->key);
+ }
}
}
}
/* following flags are used by the backend
for code generation and can be changed
if a better scheme for backend is thought of */
-
+ unsigned isLiveFcall:1 ; /* is live at or across a function call */
unsigned isspilt :1 ; /* has to be spilt */
unsigned remat :1 ; /* can be remateriazed */
unsigned isptr :1 ; /* is a pointer */
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;
}
}
/* determine the type of register required */
if (sym->nRegs == 2 && /* size is two */
IS_PTR(sym->type) && /* is a pointer */
- sym->uptr) { /* has has pointer usage i.e. get/set pointer */
+ sym->uptr) { /* has pointer usage i.e. get/set pointer */
sym->regType = REG_PTR ;
avr_ptrRegReq++;
}
- else
- sym->regType = REG_GPR ;
-
+ else {
+ /* live accross a function call then gpr else scratch */
+ if (sym->isLiveFcall)
+ sym->regType = REG_GPR ;
+ else
+ sym->regType = REG_SCR ;
+ }
} else
/* for the first run we don't provide */
/* registers for true symbols we will */
/*-----------------------------------------------------------------*/
static void setDefaultRegs(eBBlock **ebbs,int count)
{
+ int i ;
/* if no pointer registers required in this function
then mark r26-27 & r30-r31 as GPR & free */
regsAVR[R1_IDX].isFree =
regsAVR[R24_IDX].isFree =
regsAVR[R25_IDX].isFree = 0;
-
+
/* if this has no function calls then we need
to do something special
a) pre-assign registers to parameters RECEIVE
b) mark the remaining parameter regs as free */
if (!currFunc->hasFcall) {
+ /* mark the parameter regs as GPR */
+ for (i= R16_IDX ; i <= R23_IDX ;i++) {
+ regsAVR[i].type = REG_GPR;
+ regsAVR[i].isFree = 1;
+ }
preAssignParms(ebbs[0]->sch);
} else {
- int i=0;
- for (i= R16_IDX ; i <= R23_IDX ;i++)
- regsAVR[i].isFree = 0;
+
+ /* otherwise mark them as free scratch */
+ for (i= R16_IDX ; i <= R23_IDX ;i++) {
+ regsAVR[i].type = REG_SCR;
+ regsAVR[i].isFree = 1;
+ }
}
/* Y - is not allocated (it is the stack frame) */
setToNull((void *)&_G.funcrUsed);
avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
- /* setup other default register allocation */
/* change assignments this will remove some
live ranges reducing some register pressure */
for (i = 0 ; i < count ;i++ )