/* AVR registers */
regs regsAVR[] = {
- {REG_GPR, R0_IDX, REG_GPR, "r0", "r0", "", 0, 0, 0}, /* scratch */
- {REG_GPR, R1_IDX, REG_GPR, "r1", "r1", "", 0, 0, 0}, /* scratch */
- {REG_GPR, R2_IDX, REG_GPR, "r2", "r2", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R3_IDX, REG_GPR, "r3", "r3", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R4_IDX, REG_GPR, "r4", "r4", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R5_IDX, REG_GPR, "r5", "r5", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R6_IDX, REG_GPR, "r6", "r6", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R7_IDX, REG_GPR, "r7", "r7", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R8_IDX, REG_GPR, "r8", "r8", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R9_IDX, REG_GPR, "r9", "r9", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R10_IDX, REG_GPR, "r10", "r10", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R11_IDX, REG_GPR, "r11", "r11", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R12_IDX, REG_GPR, "r12", "r12", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R13_IDX, REG_GPR, "r13", "r13", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R14_IDX, REG_GPR, "r14", "r14", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R15_IDX, REG_GPR, "r15", "r15", "", 0, 1, 1}, /* gpr */
- {REG_GPR, R16_IDX, REG_GPR, "r16", "r16", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R17_IDX, REG_GPR, "r17", "r17", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R18_IDX, REG_GPR, "r18", "r18", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R19_IDX, REG_GPR, "r19", "r19", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R20_IDX, REG_GPR, "r20", "r20", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R21_IDX, REG_GPR, "r21", "r21", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R22_IDX, REG_GPR, "r22", "r22", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R23_IDX, REG_GPR, "r23", "r23", "", 0, 1, 0}, /* parm/gpr */
- {REG_GPR, R24_IDX, REG_GPR, "r24", "r24", "", 0, 0, 0}, /* scratch */
- {REG_GPR, R25_IDX, REG_GPR, "r25", "r25", "", 0, 0, 0}, /* scratch */
- {REG_GPR, R26_IDX, REG_GPR, "r26", "r26", "", 0, 1, 1}, /* used as pointer reg X */
- {REG_GPR, R27_IDX, REG_GPR, "r27", "r27", "", 0, 1, 1}, /* used as pointer reg X */
- {REG_GPR, R28_IDX, REG_GPR, "r28", "r28", "", 0, 1, 0}, /* stack frame Y */
- {REG_GPR, R29_IDX, REG_GPR, "r29", "r29", "", 0, 1, 0}, /* stack frame Y */
- {REG_GPR, R30_IDX, REG_GPR, "r30", "r30", "", 0, 1, 1}, /* used as pointer reg Z */
- {REG_GPR, R31_IDX, REG_GPR, "r31", "r31", "", 0, 1, 1}, /* used as pointer reg Z */
+ {REG_GPR|REG_PAIR, R0_IDX, REG_GPR|REG_PAIR, "r0", "r0", "", 0, 0, 0}, /* scratch */
+ {REG_GPR, R1_IDX, REG_GPR , "r1", "r1", "", 0, 0, 0}, /* scratch */
+ {REG_GPR|REG_PAIR, R2_IDX, REG_GPR|REG_PAIR, "r2", "r2", "", 0, 1, 1}, /* gpr */
+ {REG_GPR, R3_IDX, REG_GPR , "r3", "r3", "", 0, 1, 1}, /* gpr */
+ {REG_GPR|REG_PAIR, R4_IDX, REG_GPR|REG_PAIR, "r4", "r4", "", 0, 1, 1}, /* gpr */
+ {REG_GPR, R5_IDX, REG_GPR , "r5", "r5", "", 0, 1, 1}, /* gpr */
+ {REG_GPR|REG_PAIR, R6_IDX, REG_GPR|REG_PAIR, "r6", "r6", "", 0, 1, 1}, /* gpr */
+ {REG_GPR, R7_IDX, REG_GPR , "r7", "r7", "", 0, 1, 1}, /* gpr */
+ {REG_GPR|REG_PAIR, R8_IDX, REG_GPR|REG_PAIR, "r8", "r8", "", 0, 1, 1}, /* gpr */
+ {REG_GPR, R9_IDX, REG_GPR , "r9", "r9", "", 0, 1, 1}, /* gpr */
+ {REG_GPR|REG_PAIR, R10_IDX,REG_GPR|REG_PAIR, "r10", "r10","",0, 1, 1}, /* gpr */
+ {REG_GPR, R11_IDX,REG_GPR , "r11", "r11","",0, 1, 1}, /* gpr */
+ {REG_GPR|REG_PAIR, R12_IDX,REG_GPR|REG_PAIR, "r12", "r12","",0, 1, 1}, /* gpr */
+ {REG_GPR, R13_IDX,REG_GPR , "r13", "r13","",0, 1, 1}, /* gpr */
+ {REG_GPR|REG_PAIR, R14_IDX,REG_GPR|REG_PAIR, "r14", "r14","",0, 1, 1}, /* gpr */
+ {REG_GPR, R15_IDX,REG_GPR , "r15", "r15","",0, 1, 1}, /* gpr */
+ {REG_GPR|REG_PAIR, R16_IDX,REG_GPR|REG_PAIR, "r16", "r16","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR, R17_IDX,REG_GPR , "r17", "r17","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR|REG_PAIR, R18_IDX,REG_GPR|REG_PAIR, "r18", "r18","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR, R19_IDX,REG_GPR , "r19", "r19","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR|REG_PAIR, R20_IDX,REG_GPR|REG_PAIR, "r20", "r20","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR, R21_IDX,REG_GPR , "r21", "r21","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR|REG_PAIR, R22_IDX,REG_GPR|REG_PAIR, "r22", "r22","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR, R23_IDX,REG_GPR , "r23", "r23","",0, 1, 0}, /* parm/gpr */
+ {REG_GPR|REG_PAIR, R24_IDX,REG_GPR|REG_PAIR, "r24", "r24","",0, 0, 0}, /* scratch */
+ {REG_GPR, R25_IDX,REG_GPR , "r25", "r25","",0, 0, 0}, /* scratch */
+ {REG_GPR|REG_PAIR, R26_IDX,REG_GPR|REG_PAIR, "r26", "r26","",0, 1, 1}, /* used as pointer reg X */
+ {REG_GPR, R27_IDX,REG_GPR , "r27", "r27","",0, 1, 1}, /* used as pointer reg X */
+ {REG_GPR|REG_PAIR, R28_IDX,REG_GPR|REG_PAIR, "r28", "r28","",0, 1, 0}, /* stack frame Y */
+ {REG_GPR, R29_IDX,REG_GPR , "r29", "r29","",0, 1, 0}, /* stack frame Y */
+ {REG_GPR|REG_PAIR, R30_IDX,REG_GPR|REG_PAIR, "r30", "r30","",0, 1, 1}, /* used as pointer reg Z */
+ {REG_GPR, R31_IDX,REG_GPR , "r31", "r31","",0, 1, 1}, /* used as pointer reg Z */
{REG_PTR, X_IDX, REG_PTR, "X", "X", "", 0, 1, 0},
{REG_PTR, Z_IDX, REG_PTR, "Z", "Z", "", 0, 1, 0},
};
static void spillThis (symbol *);
+#if 0
+// PENDING: Unused
+/*-----------------------------------------------------------------*/
+/* findAssignToSym : scanning backwards looks for first assig found */
+/*-----------------------------------------------------------------*/
+static iCode *
+findAssignToSym (operand * op, iCode * ic)
+{
+ iCode *dic;
+
+ for (dic = ic->prev; dic; dic = dic->prev) {
+
+ /* if definition by assignment */
+ if (dic->op == '=' &&
+ !POINTER_SET (dic) && IC_RESULT (dic)->key == op->key
+/* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
+ ) {
+
+ /* we are interested only if defined in far space */
+ /* or in stack space in case of + & - */
+
+ /* if assigned to a non-symbol then return
+ true */
+ if (!IS_SYMOP (IC_RIGHT (dic)))
+ break;
+
+ /* if the symbol is in far space then
+ we should not */
+ if (isOperandInFarSpace (IC_RIGHT (dic)))
+ return NULL;
+
+ /* for + & - operations make sure that
+ if it is on the stack it is the same
+ as one of the three operands */
+ if ((ic->op == '+' || ic->op == '-') &&
+ OP_SYMBOL (IC_RIGHT (dic))->onStack) {
+
+ if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key
+ && IC_LEFT (ic)->key !=
+ IC_RIGHT (dic)->key
+ && IC_RIGHT (ic)->key !=
+ IC_RIGHT (dic)->key) return NULL;
+ }
+
+ break;
+
+ }
+
+ /* if we find an usage then we cannot delete it */
+ if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
+ return NULL;
+
+ if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
+ return NULL;
+
+ if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
+ return NULL;
+ }
+
+ /* now make sure that the right side of dic
+ is not defined between ic & dic */
+ if (dic) {
+ iCode *sic = dic->next;
+
+ for (; sic != ic; sic = sic->next)
+ if (IC_RESULT (sic) &&
+ IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
+ return NULL;
+ }
+
+ return dic;
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* packForPush - hueristics to reduce iCode for pushing */
+/*-----------------------------------------------------------------*/
+static void
+packForPush (iCode * ic, eBBlock * ebp)
+{
+ iCode *dic;
+
+ if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
+ return;
+
+ /* must have only definition & one usage */
+ if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
+ bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
+ return;
+
+ /* find the definition */
+ if (!(dic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (OP_DEFS
+ (IC_LEFT (ic))))))
+ return;
+
+ 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);
+ hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+}
+
+/*-----------------------------------------------------------------*/
+/* packRegsForSupport :- reduce some registers for support calls */
+/*-----------------------------------------------------------------*/
+static int
+packRegsForSupport (iCode * ic, eBBlock * ebp)
+{
+ int change = 0;
+ /* for the left & right operand :- look to see if the
+ left was assigned a true symbol in far space in that
+ case replace them */
+ if (IS_ITEMP (IC_LEFT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq) {
+ iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
+ iCode *sic;
+
+ if (!dic)
+ goto right;
+
+ /* found it we need to remove it from the
+ block */
+ for (sic = dic; sic != ic; sic = sic->next)
+ bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
+
+ IC_LEFT (ic)->operand.symOperand =
+ IC_RIGHT (dic)->operand.symOperand;
+ IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+ remiCodeFromeBBlock (ebp, dic);
+ hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+ change++;
+ }
+
+ /* do the same for the right operand */
+ right:
+ if (!change &&
+ IS_ITEMP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq) {
+ iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
+ iCode *sic;
+
+ if (!dic)
+ return change;
+
+ /* if this is a subtraction & the result
+ is a true symbol in far space then don't pack */
+ if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic))) {
+ sym_link *etype =
+ getSpec (operandType (IC_RESULT (dic)));
+ if (IN_FARSPACE (SPEC_OCLS (etype)))
+ return change;
+ }
+ /* found it we need to remove it from the
+ block */
+ for (sic = dic; sic != ic; sic = sic->next)
+ bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
+
+ IC_RIGHT (ic)->operand.symOperand =
+ IC_RIGHT (dic)->operand.symOperand;
+ IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+
+ remiCodeFromeBBlock (ebp, dic);
+ hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+ change++;
+ }
+
+ return change;
+}
+
+/*-----------------------------------------------------------------*/
+/* farSpacePackable - returns the packable icode for far variables */
+/*-----------------------------------------------------------------*/
+static iCode *
+farSpacePackable (iCode * ic)
+{
+ iCode *dic;
+
+ /* go thru till we find a definition for the
+ symbol on the right */
+ for (dic = ic->prev; dic; dic = dic->prev) {
+
+ /* if the definition is a call then no */
+ if ((dic->op == CALL || dic->op == PCALL) &&
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
+ return NULL;
+ }
+
+ /* if shift by unknown amount then not */
+ if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ return NULL;
+
+ /* if pointer get and size > 1 */
+ if (POINTER_GET (dic) &&
+ getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) >
+ 1) return NULL;
+
+ if (POINTER_SET (dic) &&
+ getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE))
+ > 1)
+ return NULL;
+
+ /* if any three is a true symbol in far space */
+ if (IC_RESULT (dic) &&
+ IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ isOperandInFarSpace (IC_RESULT (dic)))
+ return NULL;
+
+ if (IC_RIGHT (dic) &&
+ IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+ isOperandInFarSpace (IC_RIGHT (dic)) &&
+ !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+ return NULL;
+
+ if (IC_LEFT (dic) &&
+ IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+ isOperandInFarSpace (IC_LEFT (dic)) &&
+ !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+ return NULL;
+
+ if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic))) {
+ if ((dic->op == LEFT_OP ||
+ dic->op == RIGHT_OP ||
+ dic->op == '-') &&
+ IS_OP_LITERAL (IC_RIGHT (dic))) return NULL;
+ else
+ return dic;
+ }
+ }
+
+ return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* rematStr - returns the rematerialized string for a remat var */
+/*-----------------------------------------------------------------*/
+static char *
+rematStr (symbol * sym)
+{
+ char *s = buffer;
+ iCode *ic = sym->rematiCode;
+
+ while (1) {
+
+ /* if plus or minus print the right hand side */
+ if (ic->op == '+' || ic->op == '-') {
+ sprintf (s, "0x%04x %c ",
+ (int) operandLitValue (IC_RIGHT (ic)),
+ ic->op);
+ s += strlen (s);
+ ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+ continue;
+ }
+
+ /* we reached the end */
+ sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+ break;
+ }
+
+ return buffer;
+}
+
+/*-----------------------------------------------------------------*/
+/* isSpiltOnStack - returns true if the spil location is on stack */
+/*-----------------------------------------------------------------*/
+static bool
+isSpiltOnStack (symbol * sym)
+{
+ sym_link *etype;
+
+ if (!sym)
+ return FALSE;
+
+ if (!sym->isspilt)
+ return FALSE;
+
+
+ if (!sym->usl.spillLoc)
+ return FALSE;
+
+ etype = getSpec (sym->usl.spillLoc->type);
+ if (IN_STACK (etype))
+ return TRUE;
+
+ return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* spillLRWithPtrReg :- will spil those live ranges which use PTR */
+/*-----------------------------------------------------------------*/
+static void
+spillLRWithPtrReg (symbol * forSym)
+{
+ symbol *lrsym;
+ regs *X, *Z, *X1, *Z1;
+ int k;
+
+ if (!_G.regAssigned || bitVectIsZero (_G.regAssigned))
+ return;
+
+ X = avr_regWithIdx (R26_IDX);
+ X1= avr_regWithIdx (R27_IDX);
+ Z = avr_regWithIdx (R30_IDX);
+ Z1= avr_regWithIdx (R31_IDX);
+
+ /* for all live ranges */
+ for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
+ lrsym = hTabNextItem (liveRanges, &k)) {
+ int j;
+
+ /* if no registers assigned to it or
+ spilt */
+ /* if it does not overlap with this then
+ not need to spill it */
+
+ if (lrsym->isspilt || !lrsym->nRegs ||
+ (lrsym->liveTo < forSym->liveFrom)) continue;
+
+ /* go thru the registers : if it is either
+ r0 or r1 then spil it */
+ for (j = 0; j < lrsym->nRegs; j++)
+ if (lrsym->regs[j] == X || lrsym->regs[j] == Z ||
+ lrsym->regs[j] == X1 || lrsym->regs[j] == Z1) {
+ spillThis (lrsym);
+ break;
+ }
+ }
+
+}
+#endif
+
/*-----------------------------------------------------------------*/
/* allocReg - allocates register of given type */
/*-----------------------------------------------------------------*/
bitVectSetBit (currFunc->regsUsed, i);
return ®sAVR[i];
}
+
/* other wise look for specific type
of register */
- if (regsAVR[i].isFree && regsAVR[i].type == type) {
+ if (regsAVR[i].isFree && (regsAVR[i].type & type)) {
regsAVR[i].isFree = 0;
if (currFunc)
currFunc->regsUsed =
return NULL;
}
+/*-----------------------------------------------------------------*/
+/* allocRegPair - allocates register pair of given */
+/*-----------------------------------------------------------------*/
+static regs *
+allocRegPair (short type)
+{
+ int i;
+
+ for (i = avr_fReg; i < avr_nRegs; i++) {
+
+ /* look for specific type of register pair */
+ if (regsAVR[i].isFree && (regsAVR[i].type & type)
+ && (regsAVR[i].type & REG_PAIR) && regsAVR[i+1].isFree) {
+
+ regsAVR[i].isFree = 0;
+ regsAVR[i+1].isFree = 0;
+ if (currFunc) {
+ currFunc->regsUsed =
+ bitVectSetBit (currFunc->regsUsed, i);
+ currFunc->regsUsed =
+ bitVectSetBit (currFunc->regsUsed, i+1);
+ }
+ return ®sAVR[i];
+ }
+ }
+ return NULL;
+}
+
/*-----------------------------------------------------------------*/
/* avr_regWithIdx - returns pointer to register wit index number */
/*-----------------------------------------------------------------*/
int nfr = 0;
for (i = avr_fReg; i < avr_nRegs; i++)
- if (regsAVR[i].isFree && regsAVR[i].type == type)
+ if (regsAVR[i].isFree && regsAVR[i].type & type)
nfr++;
return nfr;
}
return nFreeRegs (type);
}
-
-/*-----------------------------------------------------------------*/
-/* allDefsOutOfRange - all definitions are out of a range */
-/*-----------------------------------------------------------------*/
-static bool
-allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
-{
- int i;
-
- if (!defs)
- return TRUE;
-
- for (i = 0; i < defs->size; i++) {
- iCode *ic;
-
- if (bitVectBitValue (defs, i) &&
- (ic = hTabItemWithKey (iCodehTab, i)) &&
- (ic->seq >= fseq && ic->seq <= toseq))
-
- return FALSE;
- }
-
- return TRUE;
-}
-
/*-----------------------------------------------------------------*/
/* computeSpillable - given a point find the spillable live ranges */
/*-----------------------------------------------------------------*/
return sym->remat;
}
-/*-----------------------------------------------------------------*/
-/* notUsedInBlock - not used in this block */
-/*-----------------------------------------------------------------*/
-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 */
/*-----------------------------------------------------------------*/
}
- setToNull ((void **) &sset);
+ setToNull ((void *) &sset);
sym->blockSpil = 0;
return sym;
}
return 0;
}
-/*-----------------------------------------------------------------*/
-/* spillLRWithPtrReg :- will spil those live ranges which use PTR */
-/*-----------------------------------------------------------------*/
-static void
-spillLRWithPtrReg (symbol * forSym)
-{
- symbol *lrsym;
- regs *X, *Z, *X1, *Z1;
- int k;
-
- if (!_G.regAssigned || bitVectIsZero (_G.regAssigned))
- return;
-
- X = avr_regWithIdx (R26_IDX);
- X1= avr_regWithIdx (R27_IDX);
- Z = avr_regWithIdx (R30_IDX);
- Z1= avr_regWithIdx (R31_IDX);
-
- /* for all live ranges */
- for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
- lrsym = hTabNextItem (liveRanges, &k)) {
- int j;
-
- /* if no registers assigned to it or
- spilt */
- /* if it does not overlap with this then
- not need to spill it */
-
- if (lrsym->isspilt || !lrsym->nRegs ||
- (lrsym->liveTo < forSym->liveFrom)) continue;
-
- /* go thru the registers : if it is either
- r0 or r1 then spil it */
- for (j = 0; j < lrsym->nRegs; j++)
- if (lrsym->regs[j] == X || lrsym->regs[j] == Z ||
- lrsym->regs[j] == X1 || lrsym->regs[j] == Z1) {
- spillThis (lrsym);
- break;
- }
- }
-
-}
-
/*-----------------------------------------------------------------*/
/* createStackSpil - create a location on the stack to spil */
/*-----------------------------------------------------------------*/
return sym;
}
-/*-----------------------------------------------------------------*/
-/* isSpiltOnStack - returns true if the spil location is on stack */
-/*-----------------------------------------------------------------*/
-static bool
-isSpiltOnStack (symbol * sym)
-{
- sym_link *etype;
-
- if (!sym)
- return FALSE;
-
- if (!sym->isspilt)
- return FALSE;
-
-
- if (!sym->usl.spillLoc)
- return FALSE;
-
- etype = getSpec (sym->usl.spillLoc->type);
- if (IN_STACK (etype))
- return TRUE;
-
- return FALSE;
-}
-
/*-----------------------------------------------------------------*/
/* spillThis - spils a specific operand */
/*-----------------------------------------------------------------*/
/* check if there are any live ranges that not
used in the remainder of the block */
if (!_G.blockSpil &&
- (selectS =
+ !isiCodeInFunctionCall (ic) &&
+ (selectS =
liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) {
sym = leastUsedLR (selectS);
if (sym != forSym) {
tryAgain:
/* try for a ptr type */
- if ((reg = allocReg (REG_PTR)))
+ if ((reg = allocReg (REG_PTR|REG_PAIR)))
return reg;
- /* try for gpr type */
+ /* try for gpr type / pair */
+ if ((reg = allocReg (REG_GPR|REG_PAIR)))
+ return reg;
+
+ /* try for gpr type */
if ((reg = allocReg (REG_GPR)))
return reg;
return NULL;
/* this looks like an infinite loop but
- in really selectSpil will abort */
+ in reality selectSpil will abort */
goto tryAgain;
}
regs *reg;
tryAgain:
- /* try for a ptr type */
+
+ /* try for a scratch non-pair */
if ((reg = allocReg (REG_SCR)))
return reg;
-
- /* try for gpr type */
+
if ((reg = allocReg (REG_GPR)))
return reg;
/* getRegGpr - will try for GPR if not spil */
/*-----------------------------------------------------------------*/
static regs *
-getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
+getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym )
{
regs *reg;
ic->prev->op == IPOP &&
!ic->prev->parmPush &&
!OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
- psym = OP_SYMBOL (IC_LEFT (ic->prev));
+ psym = OP_SYMBOL (IC_LEFT (ic->prev));
if (sym->nRegs) {
int i = 0;
(result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
result->liveTo > ic->seq && /* and will live beyond this */
result->liveTo <= ebp->lSeq && /* does not go beyond this block */
+ result->liveFrom == ic->seq && /* does not start before here */
result->regType == sym->regType && /* same register types */
result->nRegs && /* which needs registers */
!result->isspilt && /* and does not already have them */
!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 < 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);
+ ((nfreeRegsType (result->regType) + sym->nRegs) >= result->nRegs)) {
- _G.regAssigned =
- bitVectSetBit (_G.regAssigned,
- result->key);
+ 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);
+ }
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
}
if (!symHasReg (psym, sym->regs[i]))
freeReg (sym->regs[i]);
}
- else
- freeReg (sym->regs[i]);
+ else freeReg (sym->regs[i]);
}
}
}
{
int count = min (result->nRegs, opsym->nRegs);
int i, j = 0, shared = 0;
-
+
/* if the result has been spilt then cannot share */
if (opsym->isspilt)
- return;
- again:
+ return;
+ again:
shared = 0;
/* first make sure that they actually share */
for (i = 0; i < count; i++) {
}
}
}
- xchgPositions:
+ xchgPositions:
if (shared) {
regs *tmp = result->regs[i];
result->regs[i] = result->regs[j];
result->regs[j] = tmp;
goto again;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* needsPair - heuristic to determine if a pair would be good */
+/*-----------------------------------------------------------------*/
+static int needsPair (iCode *ic)
+{
+ symbol *sym = OP_SYMBOL(IC_RESULT(ic));
+ bitVect *uses_defs =
+ bitVectUnion(OP_USES (IC_RESULT(ic)),OP_DEFS(IC_RESULT(ic)));
+
+ /* if size is less than 2 then NO */
+ if (sym->nRegs < 2) return 0;
+ /* if type Pointer then YES */
+ if (IS_PTR(sym->type)) return 1;
+
+ /* go thru the usages of this operand if used with
+ a constant then yes */
+ while (!bitVectIsZero(uses_defs)) {
+ int ikey = bitVectFirstBit(uses_defs);
+ iCode *uic = hTabItemWithKey(iCodehTab,ikey);
+ sym_link *otype = NULL;
+ bitVectUnSetBit(uses_defs,ikey);
+ if (!uic) continue;
+ otype = (IC_RIGHT(uic) ? operandType(IC_RIGHT(uic)) : NULL);
+ if (otype && IS_LITERAL(otype)) return 1;
}
+ return 0;
}
/*-----------------------------------------------------------------*/
symbol *sym = OP_SYMBOL (IC_RESULT (ic));
bitVect *spillable;
int willCS;
- int j;
+ int j=0;
+
+ /* Make sure any spill location is definately allocated */
+ if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+ !sym->usl.spillLoc->allocreq) {
+ sym->usl.spillLoc->allocreq++;
+ }
/* if it does not need or is spilt
or is already assigned to registers
willCauseSpill (sym->nRegs,
sym->regType);
spillable = computeSpillable (ic);
- if (sym->remat ||
- (willCS && bitVectIsZero (spillable))) {
-
+ if (sym->remat || (willCS && bitVectIsZero (spillable))) {
spillThis (sym);
continue;
+ }
+ /* If the live range preceeds the point of definition
+ then ideally we must take into account registers that
+ have been allocated after sym->liveFrom but freed
+ before ic->seq. This is complicated, so spill this
+ symbol instead and let fillGaps handle the allocation. */
+ if (sym->liveFrom < ic->seq)
+ {
+ spillThis (sym);
+ continue;
}
/* if it has a spillocation & is used less than
all other live ranges then spill this */
- if (willCS && sym->usl.spillLoc) {
-
- symbol *leastUsed =
- leastUsedLR (liveRangesWith
- (spillable,
- allLRs,
- ebbs[i],
- ic));
- if (leastUsed &&
- leastUsed->used > sym->used) {
- spillThis (sym);
- continue;
+ if (willCS) {
+ if (sym->usl.spillLoc) {
+ symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
+ allLRs, ebbs[i], ic));
+ if (leastUsed && leastUsed->used > sym->used) {
+ spillThis (sym);
+ continue;
+ }
+ } else {
+ /* if none of the liveRanges have a spillLocation then better
+ to spill this one than anything else already assigned to registers */
+ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
+ spillThis (sym);
+ continue;
+ }
}
}
/* we assign registers to it */
_G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
-
- for (j = 0; j < sym->nRegs; j++) {
+ if (needsPair(ic)) {
+ short regtype ;
+ regs *preg;
+ if (sym->regType == REG_PTR) regtype = REG_PTR;
+ else if (sym->regType == REG_SCR) regtype = REG_SCR;
+ else regtype = REG_GPR;
+ preg = allocRegPair(regtype);
+ if (preg) {
+ sym->regs[j++] = preg;
+ sym->regs[j++] = ®sAVR[preg->rIdx+1];
+ }
+ }
+ for (; 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);
-
/* if the allocation falied which means
this was spilt then break */
- if (!sym->regs[j])
- break;
+ if (!sym->regs[j]) break;
}
+
/* if it shares registers with operands make sure
that they are in the same position */
if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
OP_SYMBOL (IC_LEFT (ic))->nRegs
&& ic->op != '=')
- positionRegs (OP_SYMBOL
- (IC_RESULT (ic)),
- OP_SYMBOL (IC_LEFT
- (ic)),
- ic->lineno);
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ 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)
- positionRegs (OP_SYMBOL
- (IC_RESULT (ic)),
- OP_SYMBOL (IC_RIGHT
- (ic)),
- ic->lineno);
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
}
}
/* for all the registers allocated to it */
for (k = 0; k < sym->nRegs; k++) {
if (sym->regs[k]) {
- ic->rMask = bitVectSetBit (ic-> rMask, sym->regs[k]->rIdx);
+ int rIdx = sym->regs[k]->rIdx;
+ ic->rMask = bitVectSetBit (ic-> rMask,rIdx);
/* special case for X & Z registers */
- if (k == R26_IDX || k == R27_IDX)
+ if (rIdx == R26_IDX || rIdx == R27_IDX)
ic->rMask = bitVectSetBit (ic->rMask, X_IDX);
- if (k == R30_IDX || k == R31_IDX)
+ if (rIdx == R30_IDX || rIdx == R31_IDX)
ic->rMask = bitVectSetBit (ic->rMask, Z_IDX);
}
- }
- }
- }
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* rematStr - returns the rematerialized string for a remat var */
-/*-----------------------------------------------------------------*/
-static char *
-rematStr (symbol * sym)
-{
- char *s = buffer;
- iCode *ic = sym->rematiCode;
-
- while (1) {
-
- /* if plus or minus print the right hand side */
- if (ic->op == '+' || ic->op == '-') {
- sprintf (s, "0x%04x %c ",
- (int) operandLitValue (IC_RIGHT (ic)),
- ic->op);
- s += strlen (s);
- ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
- continue;
+ }
+ }
}
-
- /* we reached the end */
- sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
- break;
}
-
- return buffer;
}
+
/*-----------------------------------------------------------------*/
/* regTypeNum - computes the type & number of registers required */
/*-----------------------------------------------------------------*/
in "data" space */
if (bitVectnBitsOn (sym->defs) == 1 &&
- (ic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (sym->
- defs)))
+ (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym-> defs)))
&& POINTER_GET (ic) && !IS_BITVAR (sym->etype)) {
/* if in data space or idata space then try to
return 0;
}
-/*-----------------------------------------------------------------*/
-/* farSpacePackable - returns the packable icode for far variables */
-/*-----------------------------------------------------------------*/
-static iCode *
-farSpacePackable (iCode * ic)
-{
- iCode *dic;
-
- /* go thru till we find a definition for the
- symbol on the right */
- for (dic = ic->prev; dic; dic = dic->prev) {
-
- /* if the definition is a call then no */
- if ((dic->op == CALL || dic->op == PCALL) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
- return NULL;
- }
-
- /* if shift by unknown amount then not */
- if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- return NULL;
-
- /* if pointer get and size > 1 */
- if (POINTER_GET (dic) &&
- getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) >
- 1) return NULL;
-
- if (POINTER_SET (dic) &&
- getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE))
- > 1)
- return NULL;
-
- /* if any three is a true symbol in far space */
- if (IC_RESULT (dic) &&
- IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- isOperandInFarSpace (IC_RESULT (dic)))
- return NULL;
-
- if (IC_RIGHT (dic) &&
- IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
- isOperandInFarSpace (IC_RIGHT (dic)) &&
- !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
- return NULL;
-
- if (IC_LEFT (dic) &&
- IS_TRUE_SYMOP (IC_LEFT (dic)) &&
- isOperandInFarSpace (IC_LEFT (dic)) &&
- !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
- return NULL;
-
- if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic))) {
- if ((dic->op == LEFT_OP ||
- dic->op == RIGHT_OP ||
- dic->op == '-') &&
- IS_OP_LITERAL (IC_RIGHT (dic))) return NULL;
- else
- return dic;
- }
- }
-
- return NULL;
-}
-
/*-----------------------------------------------------------------*/
/* packRegsForAssign - register reduction for assignment */
/*-----------------------------------------------------------------*/
}
-/*-----------------------------------------------------------------*/
-/* findAssignToSym : scanning backwards looks for first assig found */
-/*-----------------------------------------------------------------*/
-static iCode *
-findAssignToSym (operand * op, iCode * ic)
-{
- iCode *dic;
-
- for (dic = ic->prev; dic; dic = dic->prev) {
-
- /* if definition by assignment */
- if (dic->op == '=' &&
- !POINTER_SET (dic) && IC_RESULT (dic)->key == op->key
-/* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
- ) {
-
- /* we are interested only if defined in far space */
- /* or in stack space in case of + & - */
-
- /* if assigned to a non-symbol then return
- true */
- if (!IS_SYMOP (IC_RIGHT (dic)))
- break;
-
- /* if the symbol is in far space then
- we should not */
- if (isOperandInFarSpace (IC_RIGHT (dic)))
- return NULL;
-
- /* for + & - operations make sure that
- if it is on the stack it is the same
- as one of the three operands */
- if ((ic->op == '+' || ic->op == '-') &&
- OP_SYMBOL (IC_RIGHT (dic))->onStack) {
-
- if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key
- && IC_LEFT (ic)->key !=
- IC_RIGHT (dic)->key
- && IC_RIGHT (ic)->key !=
- IC_RIGHT (dic)->key) return NULL;
- }
-
- break;
-
- }
-
- /* if we find an usage then we cannot delete it */
- if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
- return NULL;
-
- if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
- return NULL;
-
- if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
- return NULL;
- }
-
- /* now make sure that the right side of dic
- is not defined between ic & dic */
- if (dic) {
- iCode *sic = dic->next;
-
- for (; sic != ic; sic = sic->next)
- if (IC_RESULT (sic) &&
- IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
- return NULL;
- }
-
- return dic;
-
-
-}
-
-/*-----------------------------------------------------------------*/
-/* packRegsForSupport :- reduce some registers for support calls */
-/*-----------------------------------------------------------------*/
-static int
-packRegsForSupport (iCode * ic, eBBlock * ebp)
-{
- int change = 0;
- /* for the left & right operand :- look to see if the
- left was assigned a true symbol in far space in that
- case replace them */
- if (IS_ITEMP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq) {
- iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
- iCode *sic;
-
- if (!dic)
- goto right;
-
- /* found it we need to remove it from the
- block */
- for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
-
- IC_LEFT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
- IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
- remiCodeFromeBBlock (ebp, dic);
- hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
- change++;
- }
-
- /* do the same for the right operand */
- right:
- if (!change &&
- IS_ITEMP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq) {
- iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
- iCode *sic;
-
- if (!dic)
- return change;
-
- /* if this is a subtraction & the result
- is a true symbol in far space then don't pack */
- if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic))) {
- sym_link *etype =
- getSpec (operandType (IC_RESULT (dic)));
- if (IN_FARSPACE (SPEC_OCLS (etype)))
- return change;
- }
- /* found it we need to remove it from the
- block */
- for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
-
- IC_RIGHT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
- IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
-
- remiCodeFromeBBlock (ebp, dic);
- hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
- change++;
- }
-
- return change;
-}
-
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
/*-----------------------------------------------------------------*/
/* packRegsForOneuse : - will reduce some registers for single Use */
/* now check if it is the return from
a function call */
if (dic->op == CALL || dic->op == PCALL) {
- if (ic->op != SEND && ic->op != RETURN) {
+ if (ic->op != SEND && ic->op != RETURN &&
+ !POINTER_SET(ic) && !POINTER_GET(ic)) {
OP_SYMBOL (op)->ruonly = 1;
return dic;
}
return FALSE;
}
-/*-----------------------------------------------------------------*/
-/* packForPush - hueristics to reduce iCode for pushing */
-/*-----------------------------------------------------------------*/
-static void
-packForPush (iCode * ic, eBBlock * ebp)
-{
- iCode *dic;
-
- if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
- return;
-
- /* must have only definition & one usage */
- if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
- bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
- return;
-
- /* find the definition */
- if (!(dic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_DEFS
- (IC_LEFT (ic))))))
- return;
-
- 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);
- hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
-}
-
/*-----------------------------------------------------------------*/
/* packRegisters - does some transformations to reduce register */
/* pressure */
if (POINTER_SET (ic))
OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
- if (POINTER_GET (ic))
+ if (POINTER_GET (ic)) {
OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+ if (OP_SYMBOL (IC_LEFT(ic))->remat)
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ }
/* if the condition of an if instruction
is defined in the previous instruction then
/* if the type from and type to are the same
then if this is the only use then packit */
- if (checkType (operandType (IC_RIGHT (ic)),
+ if (compareType (operandType (IC_RIGHT (ic)),
operandType (IC_LEFT (ic))) ==
1) {
iCode *dic =
regsAVR[R30_IDX].isFree = regsAVR[R31_IDX].isFree = 1;
if (!avr_ptrRegReq) {
- regsAVR[R26_IDX].type =
- regsAVR[R27_IDX].type =
- regsAVR[R30_IDX].type =
- regsAVR[R31_IDX].type = REG_GPR;
+ regsAVR[R26_IDX].type = (regsAVR[R26_IDX].type & ~REG_MASK) | REG_GPR;
+ regsAVR[R27_IDX].type = (regsAVR[R27_IDX].type & ~REG_MASK) | REG_GPR;
+ regsAVR[R28_IDX].type = (regsAVR[R28_IDX].type & ~REG_MASK) | REG_GPR;
+ regsAVR[R29_IDX].type = (regsAVR[R29_IDX].type & ~REG_MASK) | REG_GPR;
}
else {
- regsAVR[R26_IDX].type =
- regsAVR[R27_IDX].type =
- regsAVR[R30_IDX].type =
- regsAVR[R31_IDX].type = REG_PTR;
+ regsAVR[R26_IDX].type = (regsAVR[R26_IDX].type & ~REG_MASK) | REG_PTR;
+ regsAVR[R27_IDX].type = (regsAVR[R27_IDX].type & ~REG_MASK) | REG_PTR;
+ regsAVR[R30_IDX].type = (regsAVR[R30_IDX].type & ~REG_MASK) | REG_PTR;
+ regsAVR[R31_IDX].type = (regsAVR[R31_IDX].type & ~REG_MASK) | REG_PTR;
}
/* registers 0-1 / 24-25 used as scratch */
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);
+ /* mark the parameter regs as SCRACH */
+ for (i = R16_IDX; i <= R23_IDX; i++) {
+ regsAVR[i].type = (regsAVR[i].type & ~REG_MASK) | REG_SCR;
+ regsAVR[i].isFree = 1;
}
- else {
-
- /* otherwise mark them as free scratch */
- for (i = R16_IDX; i <= R23_IDX; i++) {
- regsAVR[i].type = REG_SCR;
- regsAVR[i].isFree = 1;
- }
+ if (!IFFUNC_HASFCALL(currFunc->type)) {
+ preAssignParms (ebbs[0]->sch);
}
-
/* Y - is not allocated (it is the stack frame) */
regsAVR[R28_IDX].isFree = regsAVR[R28_IDX].isFree = 0;
}
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-avr_assignRegisters (eBBlock ** ebbs, int count)
+avr_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
for (i = 0; i < count; i++)
packRegisters (ebbs[i]);
+ /* liveranges probably changed by register packing
+ so we compute them again */
+ recomputeLiveRanges (ebbs, count);
+
if (options.dump_pack)
- dumpEbbsToFileExt (".dumppack", ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
redoStackOffsets ();
if (options.dump_rassgn)
- dumpEbbsToFileExt (".dumprassgn", ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
/* now get back the chain */
ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
/* free up any _G.stackSpil locations allocated */
applyToSet (_G.stackSpil, deallocStackSpil);
_G.slocNum = 0;
- setToNull ((void **) &_G.stackSpil);
- setToNull ((void **) &_G.spiltSet);
+ setToNull ((void *) &_G.stackSpil);
+ setToNull ((void *) &_G.spiltSet);
/* mark all registers as free */
return;