regsAVR[i].isFree ) {
regsAVR[i].isFree = 0;
if (currFunc)
- currFunc->regsUsed =
- bitVectSetBit(currFunc->regsUsed,i);
+ currFunc->regsUsed = bitVectSetBit(currFunc->regsUsed,i);
return ®sAVR[i];
}
/* other wise look for specific type
(ic = hTabItemWithKey(iCodehTab,i)) &&
( ic->seq >= fseq && ic->seq <= toseq))
- return FALSE;
-
+ return FALSE;
}
return TRUE;
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;
}
}
goto tryAgain ;
}
+/*-----------------------------------------------------------------*/
+/* getRegScr - will try for SCR if not a GPR type if not spil */
+/*-----------------------------------------------------------------*/
+static regs *getRegScr (iCode *ic, eBBlock *ebp, symbol *sym)
+{
+ regs *reg;
+
+ tryAgain:
+ /* try for a ptr type */
+ if ((reg = allocReg(REG_SCR)))
+ return reg;
+
+ /* try for gpr type */
+ if ((reg = allocReg(REG_GPR)))
+ return reg;
+
+ /* we have to spil */
+ if (!spilSomething (ic,ebp,sym))
+ return NULL ;
+
+ /* this looks like an infinite loop but
+ in really selectSpil will abort */
+ goto tryAgain ;
+}
+
/*-----------------------------------------------------------------*/
/* getRegGpr - will try for GPR if not spil */
/*-----------------------------------------------------------------*/
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 (result->regType == REG_SCR)
+ result->regs[i] = getRegScr(ic,ebp,result);
else
- result->regs[i] = getRegGpr (ic,ebp,result);
+ result->regs[i] = getRegGpr (ic,ebp,result);
_G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
for (j = 0 ; j < sym->nRegs ;j++ ) {
if (sym->regType == REG_PTR)
sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
+ else if (sym->regType == REG_SCR)
+ sym->regs[j] = getRegScr(ic,ebbs[i],sym);
else
sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
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);
continue ;
/* for all the registers allocated to it */
- for (k = 0 ; k < sym->nRegs ;k++)
- if (sym->regs[k])
+ for (k = 0 ; k < sym->nRegs ;k++) {
+ if (sym->regs[k]) {
ic->rMask =
bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
+ /* special case for X & Z registers */
+ if (k == R26_IDX || k == R27_IDX)
+ ic->rMask = bitVectSetBit(ic->rMask,X_IDX);
+ if (k == R30_IDX || k == R31_IDX)
+ ic->rMask = bitVectSetBit(ic->rMask,Z_IDX);
+ }
+ }
}
}
}
/* 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 */
/* only upto 2 bytes since we cannot predict
the usage of b, & acc */
- if (getSize(operandType(op)) > (fReturnSize - 2) &&
+ if (getSize(operandType(op)) > fAVRReturnSize &&
ic->op != RETURN &&
ic->op != SEND)
return NULL;
a function call */
if (dic->op == CALL || dic->op == PCALL ) {
if (ic->op != SEND && ic->op != RETURN) {
-/* OP_SYMBOL(op)->ruonly = 1; */
+ OP_SYMBOL(op)->ruonly = 1;
return dic;
}
dic = dic->next ;
/* 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)) ||
+ if (IS_OP_RUONLY(IC_LEFT(ic)) ||
IS_OP_RUONLY(IC_RIGHT(ic)) ) {
return NULL;
}
return NULL;
/* if left or right or result is in far space */
- if (isOperandInFarSpace(IC_LEFT(dic)) ||
- isOperandInFarSpace(IC_RIGHT(dic)) ||
- isOperandInFarSpace(IC_RESULT(dic)) ||
- IS_OP_RUONLY(IC_LEFT(dic)) ||
+ if (IS_OP_RUONLY(IC_LEFT(dic)) ||
IS_OP_RUONLY(IC_RIGHT(dic)) ||
IS_OP_RUONLY(IC_RESULT(dic)) ) {
return NULL;
}
}
-/* OP_SYMBOL(op)->ruonly = 1; */
+ OP_SYMBOL(op)->ruonly = 1;
return sic;
}
/* some cases the redundant moves can
can be eliminated for return statements */
-/* if ((ic->op == RETURN || ic->op == SEND) && */
-/* !isOperandInFarSpace(IC_LEFT(ic)) && */
-/* !options.model) */
-/* packRegsForOneuse (ic,IC_LEFT(ic),ebp); */
+ if ((ic->op == RETURN || ic->op == SEND))
+ packRegsForOneuse (ic,IC_LEFT(ic),ebp);
/* if pointer set & left has a size more than
one and right is not in far space */
if (ic->op == RECEIVE) {
symbol *r = OP_SYMBOL(IC_RESULT(ic));
int size = getSize(r->type);
- if (r->regType == REG_GPR) {
+ if (r->regType == REG_GPR || r->regType == REG_SCR) {
int j = 0;
while (size--) {
r->regs[j++] = ®sAVR[i++];
/*-----------------------------------------------------------------*/
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[R26_IDX].isFree =
+ regsAVR[R27_IDX].isFree =
+ regsAVR[R30_IDX].isFree =
+ regsAVR[R31_IDX].isFree = 1;
+
if (!avr_ptrRegReq) {
- regsAVR[R26_IDX].isFree =
- regsAVR[R27_IDX].isFree =
- regsAVR[R30_IDX].isFree =
- regsAVR[R31_IDX].isFree = 1;
regsAVR[R26_IDX].type =
regsAVR[R27_IDX].type =
regsAVR[R30_IDX].type =
regsAVR[R31_IDX].type = REG_GPR ;
} else {
- regsAVR[R26_IDX].isFree =
- regsAVR[R27_IDX].isFree =
- regsAVR[R30_IDX].isFree =
- regsAVR[R31_IDX].isFree = 1;
regsAVR[R26_IDX].type =
regsAVR[R27_IDX].type =
regsAVR[R30_IDX].type =
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_SCR;
+ 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++ )
genAVRCode(ic);
-
+/* for (; ic ; ic = ic->next) */
+/* piCode(ic,stdout); */
/* free up any _G.stackSpil locations allocated */
applyToSet(_G.stackSpil,deallocStackSpil);
_G.slocNum = 0;