X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Favr%2Fralloc.c;h=8388d84b58d95ee195c9ae7b853811bea386d81b;hb=a12dad7dfe654ada025ae6752fca404d58edc2fa;hp=8fe1cdae3cc8d32734c4f96d06e31639749477f2;hpb=b4d69dfd516f175255aa87b18b59dcf309d98b46;p=fw%2Fsdcc diff --git a/src/avr/ralloc.c b/src/avr/ralloc.c index 8fe1cdae..8388d84b 100644 --- a/src/avr/ralloc.c +++ b/src/avr/ralloc.c @@ -39,99 +39,458 @@ extern void genAVRCode (iCode *); /* 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; +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 avr_ptrRegReq; /* pointer register required */ /* AVR registers */ -regs regsAVR[] = -{ - {REG_GPR, R0_IDX, REG_GPR, "r0", "r0", "", 0, 0, 0}, /* used as scratch */ - {REG_GPR, R1_IDX, REG_GPR, "r1", "r1", "", 0, 0, 0}, /* used as 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_PTR, X_IDX, REG_PTR, "X", "X", "", 0, 1, 0}, - {REG_PTR, Z_IDX, REG_PTR, "Z", "Z", "", 0, 1, 0}, +regs regsAVR[] = { + {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}, }; int avr_nRegs = 32; int avr_fReg = 0; /* first allocatable register */ 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 */ /*-----------------------------------------------------------------*/ static regs * allocReg (short type) { - int i; - - for (i = avr_fReg; i < avr_nRegs; i++) - { - - /* if type is given as 0 then any - free register will do */ - if (!type && - regsAVR[i].isFree) - { - regsAVR[i].isFree = 0; - if (currFunc) - currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i); - return ®sAVR[i]; + int i; + + for (i = avr_fReg; i < avr_nRegs; i++) { + + /* if type is given as 0 then any + free register will do */ + if (!type && regsAVR[i].isFree) { + regsAVR[i].isFree = 0; + if (currFunc) + currFunc->regsUsed = + bitVectSetBit (currFunc->regsUsed, i); + return ®sAVR[i]; + } + + /* other wise look for specific type + of register */ + if (regsAVR[i].isFree && (regsAVR[i].type & type)) { + regsAVR[i].isFree = 0; + if (currFunc) + currFunc->regsUsed = + bitVectSetBit (currFunc->regsUsed, i); + return ®sAVR[i]; + } } - /* other wise look for specific type - of register */ - if (regsAVR[i].isFree && - regsAVR[i].type == type) - { - regsAVR[i].isFree = 0; - if (currFunc) - currFunc->regsUsed = - bitVectSetBit (currFunc->regsUsed, i); - return ®sAVR[i]; + 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; + return NULL; } /*-----------------------------------------------------------------*/ @@ -140,15 +499,14 @@ allocReg (short type) regs * avr_regWithIdx (int idx) { - int i; + int i; - for (i = 0; i < avr_nRegs; i++) - if (regsAVR[i].rIdx == idx) - return ®sAVR[i]; + for (i = 0; i < avr_nRegs; i++) + if (regsAVR[i].rIdx == idx) + return ®sAVR[i]; - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "regWithIdx not found"); - exit (1); + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "regWithIdx not found"); + exit (1); } /*-----------------------------------------------------------------*/ @@ -157,7 +515,7 @@ avr_regWithIdx (int idx) static void freeReg (regs * reg) { - reg->isFree = 1; + reg->isFree = 1; } @@ -167,13 +525,13 @@ freeReg (regs * reg) static int nFreeRegs (int type) { - int i; - int nfr = 0; + int i; + int nfr = 0; - for (i = avr_fReg; i < avr_nRegs; i++) - if (regsAVR[i].isFree && regsAVR[i].type == type) - nfr++; - return nfr; + for (i = avr_fReg; i < avr_nRegs; i++) + if (regsAVR[i].isFree && regsAVR[i].type & type) + nfr++; + return nfr; } /*-----------------------------------------------------------------*/ @@ -182,14 +540,13 @@ nFreeRegs (int type) static int nfreeRegsType (int type) { - int nfr; - if (type == REG_PTR) - { - if ((nfr = nFreeRegs (type)) == 0) - return nFreeRegs (REG_GPR); - } - - return nFreeRegs (type); + int nfr; + if (type == REG_PTR) { + if ((nfr = nFreeRegs (type)) == 0) + return nFreeRegs (REG_GPR); + } + + return nFreeRegs (type); } @@ -199,23 +556,22 @@ nfreeRegsType (int type) static bool allDefsOutOfRange (bitVect * defs, int fseq, int toseq) { - int i; + int i; - if (!defs) - return TRUE; + if (!defs) + return TRUE; - for (i = 0; i < defs->size; i++) - { - iCode *ic; + for (i = 0; i < defs->size; i++) { + iCode *ic; - if (bitVectBitValue (defs, i) && - (ic = hTabItemWithKey (iCodehTab, i)) && - (ic->seq >= fseq && ic->seq <= toseq)) + if (bitVectBitValue (defs, i) && + (ic = hTabItemWithKey (iCodehTab, i)) && + (ic->seq >= fseq && ic->seq <= toseq)) - return FALSE; - } + return FALSE; + } - return TRUE; + return TRUE; } /*-----------------------------------------------------------------*/ @@ -224,23 +580,21 @@ allDefsOutOfRange (bitVect * defs, int fseq, int toseq) static bitVect * computeSpillable (iCode * ic) { - bitVect *spillable; - - /* spillable live ranges are those that are live at this - point . the following categories need to be subtracted - from this set. - a) - those that are already spilt - b) - if being used by this one - c) - defined by this one */ - - spillable = bitVectCopy (ic->rlive); - spillable = - bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */ - spillable = - bitVectCplAnd (spillable, ic->uses); /* used in this one */ - bitVectUnSetBit (spillable, ic->defKey); - spillable = bitVectIntersect (spillable, _G.regAssigned); - return spillable; + bitVect *spillable; + + /* spillable live ranges are those that are live at this + point . the following categories need to be subtracted + from this set. + a) - those that are already spilt + b) - if being used by this one + c) - defined by this one */ + + spillable = bitVectCopy (ic->rlive); + spillable = bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */ + spillable = bitVectCplAnd (spillable, ic->uses); /* used in this one */ + bitVectUnSetBit (spillable, ic->defKey); + spillable = bitVectIntersect (spillable, _G.regAssigned); + return spillable; } @@ -250,7 +604,7 @@ computeSpillable (iCode * ic) static int noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) { - return (sym->usl.spillLoc ? 0 : 1); + return (sym->usl.spillLoc ? 0 : 1); } /*-----------------------------------------------------------------*/ @@ -259,7 +613,7 @@ noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) static int hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) { - return (sym->usl.spillLoc ? 1 : 0); + return (sym->usl.spillLoc ? 1 : 0); } /*-----------------------------------------------------------------*/ @@ -269,7 +623,7 @@ hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) static int hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic) { - return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0); + return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0); } /*-----------------------------------------------------------------*/ @@ -278,7 +632,7 @@ hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic) static int rematable (symbol * sym, eBBlock * ebp, iCode * ic) { - return sym->remat; + return sym->remat; } /*-----------------------------------------------------------------*/ @@ -287,8 +641,8 @@ rematable (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)); + return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) && + allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq)); } /*-----------------------------------------------------------------*/ @@ -297,8 +651,8 @@ notUsedInBlock (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)); + return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) && + allDefsOutOfRange (sym->defs, ic->seq, ebp->lSeq)); } /*-----------------------------------------------------------------*/ @@ -307,7 +661,7 @@ notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic) static int allLRs (symbol * sym, eBBlock * ebp, iCode * ic) { - return 1; + return 1; } /*-----------------------------------------------------------------*/ @@ -318,32 +672,31 @@ liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *), eBBlock * ebp, iCode * ic) { - set *rset = NULL; - int i; - - if (!lrs || !lrs->size) - return NULL; - - for (i = 1; i < lrs->size; i++) - { - symbol *sym; - if (!bitVectBitValue (lrs, i)) - continue; - - /* if we don't find it in the live range - hash table we are in serious trouble */ - if (!(sym = hTabItemWithKey (liveRanges, i))) - { - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "liveRangesWith could not find liveRange"); - exit (1); - } + set *rset = NULL; + int i; - if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key)) - addSetHead (&rset, sym); - } + if (!lrs || !lrs->size) + return NULL; + + for (i = 1; i < lrs->size; i++) { + symbol *sym; + if (!bitVectBitValue (lrs, i)) + continue; + + /* if we don't find it in the live range + hash table we are in serious trouble */ + if (!(sym = hTabItemWithKey (liveRanges, i))) { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "liveRangesWith could not find liveRange"); + exit (1); + } - return rset; + if (func (sym, ebp, ic) + && bitVectBitValue (_G.regAssigned, + sym->key)) addSetHead (&rset, sym); + } + + return rset; } @@ -353,31 +706,30 @@ liveRangesWith (bitVect * lrs, static symbol * leastUsedLR (set * sset) { - symbol *sym = NULL, *lsym = NULL; + symbol *sym = NULL, *lsym = NULL; - sym = lsym = setFirstItem (sset); + sym = lsym = setFirstItem (sset); - if (!lsym) - return NULL; + if (!lsym) + return NULL; - for (; lsym; lsym = setNextItem (sset)) - { + for (; lsym; lsym = setNextItem (sset)) { - /* if usage is the same then prefer - the spill the smaller of the two */ - if (lsym->used == sym->used) - if (getSize (lsym->type) < getSize (sym->type)) - sym = lsym; + /* if usage is the same then prefer + the spill the smaller of the two */ + if (lsym->used == sym->used) + if (getSize (lsym->type) < getSize (sym->type)) + sym = lsym; - /* if less usage */ - if (lsym->used < sym->used) - sym = lsym; + /* if less usage */ + if (lsym->used < sym->used) + sym = lsym; - } + } - setToNull ((void **) &sset); - sym->blockSpil = 0; - return sym; + setToNull ((void **) &sset); + sym->blockSpil = 0; + return sym; } /*-----------------------------------------------------------------*/ @@ -386,18 +738,17 @@ leastUsedLR (set * sset) static int noOverLap (set * itmpStack, symbol * fsym) { - symbol *sym; + symbol *sym; - for (sym = setFirstItem (itmpStack); sym; - sym = setNextItem (itmpStack)) - { - if (sym->liveTo > fsym->liveFrom) - return 0; + for (sym = setFirstItem (itmpStack); sym; + sym = setNextItem (itmpStack)) { + if (sym->liveTo > fsym->liveFrom) + return 0; - } + } - return 1; + return 1; } /*-----------------------------------------------------------------*/ @@ -406,71 +757,26 @@ noOverLap (set * itmpStack, symbol * fsym) static DEFSETFUNC (isFree) { - symbol *sym = item; - V_ARG (symbol **, sloc); - V_ARG (symbol *, fsym); - - /* if already found */ - if (*sloc) - return 0; - - /* if it is free && and the itmp assigned to - this does not have any overlapping live ranges - with the one currently being assigned and - the size can be accomodated */ - if (sym->isFree && - noOverLap (sym->usl.itmpStack, fsym) && - getSize (sym->type) >= getSize (fsym->type)) - { - *sloc = sym; - return 1; - } - - return 0; -} - -/*-----------------------------------------------------------------*/ -/* spillLRWithPtrReg :- will spil those live ranges which use PTR */ -/*-----------------------------------------------------------------*/ -static void -spillLRWithPtrReg (symbol * forSym) -{ - symbol *lrsym; - regs *X, *Z; - int k; - - if (!_G.regAssigned || - bitVectIsZero (_G.regAssigned)) - return; - - X = avr_regWithIdx (X_IDX); - Z = avr_regWithIdx (Z_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) - { - spillThis (lrsym); - break; - } - } + symbol *sym = item; + V_ARG (symbol **, sloc); + V_ARG (symbol *, fsym); + + /* if already found */ + if (*sloc) + return 0; + + /* if it is free && and the itmp assigned to + this does not have any overlapping live ranges + with the one currently being assigned and + the size can be accomodated */ + if (sym->isFree && + noOverLap (sym->usl.itmpStack, fsym) && + getSize (sym->type) >= getSize (fsym->type)) { + *sloc = sym; + return 1; + } + return 0; } /*-----------------------------------------------------------------*/ @@ -479,109 +785,83 @@ spillLRWithPtrReg (symbol * forSym) 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 (_G.stackSpil, isFree, &sloc, sym)) - { - /* found a free one : just update & return */ - sym->usl.spillLoc = sloc; - sym->stackSpil = 1; - sloc->isFree = 0; - addSetHead (&sloc->usl.itmpStack, sym); - return sym; - } - - /* could not then have to create one , this is the hard part - we need to allocate this on the stack : this is really a - hack!! but cannot think of anything better at this time */ - - 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_EXTR (sloc->etype) = 0; - - /* we don't allow it to be allocated` - onto the external stack since : so we - 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; - options.model = options.useXstack = 0; - - allocLocal (sloc); - - options.useXstack = useXstack; - options.model = model; - options.noOverlay = noOverlay; - options.stackAuto = stackAuto; - 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); - _G.stackExtend += getSize (sloc->type); - } - else - _G.dataExtend += getSize (sloc->type); - - /* add it to the _G.stackSpil set */ - addSetHead (&_G.stackSpil, sloc); - sym->usl.spillLoc = sloc; - sym->stackSpil = 1; - - /* add it to the set of itempStack set - of the spill location */ - addSetHead (&sloc->usl.itmpStack, sym); - 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; - + 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 (_G.stackSpil, isFree, &sloc, sym)) { + /* found a free one : just update & return */ + sym->usl.spillLoc = sloc; + sym->stackSpil = 1; + sloc->isFree = 0; + addSetHead (&sloc->usl.itmpStack, sym); + return sym; + } - if (!sym->usl.spillLoc) - return FALSE; + /* could not then have to create one , this is the hard part + we need to allocate this on the stack : this is really a + hack!! but cannot think of anything better at this time */ - etype = getSpec (sym->usl.spillLoc->type); - if (IN_STACK (etype)) - return TRUE; + if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= + sizeof (slocBuffer)) { + fprintf (stderr, + "***Internal error: slocBuffer overflowed: %s:%d\n", + __FILE__, __LINE__); + exit (1); + } - return FALSE; + 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_EXTR (sloc->etype) = 0; + + /* we don't allow it to be allocated` + onto the external stack since : so we + 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; + options.model = options.useXstack = 0; + + allocLocal (sloc); + + options.useXstack = useXstack; + options.model = model; + options.noOverlay = noOverlay; + options.stackAuto = stackAuto; + 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); + _G.stackExtend += getSize (sloc->type); + } + else + _G.dataExtend += getSize (sloc->type); + + /* add it to the _G.stackSpil set */ + addSetHead (&_G.stackSpil, sloc); + sym->usl.spillLoc = sloc; + sym->stackSpil = 1; + + /* add it to the set of itempStack set + of the spill location */ + addSetHead (&sloc->usl.itmpStack, sym); + return sym; } /*-----------------------------------------------------------------*/ @@ -590,31 +870,30 @@ isSpiltOnStack (symbol * sym) static void spillThis (symbol * sym) { - int i; - /* if this is rematerializable or has a spillLocation - we are okay, else we need to create a spillLocation - for it */ - if (!(sym->remat || sym->usl.spillLoc)) - createStackSpil (sym); + int i; + /* if this is rematerializable or has a spillLocation + we are okay, else we need to create a spillLocation + for it */ + if (!(sym->remat || sym->usl.spillLoc)) + createStackSpil (sym); - /* mark it has spilt & put it in the spilt set */ - sym->isspilt = 1; - _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key); + /* mark it has spilt & put it in the spilt set */ + sym->isspilt = 1; + _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key); - bitVectUnSetBit (_G.regAssigned, sym->key); + bitVectUnSetBit (_G.regAssigned, sym->key); - for (i = 0; i < sym->nRegs; i++) + for (i = 0; i < sym->nRegs; i++) - if (sym->regs[i]) - { - freeReg (sym->regs[i]); - sym->regs[i] = NULL; - } + if (sym->regs[i]) { + freeReg (sym->regs[i]); + sym->regs[i] = NULL; + } - if (sym->usl.spillLoc && !sym->remat) - sym->usl.spillLoc->allocreq = 1; - return; + if (sym->usl.spillLoc && !sym->remat) + sym->usl.spillLoc->allocreq = 1; + return; } /*-----------------------------------------------------------------*/ @@ -623,93 +902,85 @@ spillThis (symbol * sym) static symbol * selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) { - bitVect *lrcs = NULL; - set *selectS; - symbol *sym; - - /* get the spillable live ranges */ - lrcs = computeSpillable (ic); - - /* get all live ranges that are rematerizable */ - if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic))) - { - - /* return the least used of these */ - return leastUsedLR (selectS); - } - - /* 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 (!_G.blockSpil && - (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic))) - { - sym = leastUsedLR (selectS); - /* if this is not rematerializable */ - if (!sym->remat) - { - _G.blockSpil++; - sym->blockSpil = 1; - } - return sym; + bitVect *lrcs = NULL; + set *selectS; + symbol *sym; + + /* get the spillable live ranges */ + lrcs = computeSpillable (ic); + + /* get all live ranges that are rematerizable */ + if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic))) { + + /* return the least used of these */ + return leastUsedLR (selectS); } - /* check if there are any live ranges that not - used in the remainder of the block */ - if (!_G.blockSpil && - (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) - { - sym = leastUsedLR (selectS); - if (sym != forSym) - { - if (!sym->remat) - { - sym->remainSpil = 1; - _G.blockSpil++; + /* 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 (!_G.blockSpil && + (selectS = + liveRangesWith (lrcs, notUsedInBlock, ebp, ic))) { + sym = leastUsedLR (selectS); + /* if this is not rematerializable */ + if (!sym->remat) { + _G.blockSpil++; + sym->blockSpil = 1; + } + return sym; } - return sym; - } + + /* check if there are any live ranges that not + used in the remainder of the block */ + if (!_G.blockSpil && + (selectS = + liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) { + sym = leastUsedLR (selectS); + if (sym != forSym) { + if (!sym->remat) { + sym->remainSpil = 1; + _G.blockSpil++; + } + return sym; + } + } + } + + /* find live ranges with spillocation && not used as pointers */ + if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic))) { + + sym = leastUsedLR (selectS); + /* mark this as allocation required */ + sym->usl.spillLoc->allocreq = 1; + return sym; } - } - - /* find live ranges with spillocation && not used as pointers */ - if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic))) - { - - sym = leastUsedLR (selectS); - /* mark this as allocation required */ - sym->usl.spillLoc->allocreq = 1; - return sym; - } - - /* find live ranges with spillocation */ - if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic))) - { - - sym = leastUsedLR (selectS); - sym->usl.spillLoc->allocreq = 1; - return sym; - } - - /* couldn't find then we need to create a spil - location on the stack , for which one? the least - used ofcourse */ - if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic))) - { - - /* return a created spil location */ - sym = createStackSpil (leastUsedLR (selectS)); - sym->usl.spillLoc->allocreq = 1; - return sym; - } - - /* this is an extreme situation we will spill - this one : happens very rarely but it does happen */ - spillThis (forSym); - return forSym; + + /* find live ranges with spillocation */ + if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic))) { + + sym = leastUsedLR (selectS); + sym->usl.spillLoc->allocreq = 1; + return sym; + } + + /* couldn't find then we need to create a spil + location on the stack , for which one? the least + used ofcourse */ + if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic))) { + + /* return a created spil location */ + sym = createStackSpil (leastUsedLR (selectS)); + sym->usl.spillLoc->allocreq = 1; + return sym; + } + + /* this is an extreme situation we will spill + this one : happens very rarely but it does happen */ + spillThis (forSym); + return forSym; } @@ -719,57 +990,55 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) static bool spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) { - symbol *ssym; - int i; - - /* get something we can spil */ - ssym = selectSpil (ic, ebp, forSym); - - /* mark it as spilt */ - ssym->isspilt = 1; - _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key); - - /* mark it as not register assigned & - take it away from the set */ - bitVectUnSetBit (_G.regAssigned, ssym->key); - - /* mark the registers as free */ - for (i = 0; i < ssym->nRegs; i++) - if (ssym->regs[i]) - freeReg (ssym->regs[i]); - - /* if this was a block level spil then insert push & pop - at the start & end of block respectively */ - if (ssym->blockSpil) - { - iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL); - /* add push to the start of the block */ - addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ? - ebp->sch->next : ebp->sch)); - nic = newiCode (IPOP, operandFromSymbol (ssym), NULL); - /* add pop to the end of the block */ - addiCodeToeBBlock (ebp, nic, NULL); - } - - /* if spilt because not used in the remainder of the - block then add a push before this instruction and - a pop at the end of the block */ - if (ssym->remainSpil) - { - - iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL); - /* add push just before this instruction */ - addiCodeToeBBlock (ebp, nic, ic); - - nic = newiCode (IPOP, operandFromSymbol (ssym), NULL); - /* add pop to the end of the block */ - addiCodeToeBBlock (ebp, nic, NULL); - } - - if (ssym == forSym) - return FALSE; - else - return TRUE; + symbol *ssym; + int i; + + /* get something we can spil */ + ssym = selectSpil (ic, ebp, forSym); + + /* mark it as spilt */ + ssym->isspilt = 1; + _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key); + + /* mark it as not register assigned & + take it away from the set */ + bitVectUnSetBit (_G.regAssigned, ssym->key); + + /* mark the registers as free */ + for (i = 0; i < ssym->nRegs; i++) + if (ssym->regs[i]) + freeReg (ssym->regs[i]); + + /* if this was a block level spil then insert push & pop + at the start & end of block respectively */ + if (ssym->blockSpil) { + iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL); + /* add push to the start of the block */ + addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ? + ebp->sch->next : ebp->sch)); + nic = newiCode (IPOP, operandFromSymbol (ssym), NULL); + /* add pop to the end of the block */ + addiCodeToeBBlock (ebp, nic, NULL); + } + + /* if spilt because not used in the remainder of the + block then add a push before this instruction and + a pop at the end of the block */ + if (ssym->remainSpil) { + + iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL); + /* add push just before this instruction */ + addiCodeToeBBlock (ebp, nic, ic); + + nic = newiCode (IPOP, operandFromSymbol (ssym), NULL); + /* add pop to the end of the block */ + addiCodeToeBBlock (ebp, nic, NULL); + } + + if (ssym == forSym) + return FALSE; + else + return TRUE; } /*-----------------------------------------------------------------*/ @@ -778,24 +1047,28 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) static regs * getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym) { - regs *reg; + regs *reg; + + tryAgain: + /* try for a ptr type */ + if ((reg = allocReg (REG_PTR|REG_PAIR))) + return reg; -tryAgain: - /* try for a ptr type */ - if ((reg = allocReg (REG_PTR))) - return reg; + /* 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; + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; - /* we have to spil */ - if (!spilSomething (ic, ebp, sym)) - return NULL; + /* 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; + /* this looks like an infinite loop but + in reality selectSpil will abort */ + goto tryAgain; } /*-----------------------------------------------------------------*/ @@ -804,50 +1077,50 @@ tryAgain: static regs * getRegScr (iCode * ic, eBBlock * ebp, symbol * sym) { - regs *reg; + regs *reg; -tryAgain: - /* try for a ptr type */ - if ((reg = allocReg (REG_SCR))) - return reg; + tryAgain: - /* try for gpr type */ - if ((reg = allocReg (REG_GPR))) - return reg; + /* try for a scratch non-pair */ + if ((reg = allocReg (REG_SCR))) + return reg; + + if ((reg = allocReg (REG_GPR))) + return reg; - /* we have to spil */ - if (!spilSomething (ic, ebp, sym)) - return NULL; + /* 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; + /* this looks like an infinite loop but + in really selectSpil will abort */ + goto tryAgain; } /*-----------------------------------------------------------------*/ /* 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; + regs *reg; -tryAgain: - /* try for gpr type */ - if ((reg = allocReg (REG_GPR))) - return reg; + tryAgain: + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; - if (!avr_ptrRegReq) - if ((reg = allocReg (REG_PTR))) - return reg; + if (!avr_ptrRegReq) + if ((reg = allocReg (REG_PTR))) + return reg; - /* we have to spil */ - if (!spilSomething (ic, ebp, sym)) - return NULL; + /* we have to spil */ + if (!spilSomething (ic, ebp, sym)) + return NULL; - /* this looks like an infinite loop but - in reality selectSpil will abort */ - goto tryAgain; + /* this looks like an infinite loop but + in reality selectSpil will abort */ + goto tryAgain; } /*-----------------------------------------------------------------*/ @@ -856,13 +1129,13 @@ tryAgain: static bool symHasReg (symbol * sym, regs * reg) { - int i; + int i; - for (i = 0; i < sym->nRegs; i++) - if (sym->regs[i] == reg) - return TRUE; + for (i = 0; i < sym->nRegs; i++) + if (sym->regs[i] == reg) + return TRUE; - return FALSE; + return FALSE; } /*-----------------------------------------------------------------*/ @@ -872,101 +1145,90 @@ symHasReg (symbol * sym, regs * reg) static void deassignLRs (iCode * ic, eBBlock * ebp) { - symbol *sym; - int k; - symbol *result; - - for (sym = hTabFirstItem (liveRanges, &k); sym; - sym = hTabNextItem (liveRanges, &k)) - { - - symbol *psym = NULL; - /* if it does not end here */ - if (sym->liveTo > ic->seq) - continue; - - /* if it was spilt on stack then we can - mark the stack spil location as free */ - if (sym->isspilt) - { - if (sym->stackSpil) - { - sym->usl.spillLoc->isFree = 1; - sym->stackSpil = 0; - } - continue; - } - - if (!bitVectBitValue (_G.regAssigned, sym->key)) - continue; - - /* special case check if this is an IFX & - the privious one was a pop and the - previous one was not spilt then keep track - of the symbol */ - if (ic->op == IFX && ic->prev && - ic->prev->op == IPOP && - !ic->prev->parmPush && - !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt) - psym = OP_SYMBOL (IC_LEFT (ic->prev)); - - if (sym->nRegs) - { - int i = 0; - - bitVectUnSetBit (_G.regAssigned, sym->key); - - /* if the result of this one needs registers - and does not have it then assign it right - away */ - if (IC_RESULT (ic) && - !(SKIP_IC2 (ic) || /* not a special icode */ - ic->op == JUMPTABLE || - ic->op == IFX || - ic->op == IPUSH || - ic->op == IPOP || - ic->op == RETURN || - POINTER_SET (ic)) && - (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->regType == sym->regType && /* same register types */ - result->nRegs && /* which needs registers */ - !result->isspilt && /* and does not already have them */ - !result->remat && - !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); - - _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); - - } + symbol *sym; + int k; + symbol *result; + + for (sym = hTabFirstItem (liveRanges, &k); sym; + sym = hTabNextItem (liveRanges, &k)) { + + symbol *psym = NULL; + /* if it does not end here */ + if (sym->liveTo > ic->seq) + continue; + + /* if it was spilt on stack then we can + mark the stack spil location as free */ + if (sym->isspilt) { + if (sym->stackSpil) { + sym->usl.spillLoc->isFree = 1; + sym->stackSpil = 0; + } + continue; + } - /* free the remaining */ - for (; i < sym->nRegs; i++) - { - if (psym) - { - if (!symHasReg (psym, sym->regs[i])) - freeReg (sym->regs[i]); + if (!bitVectBitValue (_G.regAssigned, sym->key)) + continue; + + /* special case check if this is an IFX & + the privious one was a pop and the + previous one was not spilt then keep track + of the symbol */ + if (ic->op == IFX && ic->prev && + ic->prev->op == IPOP && + !ic->prev->parmPush && + !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt) + psym = OP_SYMBOL (IC_LEFT (ic->prev)); + + if (sym->nRegs) { + int i = 0; + + bitVectUnSetBit (_G.regAssigned, sym->key); + + /* if the result of this one needs registers + and does not have it then assign it right + away */ + if (IC_RESULT (ic) && !(SKIP_IC2 (ic) || /* not a special icode */ + ic->op == JUMPTABLE || + ic->op == IFX || + ic->op == IPUSH || + ic->op == IPOP || + ic->op == RETURN || + POINTER_SET (ic)) && + (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->regType == sym->regType && /* same register types */ + result->nRegs && /* which needs registers */ + !result->isspilt && /* and does not already have them */ + !result->remat && + !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); + } + _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); + + } + + /* free the remaining */ + for (; i < sym->nRegs; i++) { + if (psym) { + if (!symHasReg (psym, sym->regs[i])) + freeReg (sym->regs[i]); + } + else freeReg (sym->regs[i]); + } } - else - freeReg (sym->regs[i]); - } } - } } @@ -976,19 +1238,19 @@ deassignLRs (iCode * ic, eBBlock * ebp) static void reassignLR (operand * op) { - symbol *sym = OP_SYMBOL (op); - int i; + symbol *sym = OP_SYMBOL (op); + int i; - /* not spilt any more */ - sym->isspilt = sym->blockSpil = sym->remainSpil = 0; - bitVectUnSetBit (_G.spiltSet, sym->key); + /* not spilt any more */ + sym->isspilt = sym->blockSpil = sym->remainSpil = 0; + bitVectUnSetBit (_G.spiltSet, sym->key); - _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); - _G.blockSpil--; + _G.blockSpil--; - for (i = 0; i < sym->nRegs; i++) - sym->regs[i]->isFree = 0; + for (i = 0; i < sym->nRegs; i++) + sym->regs[i]->isFree = 0; } /*-----------------------------------------------------------------*/ @@ -997,35 +1259,30 @@ reassignLR (operand * op) static int willCauseSpill (int nr, int rt) { - /* first check if there are any avlb registers - of te type required */ - if (rt == REG_PTR) - { - /* special case for pointer type - if pointer type not avlb then - check for type gpr */ - if (nFreeRegs (rt) >= nr) - return 0; - if (nFreeRegs (REG_GPR) >= nr) - return 0; - } - else - { - if (avr_ptrRegReq) - { - if (nFreeRegs (rt) >= nr) - return 0; + /* first check if there are any avlb registers + of te type required */ + if (rt == REG_PTR) { + /* special case for pointer type + if pointer type not avlb then + check for type gpr */ + if (nFreeRegs (rt) >= nr) + return 0; + if (nFreeRegs (REG_GPR) >= nr) + return 0; } - else - { - if (nFreeRegs (REG_PTR) + - nFreeRegs (REG_GPR) >= nr) - return 0; + else { + if (avr_ptrRegReq) { + if (nFreeRegs (rt) >= nr) + return 0; + } + else { + if (nFreeRegs (REG_PTR) + nFreeRegs (REG_GPR) >= nr) + return 0; + } } - } - /* it will cause a spil */ - return 1; + /* it will cause a spil */ + return 1; } /*-----------------------------------------------------------------*/ @@ -1036,34 +1293,58 @@ willCauseSpill (int nr, int rt) static void positionRegs (symbol * result, symbol * opsym, int lineno) { - 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: - shared = 0; - /* first make sure that they actually share */ - for (i = 0; i < count; i++) - { - for (j = 0; j < count; j++) - { - if (result->regs[i] == opsym->regs[j] && i != j) - { - shared = 1; - goto xchgPositions; - } + 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: + shared = 0; + /* first make sure that they actually share */ + for (i = 0; i < count; i++) { + for (j = 0; j < count; j++) { + if (result->regs[i] == opsym->regs[j] && i != j) { + shared = 1; + goto 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; + if (!uic) continue; + otype = (IC_RIGHT(uic) ? operandType(IC_RIGHT(uic)) : NULL); + if (otype && IS_LITERAL(otype)) return 1; + bitVectUnSetBit(uses_defs,ikey); } - } -xchgPositions: - if (shared) - { - regs *tmp = result->regs[i]; - result->regs[i] = result->regs[j]; - result->regs[j] = tmp; - goto again; - } + return 0; } /*-----------------------------------------------------------------*/ @@ -1072,137 +1353,143 @@ xchgPositions: static void serialRegAssign (eBBlock ** ebbs, int count) { - int i; - - /* for all blocks */ - for (i = 0; i < count; i++) - { - - iCode *ic; - - if (ebbs[i]->noPath && - (ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel)) - continue; - - /* of all instructions do */ - for (ic = ebbs[i]->sch; ic; ic = ic->next) - { - - /* if this is an ipop that means some live - range will have to be assigned again */ - if (ic->op == IPOP) - reassignLR (IC_LEFT (ic)); - - /* if result is present && is a true symbol */ - if (IC_RESULT (ic) && ic->op != IFX && - IS_TRUE_SYMOP (IC_RESULT (ic))) - OP_SYMBOL (IC_RESULT (ic))->allocreq = 1; - - /* take away registers from live - ranges that end at this instruction */ - deassignLRs (ic, ebbs[i]); - - /* some don't need registers */ - if (SKIP_IC2 (ic) || - ic->op == JUMPTABLE || - ic->op == IFX || - ic->op == IPUSH || - ic->op == IPOP || - (IC_RESULT (ic) && POINTER_SET (ic))) - continue; - - /* now we need to allocate registers - only for the result */ - if (IC_RESULT (ic)) - { - symbol *sym = OP_SYMBOL (IC_RESULT (ic)); - bitVect *spillable; - int willCS; - int j; - - /* if it does not need or is spilt - or is already assigned to registers - or will not live beyond this instructions */ - if (!sym->nRegs || - sym->isspilt || - 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 (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) - { - spillThis (sym); - continue; - } - /* if trying to allocate this will cause - a spill and there is nothing to spill - or this one is rematerializable then - spill this one */ - willCS = willCauseSpill (sym->nRegs, sym->regType); - spillable = computeSpillable (ic); - if (sym->remat || - (willCS && bitVectIsZero (spillable))) - { - - 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; - } - } - - /* we assign registers to it */ - _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->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); - - /* if the allocation falied which means - this was spilt then break */ - if (!sym->regs[j]) - break; + int i; + + /* for all blocks */ + for (i = 0; i < count; i++) { + + iCode *ic; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + continue; + + /* of all instructions do */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) { + + /* if this is an ipop that means some live + range will have to be assigned again */ + if (ic->op == IPOP) + reassignLR (IC_LEFT (ic)); + + /* if result is present && is a true symbol */ + if (IC_RESULT (ic) && ic->op != IFX && + IS_TRUE_SYMOP (IC_RESULT (ic))) + OP_SYMBOL (IC_RESULT (ic))->allocreq = 1; + + /* take away registers from live + ranges that end at this instruction */ + deassignLRs (ic, ebbs[i]); + + /* some don't need registers */ + if (SKIP_IC2 (ic) || + ic->op == JUMPTABLE || + ic->op == IFX || + ic->op == IPUSH || + ic->op == IPOP || + (IC_RESULT (ic) && POINTER_SET (ic))) continue; + + /* now we need to allocate registers + only for the result */ + if (IC_RESULT (ic)) { + symbol *sym = OP_SYMBOL (IC_RESULT (ic)); + bitVect *spillable; + int willCS; + int j=0; + + /* if it does not need or is spilt + or is already assigned to registers + or will not live beyond this instructions */ + if (!sym->nRegs || + sym->isspilt || + 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 (_G.blockSpil + && sym->liveTo > ebbs[i]->lSeq) { + spillThis (sym); + continue; + } + /* if trying to allocate this will cause + a spill and there is nothing to spill + or this one is rematerializable then + spill this one */ + willCS = + willCauseSpill (sym->nRegs, + sym->regType); + spillable = computeSpillable (ic); + if (sym->remat || (willCS && bitVectIsZero (spillable))) { + spillThis (sym); + continue; + } + + /* if it has a spillocation & is used less than + all other live ranges then spill this */ + 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); + 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 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); + /* 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); + + } } - /* 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); - /* 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); - - } } - } } /*-----------------------------------------------------------------*/ @@ -1211,30 +1498,28 @@ serialRegAssign (eBBlock ** ebbs, int count) static bitVect * rUmaskForOp (operand * op) { - bitVect *rumask; - symbol *sym; - int j; + bitVect *rumask; + symbol *sym; + int j; - /* only temporaries are assigned registers */ - if (!IS_ITEMP (op)) - return NULL; + /* only temporaries are assigned registers */ + if (!IS_ITEMP (op)) + return NULL; - sym = OP_SYMBOL (op); + sym = OP_SYMBOL (op); - /* if spilt or no registers assigned to it - then nothing */ - if (sym->isspilt || !sym->nRegs) - return NULL; + /* if spilt or no registers assigned to it + then nothing */ + if (sym->isspilt || !sym->nRegs) + return NULL; - rumask = newBitVect (avr_nRegs); + rumask = newBitVect (avr_nRegs); - for (j = 0; j < sym->nRegs; j++) - { - rumask = bitVectSetBit (rumask, - sym->regs[j]->rIdx); - } + for (j = 0; j < sym->nRegs; j++) { + rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx); + } - return rumask; + return rumask; } /*-----------------------------------------------------------------*/ @@ -1243,41 +1528,34 @@ rUmaskForOp (operand * op) static bitVect * regsUsedIniCode (iCode * ic) { - bitVect *rmask = newBitVect (avr_nRegs); + bitVect *rmask = newBitVect (avr_nRegs); - /* do the special cases first */ - if (ic->op == IFX) - { - rmask = bitVectUnion (rmask, - rUmaskForOp (IC_COND (ic))); - goto ret; - } + /* do the special cases first */ + if (ic->op == IFX) { + rmask = bitVectUnion (rmask, rUmaskForOp (IC_COND (ic))); + goto ret; + } - /* for the jumptable */ - if (ic->op == JUMPTABLE) - { - rmask = bitVectUnion (rmask, - rUmaskForOp (IC_JTCOND (ic))); + /* for the jumptable */ + if (ic->op == JUMPTABLE) { + rmask = bitVectUnion (rmask, rUmaskForOp (IC_JTCOND (ic))); - goto ret; - } + goto ret; + } - /* of all other cases */ - if (IC_LEFT (ic)) - rmask = bitVectUnion (rmask, - rUmaskForOp (IC_LEFT (ic))); + /* of all other cases */ + if (IC_LEFT (ic)) + rmask = bitVectUnion (rmask, rUmaskForOp (IC_LEFT (ic))); - if (IC_RIGHT (ic)) - rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RIGHT (ic))); + if (IC_RIGHT (ic)) + rmask = bitVectUnion (rmask, rUmaskForOp (IC_RIGHT (ic))); - if (IC_RESULT (ic)) - rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RESULT (ic))); + if (IC_RESULT (ic)) + rmask = bitVectUnion (rmask, rUmaskForOp (IC_RESULT (ic))); -ret: - return rmask; + ret: + return rmask; } /*-----------------------------------------------------------------*/ @@ -1286,107 +1564,72 @@ ret: static void createRegMask (eBBlock ** ebbs, int count) { - int i; - - /* for all blocks */ - for (i = 0; i < count; i++) - { - iCode *ic; - - if (ebbs[i]->noPath && - (ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel)) - continue; - - /* for all instructions */ - for (ic = ebbs[i]->sch; ic; ic = ic->next) - { - - int j; - - if (SKIP_IC2 (ic) || !ic->rlive) - continue; - - /* first mark the registers used in this - instruction */ - ic->rUsed = regsUsedIniCode (ic); - _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 (avr_nRegs + 1); - - /* for all live Ranges alive at this point */ - for (j = 1; j < ic->rlive->size; j++) - { - symbol *sym; - int k; - - /* if not alive then continue */ - if (!bitVectBitValue (ic->rlive, j)) - continue; - - /* find the live range we are interested in */ - if (!(sym = hTabItemWithKey (liveRanges, j))) - { - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "createRegMask cannot find live range"); - exit (0); + int i; + + /* for all blocks */ + for (i = 0; i < count; i++) { + iCode *ic; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + continue; + + /* for all instructions */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) { + + int j; + + if (SKIP_IC2 (ic) || !ic->rlive) + continue; + + /* first mark the registers used in this + instruction */ + ic->rUsed = regsUsedIniCode (ic); + _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 (avr_nRegs + 1); + + /* for all live Ranges alive at this point */ + for (j = 1; j < ic->rlive->size; j++) { + symbol *sym; + int k; + + /* if not alive then continue */ + if (!bitVectBitValue (ic->rlive, j)) + continue; + + /* find the live range we are interested in */ + if (!(sym = hTabItemWithKey (liveRanges, j))) { + werror (E_INTERNAL_ERROR, __FILE__, + __LINE__, + "createRegMask cannot find live range"); + exit (0); + } + + /* if no register assigned to it */ + if (!sym->nRegs || sym->isspilt) + continue; + + /* 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); + /* 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); + } + } + } } - - /* if no register assigned to it */ - if (!sym->nRegs || sym->isspilt) - continue; - - /* 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); - /* 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); - } - } - } } - } } -/*-----------------------------------------------------------------*/ -/* 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 */ @@ -1394,89 +1637,85 @@ rematStr (symbol * sym) static void regTypeNum () { - symbol *sym; - int k; - iCode *ic; - - /* for each live range do */ - for (sym = hTabFirstItem (liveRanges, &k); sym; - sym = hTabNextItem (liveRanges, &k)) - { - - /* if used zero times then no registers needed */ - if ((sym->liveTo - sym->liveFrom) == 0) - continue; - - - /* if the live range is a temporary */ - if (sym->isitmp) - { - - /* if the type is marked as a conditional */ - if (sym->regType == REG_CND) - continue; - - /* if used in return only then we don't - need registers */ - if (sym->ruonly || sym->accuse) - { - if (IS_AGGREGATE (sym->type) || sym->isptr) - sym->type = aggrToPtr (sym->type, FALSE); - continue; - } - - /* if the symbol has only one definition & - that definition is a get_pointer and the - pointer we are getting is rematerializable and - in "data" space */ - - if (bitVectnBitsOn (sym->defs) == 1 && - (ic = hTabItemWithKey (iCodehTab, - bitVectFirstBit (sym->defs))) && - POINTER_GET (ic) && - !IS_BITVAR (sym->etype)) - { - - /* if in data space or idata space then try to - allocate pointer register */ - - } - - /* if not then we require registers */ - sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ? - getSize (sym->type = aggrToPtr (sym->type, FALSE)) : - getSize (sym->type)); - - if (sym->nRegs > 4) - { - fprintf (stderr, "allocated more than 4 or 0 registers for type "); - printTypeChain (sym->type, stderr); - fprintf (stderr, "\n"); - } - - /* determine the type of register required */ - if (sym->nRegs == 2 && /* size is two */ - IS_PTR (sym->type) && /* is a pointer */ - sym->uptr) - { /* has pointer usage i.e. get/set pointer */ - sym->regType = REG_PTR; - avr_ptrRegReq++; - } - else - { - /* live accross a function call then gpr else scratch */ - if (sym->isLiveFcall) - sym->regType = REG_GPR; - else - sym->regType = REG_SCR; - } + symbol *sym; + int k; + iCode *ic; + + /* for each live range do */ + for (sym = hTabFirstItem (liveRanges, &k); sym; + sym = hTabNextItem (liveRanges, &k)) { + + /* if used zero times then no registers needed */ + if ((sym->liveTo - sym->liveFrom) == 0) + continue; + + + /* if the live range is a temporary */ + if (sym->isitmp) { + + /* if the type is marked as a conditional */ + if (sym->regType == REG_CND) + continue; + + /* if used in return only then we don't + need registers */ + if (sym->ruonly || sym->accuse) { + if (IS_AGGREGATE (sym->type) || sym->isptr) + sym->type = + aggrToPtr (sym->type, FALSE); + continue; + } + + /* if the symbol has only one definition & + that definition is a get_pointer and the + pointer we are getting is rematerializable and + in "data" space */ + + if (bitVectnBitsOn (sym->defs) == 1 && + (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym-> defs))) + && POINTER_GET (ic) && !IS_BITVAR (sym->etype)) { + + /* if in data space or idata space then try to + allocate pointer register */ + + } + + /* if not then we require registers */ + sym->nRegs = + ((IS_AGGREGATE (sym->type) || sym->isptr) ? + getSize (sym->type = + aggrToPtr (sym->type, + FALSE)) : getSize (sym-> + type)); + + if (sym->nRegs > 4) { + fprintf (stderr, + "allocated more than 4 or 0 registers for type "); + printTypeChain (sym->type, stderr); + fprintf (stderr, "\n"); + } + + /* determine the type of register required */ + if (sym->nRegs == 2 && /* size is two */ + IS_PTR (sym->type) && /* is a pointer */ + sym->uptr) { /* has pointer usage i.e. get/set pointer */ + sym->regType = REG_PTR; + avr_ptrRegReq++; + } + 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 */ + /* see how things go */ + sym->nRegs = 0; } - else - /* for the first run we don't provide */ - /* registers for true symbols we will */ - /* see how things go */ - sym->nRegs = 0; - } } @@ -1486,77 +1725,10 @@ regTypeNum () static DEFSETFUNC (deallocStackSpil) { - symbol *sym = item; - - deallocLocal (sym); - 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; + symbol *sym = item; - 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; + deallocLocal (sym); + return 0; } /*-----------------------------------------------------------------*/ @@ -1565,268 +1737,111 @@ farSpacePackable (iCode * ic) static int packRegsForAssign (iCode * ic, eBBlock * ebp) { - iCode *dic, *sic; - - if (!IS_ITEMP (IC_RIGHT (ic)) || - OP_SYMBOL (IC_RIGHT (ic))->isind || - OP_LIVETO (IC_RIGHT (ic)) > ic->seq) - { - return 0; - } - - /* find the definition of iTempNN scanning backwards if we find a - a use of the true symbol in before we find the definition then - we cannot */ - for (dic = ic->prev; dic; dic = dic->prev) - { - - /* if there is a function call and this is - a parameter & not my parameter then don't pack it */ - if ((dic->op == CALL || dic->op == PCALL) && - (OP_SYMBOL (IC_RESULT (ic))->_isparm && - !OP_SYMBOL (IC_RESULT (ic))->ismyparm)) - { - dic = NULL; - break; - } + iCode *dic, *sic; - if (SKIP_IC2 (dic)) - continue; - - if (IS_TRUE_SYMOP (IC_RESULT (dic)) && - IS_OP_VOLATILE (IC_RESULT (dic))) - { - dic = NULL; - break; + if (!IS_ITEMP (IC_RIGHT (ic)) || + OP_SYMBOL (IC_RIGHT (ic))->isind || + OP_LIVETO (IC_RIGHT (ic)) > ic->seq) { + return 0; } - if (IS_SYMOP (IC_RESULT (dic)) && - IC_RESULT (dic)->key == IC_RIGHT (ic)->key) - { - if (POINTER_SET (dic)) - dic = NULL; - - break; - } - - if (IS_SYMOP (IC_RIGHT (dic)) && - (IC_RIGHT (dic)->key == IC_RESULT (ic)->key || - IC_RIGHT (dic)->key == IC_RIGHT (ic)->key)) - { - dic = NULL; - break; - } + /* find the definition of iTempNN scanning backwards if we find a + a use of the true symbol in before we find the definition then + we cannot */ + for (dic = ic->prev; dic; dic = dic->prev) { + + /* if there is a function call and this is + a parameter & not my parameter then don't pack it */ + if ((dic->op == CALL || dic->op == PCALL) && + (OP_SYMBOL (IC_RESULT (ic))->_isparm && + !OP_SYMBOL (IC_RESULT (ic))->ismyparm)) { + dic = NULL; + break; + } - if (IS_SYMOP (IC_LEFT (dic)) && - (IC_LEFT (dic)->key == IC_RESULT (ic)->key || - IC_LEFT (dic)->key == IC_RIGHT (ic)->key)) - { - dic = NULL; - break; - } + if (SKIP_IC2 (dic)) + continue; - if (POINTER_SET (dic) && - IC_RESULT (dic)->key == IC_RESULT (ic)->key) - { - dic = NULL; - break; - } - } - - if (!dic) - return 0; /* did not find */ - - /* 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 || - OP_SYMBOL (IC_RESULT (ic))->iaccess) - { - - /* the operation has only one symbol - operator then we can pack */ - if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) || - (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic)))) - goto pack; - - if (!((IC_LEFT (dic) && - IC_RESULT (ic)->key == IC_LEFT (dic)->key) || - (IC_RIGHT (dic) && - IC_RESULT (ic)->key == IC_RIGHT (dic)->key))) - return 0; - } -pack: - /* if in far space & tru symbol then don't */ - if ((IS_TRUE_SYMOP (IC_RESULT (ic))) && isOperandInFarSpace (IC_RESULT (ic))) - return 0; - /* found the definition */ - /* replace the result with the result of */ - /* this assignment and remove this assignment */ - IC_RESULT (dic) = IC_RESULT (ic); - - if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) - { - OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq; - } - /* delete from liverange table also - delete from all the points inbetween and the new - one */ - for (sic = dic; sic != ic; sic = sic->next) - { - bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key); - if (IS_ITEMP (IC_RESULT (dic))) - bitVectSetBit (sic->rlive, IC_RESULT (dic)->key); - } - - remiCodeFromeBBlock (ebp, ic); - hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - return 1; + 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)) + dic = NULL; -/*-----------------------------------------------------------------*/ -/* 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) - { + break; + } - /* 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; - } + if (IS_SYMOP (IC_RIGHT (dic)) && + (IC_RIGHT (dic)->key == IC_RESULT (ic)->key || + IC_RIGHT (dic)->key == IC_RIGHT (ic)->key)) { + dic = NULL; + break; + } - break; + if (IS_SYMOP (IC_LEFT (dic)) && + (IC_LEFT (dic)->key == IC_RESULT (ic)->key || + IC_LEFT (dic)->key == IC_RIGHT (ic)->key)) { + dic = NULL; + break; + } + if (POINTER_SET (dic) && + IC_RESULT (dic)->key == IC_RESULT (ic)->key) { + dic = 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 (!dic) + return 0; /* did not find */ - if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key) - return NULL; - } + /* 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 || + OP_SYMBOL (IC_RESULT (ic))->iaccess) { - /* now make sure that the right side of dic - is not defined between ic & dic */ - if (dic) - { - iCode *sic = dic->next; + /* the operation has only one symbol + operator then we can pack */ + if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) || + (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic)))) + goto pack; - 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; + if (!((IC_LEFT (dic) && + IC_RESULT (ic)->key == IC_LEFT (dic)->key) || + (IC_RIGHT (dic) && + IC_RESULT (ic)->key == IC_RIGHT (dic)->key))) return 0; + } + pack: + /* if in far space & tru symbol then don't */ + if ((IS_TRUE_SYMOP (IC_RESULT (ic))) + && isOperandInFarSpace (IC_RESULT (ic))) return 0; + /* found the definition */ + /* replace the result with the result of */ + /* this assignment and remove this assignment */ + IC_RESULT (dic) = IC_RESULT (ic); + + if (IS_ITEMP (IC_RESULT (dic)) + && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) { + OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq; + } + /* delete from liverange table also + delete from all the points inbetween and the new + one */ + for (sic = dic; sic != ic; sic = sic->next) { + bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key); + if (IS_ITEMP (IC_RESULT (dic))) + bitVectSetBit (sic->rlive, IC_RESULT (dic)->key); } - /* 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++; - } + remiCodeFromeBBlock (ebp, ic); + hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); + return 1; - return change; } #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) @@ -1838,117 +1853,110 @@ right: static iCode * packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) { - bitVect *uses; - iCode *dic, *sic; - - /* if returning a literal then do nothing */ - if (!IS_SYMOP (op)) - return NULL; - - /* returns only */ - if (ic->op != RETURN) - return NULL; - - /* this routine will mark the a symbol as used in one - instruction use only && if the defintion is local - (ie. within the basic block) && has only one definition && - that definiion is either a return value from a - function or does not contain any variables in - far space */ - uses = bitVectCopy (OP_USES (op)); - bitVectUnSetBit (uses, ic->key); /* take away this iCode */ - if (!bitVectIsZero (uses)) /* has other uses */ - return NULL; - - /* if it has only one defintion */ - if (bitVectnBitsOn (OP_DEFS (op)) > 1) - return NULL; /* has more than one definition */ - - /* get the that definition */ - if (!(dic = - hTabItemWithKey (iCodehTab, - bitVectFirstBit (OP_DEFS (op))))) - return NULL; - - /* found the definition now check if it is local */ - if (dic->seq < ebp->fSeq || - dic->seq > ebp->lSeq) - return NULL; /* non-local */ - - /* 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) - { - OP_SYMBOL (op)->ruonly = 1; - return dic; - } - dic = dic->next; - } + bitVect *uses; + iCode *dic, *sic; + /* if returning a literal then do nothing */ + if (!IS_SYMOP (op)) + return NULL; - /* otherwise check that the definition does - not contain any symbols in far space */ - if (IS_OP_RUONLY (IC_LEFT (ic)) || - IS_OP_RUONLY (IC_RIGHT (ic))) - { - return NULL; - } - - /* if pointer set then make sure the pointer - is one byte */ - if (POINTER_SET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE))) - return NULL; - - if (POINTER_GET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) - return NULL; + /* returns only */ + if (ic->op != RETURN) + return NULL; - sic = dic; + /* this routine will mark the a symbol as used in one + instruction use only && if the defintion is local + (ie. within the basic block) && has only one definition && + that definiion is either a return value from a + function or does not contain any variables in + far space */ + uses = bitVectCopy (OP_USES (op)); + bitVectUnSetBit (uses, ic->key); /* take away this iCode */ + if (!bitVectIsZero (uses)) /* has other uses */ + return NULL; - /* also make sure the intervenening instructions - don't have any thing in far space */ - for (dic = dic->next; dic && dic != ic; dic = dic->next) - { + /* if it has only one defintion */ + if (bitVectnBitsOn (OP_DEFS (op)) > 1) + return NULL; /* has more than one definition */ + + /* get the that definition */ + if (!(dic = + hTabItemWithKey (iCodehTab, + bitVectFirstBit (OP_DEFS (op))))) return NULL; + + /* found the definition now check if it is local */ + if (dic->seq < ebp->fSeq || dic->seq > ebp->lSeq) + return NULL; /* non-local */ + + /* 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) { + OP_SYMBOL (op)->ruonly = 1; + return dic; + } + dic = dic->next; + } - /* if there is an intervening function call then no */ - if (dic->op == CALL || dic->op == PCALL) - return NULL; - /* if pointer set then make sure the pointer - is one byte */ - if (POINTER_SET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE))) - return NULL; - if (POINTER_GET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) - return NULL; + /* otherwise check that the definition does + not contain any symbols in far space */ + if (IS_OP_RUONLY (IC_LEFT (ic)) || IS_OP_RUONLY (IC_RIGHT (ic))) { + return NULL; + } - /* if address of & the result is remat the okay */ - if (dic->op == ADDRESS_OF && - OP_SYMBOL (IC_RESULT (dic))->remat) - continue; + /* if pointer set then make sure the pointer + is one byte */ + if (POINTER_SET (dic) && + !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE))) + return NULL; - /* if operand has size of three or more & this - operation is a '*','/' or '%' then 'b' may - cause a problem */ - if ((dic->op == '%' || dic->op == '/' || dic->op == '*') && - getSize (operandType (op)) >= 3) - return NULL; + if (POINTER_GET (dic) && + !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) + return NULL; - /* if left or right or result is in far space */ - if (IS_OP_RUONLY (IC_LEFT (dic)) || - IS_OP_RUONLY (IC_RIGHT (dic)) || - IS_OP_RUONLY (IC_RESULT (dic))) - { - return NULL; + sic = dic; + + /* also make sure the intervenening instructions + don't have any thing in far space */ + for (dic = dic->next; dic && dic != ic; dic = dic->next) { + + /* if there is an intervening function call then no */ + if (dic->op == CALL || dic->op == PCALL) + return NULL; + /* if pointer set then make sure the pointer + is one byte */ + if (POINTER_SET (dic) && + !IS_DATA_PTR (aggrToPtr + (operandType (IC_RESULT (dic)), + FALSE))) return NULL; + + if (POINTER_GET (dic) && + !IS_DATA_PTR (aggrToPtr + (operandType (IC_LEFT (dic)), + FALSE))) return NULL; + + /* if address of & the result is remat the okay */ + if (dic->op == ADDRESS_OF && + OP_SYMBOL (IC_RESULT (dic))->remat) continue; + + /* if operand has size of three or more & this + operation is a '*','/' or '%' then 'b' may + cause a problem */ + if ((dic->op == '%' || dic->op == '/' || dic->op == '*') && + getSize (operandType (op)) >= 3) + return NULL; + + /* if left or right or result is in far space */ + 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; - return sic; + OP_SYMBOL (op)->ruonly = 1; + return sic; } @@ -1958,59 +1966,27 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) static bool isBitwiseOptimizable (iCode * ic) { - sym_link *ltype = getSpec (operandType (IC_LEFT (ic))); - sym_link *rtype = getSpec (operandType (IC_RIGHT (ic))); - - /* bitwise operations are considered optimizable - under the following conditions (Jean-Louis VERN) - - x & lit - bit & bit - bit & x - bit ^ bit - bit ^ x - x ^ lit - x | lit - bit | bit - bit | x - */ - if (IS_LITERAL (rtype) || - (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype)))) - return TRUE; - else - 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); + sym_link *ltype = getSpec (operandType (IC_LEFT (ic))); + sym_link *rtype = getSpec (operandType (IC_RIGHT (ic))); + + /* bitwise operations are considered optimizable + under the following conditions (Jean-Louis VERN) + + x & lit + bit & bit + bit & x + bit ^ bit + bit ^ x + x ^ lit + x | lit + bit | bit + bit | x + */ + if (IS_LITERAL (rtype) || + (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype)))) + return TRUE; + else + return FALSE; } /*-----------------------------------------------------------------*/ @@ -2020,164 +1996,167 @@ packForPush (iCode * ic, eBBlock * ebp) static void packRegisters (eBBlock * ebp) { - iCode *ic; - int change = 0; + iCode *ic; + int change = 0; + + while (1) { - while (1) - { + change = 0; - change = 0; + /* look for assignments of the form */ + /* iTempNN = TRueSym (someoperation) SomeOperand */ + /* .... */ + /* TrueSym := iTempNN:1 */ + for (ic = ebp->sch; ic; ic = ic->next) { - /* look for assignments of the form */ - /* iTempNN = TRueSym (someoperation) SomeOperand */ - /* .... */ - /* TrueSym := iTempNN:1 */ - for (ic = ebp->sch; ic; ic = ic->next) - { + /* find assignment of the form TrueSym := iTempNN:1 */ + if (ic->op == '=' && !POINTER_SET (ic)) + change += packRegsForAssign (ic, ebp); + } - /* find assignment of the form TrueSym := iTempNN:1 */ - if (ic->op == '=' && !POINTER_SET (ic)) - change += packRegsForAssign (ic, ebp); + if (!change) + break; } - if (!change) - break; - } + for (ic = ebp->sch; ic; ic = ic->next) { - for (ic = ebp->sch; ic; ic = ic->next) - { + /* if this is an itemp & result of a address of a true sym + then mark this as rematerialisable */ + if (ic->op == ADDRESS_OF && + IS_ITEMP (IC_RESULT (ic)) && + IS_TRUE_SYMOP (IC_LEFT (ic)) && + bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && + !OP_SYMBOL (IC_LEFT (ic))->onStack) { - /* if this is an itemp & result of a address of a true sym - then mark this as rematerialisable */ - if (ic->op == ADDRESS_OF && - IS_ITEMP (IC_RESULT (ic)) && - IS_TRUE_SYMOP (IC_LEFT (ic)) && - bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && - !OP_SYMBOL (IC_LEFT (ic))->onStack) - { + 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; + } - } + /* if straight assignment then carry remat flag if + this is the only definition */ + if (ic->op == '=' && + !POINTER_SET (ic) && + IS_SYMOP (IC_RIGHT (ic)) && + OP_SYMBOL (IC_RIGHT (ic))->remat && + bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) { + + OP_SYMBOL (IC_RESULT (ic))->remat = + OP_SYMBOL (IC_RIGHT (ic))->remat; + OP_SYMBOL (IC_RESULT (ic))->rematiCode = + OP_SYMBOL (IC_RIGHT (ic))->rematiCode; + } - /* if straight assignment then carry remat flag if - this is the only definition */ - if (ic->op == '=' && - !POINTER_SET (ic) && - IS_SYMOP (IC_RIGHT (ic)) && - OP_SYMBOL (IC_RIGHT (ic))->remat && - bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) - { - - OP_SYMBOL (IC_RESULT (ic))->remat = - OP_SYMBOL (IC_RIGHT (ic))->remat; - OP_SYMBOL (IC_RESULT (ic))->rematiCode = - OP_SYMBOL (IC_RIGHT (ic))->rematiCode; - } + /* 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 */ + if ((ic->op == '+' || ic->op == '-') && + (IS_SYMOP (IC_LEFT (ic)) && + IS_ITEMP (IC_RESULT (ic)) && + OP_SYMBOL (IC_LEFT (ic))->remat && + bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && + IS_OP_LITERAL (IC_RIGHT (ic)))) { + + int i = (int) 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; + } + } - /* 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 */ - if ((ic->op == '+' || ic->op == '-') && - - (IS_SYMOP (IC_LEFT (ic)) && - IS_ITEMP (IC_RESULT (ic)) && - OP_SYMBOL (IC_LEFT (ic))->remat && - bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && - IS_OP_LITERAL (IC_RIGHT (ic)))) - { - - int i = (int) 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; - } - } + /* mark the pointer usages */ + if (POINTER_SET (ic)) + OP_SYMBOL (IC_RESULT (ic))->uptr = 1; - /* mark the pointer usages */ - if (POINTER_SET (ic)) - OP_SYMBOL (IC_RESULT (ic))->uptr = 1; - - if (POINTER_GET (ic)) - OP_SYMBOL (IC_LEFT (ic))->uptr = 1; - - /* if the condition of an if instruction - is defined in the previous instruction then - mark the itemp as a conditional */ - if ((IS_CONDITIONAL (ic) || - ((ic->op == BITWISEAND || - ic->op == '|' || - ic->op == '^') && - isBitwiseOptimizable (ic))) && - ic->next && ic->next->op == IFX && - isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) && - OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) - { - - OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; - continue; - } + 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; + } - /* some cases the redundant moves can - can be eliminated for return statements */ - if ((ic->op == RETURN || ic->op == SEND)) - packRegsForOneuse (ic, IC_LEFT (ic), ebp); - - /* if this is cast for intergral promotion then - check if only use of the definition of the - operand being casted/ if yes then replace - the result of that arithmetic operation with - this result and get rid of the cast */ - if (ic->op == CAST) - { - sym_link *fromType = operandType (IC_RIGHT (ic)); - sym_link *toType = operandType (IC_LEFT (ic)); - - if (IS_INTEGRAL (fromType) && IS_INTEGRAL (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); - ic = ic->prev; - } - else - OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0; + /* if the condition of an if instruction + is defined in the previous instruction then + mark the itemp as a conditional */ + if ((IS_CONDITIONAL (ic) || + ((ic->op == BITWISEAND || + ic->op == '|' || + ic->op == '^') && + isBitwiseOptimizable (ic))) && + ic->next && ic->next->op == IFX && + isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) && + OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) { + + OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; + continue; } - } - else - { - - /* 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)), - operandType (IC_LEFT (ic))) == 1) - { - iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp); - if (dic) - { - IC_RESULT (dic) = IC_RESULT (ic); - remiCodeFromeBBlock (ebp, ic); - hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - ic = ic->prev; - } + + /* some cases the redundant moves can + can be eliminated for return statements */ + if ((ic->op == RETURN || ic->op == SEND)) + packRegsForOneuse (ic, IC_LEFT (ic), ebp); + + /* if this is cast for intergral promotion then + check if only use of the definition of the + operand being casted/ if yes then replace + the result of that arithmetic operation with + this result and get rid of the cast */ + if (ic->op == CAST) { + sym_link *fromType = operandType (IC_RIGHT (ic)); + sym_link *toType = operandType (IC_LEFT (ic)); + + if (IS_INTEGRAL (fromType) && IS_INTEGRAL (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); + ic = ic->prev; + } + else + OP_SYMBOL (IC_RIGHT (ic))-> + ruonly = 0; + } + } + else { + + /* if the type from and type to are the same + then if this is the only use then packit */ + if (compareType (operandType (IC_RIGHT (ic)), + operandType (IC_LEFT (ic))) == + 1) { + iCode *dic = + packRegsForOneuse (ic, + IC_RIGHT + (ic), ebp); + if (dic) { + IC_RESULT (dic) = + IC_RESULT (ic); + remiCodeFromeBBlock (ebp, ic); + hTabDeleteItem (&iCodehTab, + ic->key, ic, + DELETE_ITEM, + NULL); + ic = ic->prev; + } + } + } } - } } - } } /*-----------------------------------------------------------------*/ @@ -2186,41 +2165,37 @@ packRegisters (eBBlock * ebp) static void preAssignParms (iCode * ic) { - int i = R16_IDX; - /* look for receives and assign registers - to the result of the receives */ - while (ic) - { - /* if it is a receive */ - if (ic->op == RECEIVE) - { - symbol *r = OP_SYMBOL (IC_RESULT (ic)); - int size = getSize (r->type); - if (r->regType == REG_GPR || r->regType == REG_SCR) - { - int j = 0; - while (size--) - { - r->regs[j++] = ®sAVR[i++]; - regsAVR[i - 1].isFree = 0; - } - /* put in the regassigned vector */ - _G.regAssigned = bitVectSetBit (_G.regAssigned, r->key); - } - else - { - /* not a GPR then we should mark as free */ - while (size--) - { - regsAVR[i++].isFree = 1; + int i = R16_IDX; + /* look for receives and assign registers + to the result of the receives */ + while (ic) { + /* if it is a receive */ + if (ic->op == RECEIVE) { + symbol *r = OP_SYMBOL (IC_RESULT (ic)); + int size = getSize (r->type); + if (r->regType == REG_GPR || r->regType == REG_SCR) { + int j = 0; + while (size--) { + r->regs[j++] = ®sAVR[i++]; + regsAVR[i - 1].isFree = 0; + } + /* put in the regassigned vector */ + _G.regAssigned = + bitVectSetBit (_G.regAssigned, + r->key); + } + else { + /* not a GPR then we should mark as free */ + while (size--) { + regsAVR[i++].isFree = 1; + } + } } - } + ic = ic->next; } - ic = ic->next; - } - /* mark anything remaining as free */ - while (i <= R23_IDX) - regsAVR[i++].isFree = 1; + /* mark anything remaining as free */ + while (i <= R23_IDX) + regsAVR[i++].isFree = 1; } /*-----------------------------------------------------------------*/ @@ -2229,64 +2204,46 @@ preAssignParms (iCode * ic) 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].type = - regsAVR[R27_IDX].type = - regsAVR[R30_IDX].type = - regsAVR[R31_IDX].type = REG_GPR; - } - else - { - regsAVR[R26_IDX].type = - regsAVR[R27_IDX].type = - regsAVR[R30_IDX].type = - regsAVR[R31_IDX].type = REG_PTR; - } - - /* registers 0-1 / 24-25 used as scratch */ - regsAVR[R0_IDX].isFree = - 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; + 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].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; } - preAssignParms (ebbs[0]->sch); - } - else - { - - /* otherwise mark them as free scratch */ - for (i = R16_IDX; i <= R23_IDX; i++) - { - regsAVR[i].type = REG_SCR; - regsAVR[i].isFree = 1; + else { + 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; } - } - /* Y - is not allocated (it is the stack frame) */ - regsAVR[R28_IDX].isFree = - regsAVR[R28_IDX].isFree = 0; + /* registers 0-1 / 24-25 used as scratch */ + regsAVR[R0_IDX].isFree = + 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 */ + /* 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; + } + if (!currFunc->hasFcall) { + preAssignParms (ebbs[0]->sch); + } + /* Y - is not allocated (it is the stack frame) */ + regsAVR[R28_IDX].isFree = regsAVR[R28_IDX].isFree = 0; } /*-----------------------------------------------------------------*/ @@ -2295,68 +2252,66 @@ setDefaultRegs (eBBlock ** ebbs, int count) void avr_assignRegisters (eBBlock ** ebbs, int count) { - iCode *ic; - int i; - - setToNull ((void *) &_G.funcrUsed); - avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; - - /* change assignments this will remove some - live ranges reducing some register pressure */ - for (i = 0; i < count; i++) - packRegisters (ebbs[i]); - - if (options.dump_pack) - dumpEbbsToFileExt (".dumppack", ebbs, count); - - /* first determine for each live range the number of - registers & the type of registers required for each */ - regTypeNum (); - - /* setup the default registers */ - setDefaultRegs (ebbs, count); - - /* and serially allocate registers */ - serialRegAssign (ebbs, count); - - /* if stack was extended then tell the user */ - if (_G.stackExtend) - { -/* werror(W_TOOMANY_SPILS,"stack", */ -/* _G.stackExtend,currFunc->name,""); */ - _G.stackExtend = 0; - } - - if (_G.dataExtend) - { -/* werror(W_TOOMANY_SPILS,"data space", */ -/* _G.dataExtend,currFunc->name,""); */ - _G.dataExtend = 0; - } - - /* after that create the register mask - for each of the instruction */ - createRegMask (ebbs, count); - - /* redo that offsets for stacked automatic variables */ - redoStackOffsets (); - - if (options.dump_rassgn) - dumpEbbsToFileExt (".dumprassgn", ebbs, count); - - /* now get back the chain */ - ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); - - - genAVRCode (ic); -/* for (; ic ; ic = ic->next) */ -/* piCode(ic,stdout); */ - /* 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 */ - - return; + iCode *ic; + int i; + + setToNull ((void *) &_G.funcrUsed); + avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; + + /* change assignments this will remove some + live ranges reducing some register pressure */ + for (i = 0; i < count; i++) + packRegisters (ebbs[i]); + + if (options.dump_pack) + dumpEbbsToFileExt (DUMP_PACK, ebbs, count); + + /* first determine for each live range the number of + registers & the type of registers required for each */ + regTypeNum (); + + /* setup the default registers */ + setDefaultRegs (ebbs, count); + + /* and serially allocate registers */ + serialRegAssign (ebbs, count); + + /* if stack was extended then tell the user */ + if (_G.stackExtend) { + /* werror(W_TOOMANY_SPILS,"stack", */ + /* _G.stackExtend,currFunc->name,""); */ + _G.stackExtend = 0; + } + + if (_G.dataExtend) { + /* werror(W_TOOMANY_SPILS,"data space", */ + /* _G.dataExtend,currFunc->name,""); */ + _G.dataExtend = 0; + } + + /* after that create the register mask + for each of the instruction */ + createRegMask (ebbs, count); + + /* redo that offsets for stacked automatic variables */ + redoStackOffsets (); + + if (options.dump_rassgn) + dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + + /* now get back the chain */ + ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); + + + genAVRCode (ic); + /* for (; ic ; ic = ic->next) */ + /* piCode(ic,stdout); */ + /* 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 */ + + return; }