X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmcs51%2Fralloc.c;h=589da661e9a0e78395cd4cbcc8cdd888bdfacbc8;hb=eae1bd2f705a2c61e143c539f8c4d1e9c2b4efe6;hp=63479c48c54d6ad0c9077552919237e3dbb45d18;hpb=f1ecc2b5a2acb09e8bbd167f8f0ff8b5f336c333;p=fw%2Fsdcc diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 63479c48..589da661 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -51,6 +51,7 @@ static struct bitVect *funcrUsed; /* registers used in a function */ int stackExtend; int dataExtend; + bitVect *allBitregs; /* all bit registers */ } _G; @@ -60,27 +61,34 @@ int mcs51_ptrRegReq; /* one byte pointer register required */ /* 8051 registers */ regs regs8051[] = { - - {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1}, - {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1}, - {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1}, - {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1}, - {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1}, - {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1}, - {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1}, - {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1}, - {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1}, - {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1}, + {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1}, + {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1}, + {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1}, + {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1}, + {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1}, + {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1}, + {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1}, + {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1}, + {REG_BIT, B0_IDX, REG_BIT, "b0", "b0", "bits", 0, 1}, + {REG_BIT, B1_IDX, REG_BIT, "b1", "b1", "bits", 1, 1}, + {REG_BIT, B2_IDX, REG_BIT, "b2", "b2", "bits", 2, 1}, + {REG_BIT, B3_IDX, REG_BIT, "b3", "b3", "bits", 3, 1}, + {REG_BIT, B4_IDX, REG_BIT, "b4", "b4", "bits", 4, 1}, + {REG_BIT, B5_IDX, REG_BIT, "b5", "b5", "bits", 5, 1}, + {REG_BIT, B6_IDX, REG_BIT, "b6", "b6", "bits", 6, 1}, + {REG_BIT, B7_IDX, REG_BIT, "b7", "b7", "bits", 7, 1}, + {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1}, + {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1}, {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1}, {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 1}, {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 1}, - {REG_CND, CND_IDX, REG_CND, "C", "psw", "0xd0", 0, 1}, - {0, DPL_IDX, 0, "dpl", "dpl", "0x82", 0, 0}, - {0, DPH_IDX, 0, "dph", "dph", "0x83", 0, 0}, - {0, B_IDX, 0, "b", "b", "0xf0", 0, 0}, - {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0}, + {REG_CND, CND_IDX, REG_CND, "C", "psw", "0xd0", 0, 1}, + {0, DPL_IDX, 0, "dpl", "dpl", "0x82", 0, 0}, + {0, DPH_IDX, 0, "dph", "dph", "0x83", 0, 0}, + {0, B_IDX, 0, "b", "b", "0xf0", 0, 0}, + {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0}, }; -int mcs51_nRegs = 17; +int mcs51_nRegs = 16; static void spillThis (symbol *); static void freeAllRegs (); @@ -94,27 +102,22 @@ allocReg (short type) for (i = 0; i < mcs51_nRegs; i++) { - /* if type is given as 0 then any free register will do */ - if (!type && - regs8051[i].isFree) + if (!type && regs8051[i].isFree) { regs8051[i].isFree = 0; if (currFunc) - currFunc->regsUsed = - bitVectSetBit (currFunc->regsUsed, i); + currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i); return ®s8051[i]; } /* other wise look for specific type of register */ - if (regs8051[i].isFree && - regs8051[i].type == type) + if (regs8051[i].isFree && regs8051[i].type == type) { regs8051[i].isFree = 0; if (currFunc) - currFunc->regsUsed = - bitVectSetBit (currFunc->regsUsed, i); + currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i); return ®s8051[i]; } } @@ -235,7 +238,15 @@ computeSpillable (iCode * ic) bitVectUnSetBit (spillable, ic->defKey); spillable = bitVectIntersect (spillable, _G.regAssigned); return spillable; +} +/*-----------------------------------------------------------------*/ +/* bitType - will return 1 if the symbol has type REG_BIT */ +/*-----------------------------------------------------------------*/ +static int +bitType (symbol * sym, eBBlock * ebp, iCode * ic) +{ + return (sym->regType == REG_BIT ? 1 : 0); } /*-----------------------------------------------------------------*/ @@ -257,7 +268,7 @@ hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) } /*-----------------------------------------------------------------*/ -/* directSpilLoc - will return 1 if the splilocation is in direct */ +/* directSpilLoc - will return 1 if the spillocation is in direct */ /*-----------------------------------------------------------------*/ static int directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) @@ -358,9 +369,8 @@ leastUsedLR (set * sset) for (; lsym; lsym = setNextItem (sset)) { - /* if usage is the same then prefer - the spill the smaller of the two */ + to spill the smaller of the two */ if (lsym->used == sym->used) if (getSize (lsym->type) < getSize (sym->type)) sym = lsym; @@ -368,7 +378,6 @@ leastUsedLR (set * sset) /* if less usage */ if (lsym->used < sym->used) sym = lsym; - } setToNull ((void *) &sset); @@ -431,8 +440,7 @@ spillLRWithPtrReg (symbol * forSym) regs *r0, *r1; int k; - if (!_G.regAssigned || - bitVectIsZero (_G.regAssigned)) + if (!_G.regAssigned || bitVectIsZero (_G.regAssigned)) return; r0 = mcs51_regWithIdx (R0_IDX); @@ -462,7 +470,6 @@ spillLRWithPtrReg (symbol * forSym) break; } } - } /*-----------------------------------------------------------------*/ @@ -505,13 +512,20 @@ createStackSpil (symbol * sym) /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); - SPEC_SCLS (sloc->etype) = S_DATA; + if (!IS_BIT (sloc->etype)) + { + SPEC_SCLS (sloc->etype) = S_DATA; + } + else if (SPEC_SCLS (sloc->etype) == S_SBIT) + { + SPEC_SCLS (sloc->etype) = S_BIT; + } SPEC_EXTR (sloc->etype) = 0; SPEC_STAT (sloc->etype) = 0; SPEC_VOLATILE(sloc->etype) = 0; SPEC_ABSA(sloc->etype) = 0; - /* we don't allow it to be allocated` + /* 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 @@ -553,6 +567,7 @@ createStackSpil (symbol * sym) /*-----------------------------------------------------------------*/ /* isSpiltOnStack - returns true if the spil location is on stack */ +/* or otherwise needs a pointer register */ /*-----------------------------------------------------------------*/ static bool isSpiltOnStack (symbol * sym) @@ -571,6 +586,9 @@ isSpiltOnStack (symbol * sym) if (!sym->usl.spillLoc) return FALSE; + if (sym->usl.spillLoc->onStack || sym->usl.spillLoc->iaccess) + return TRUE; + etype = getSpec (sym->usl.spillLoc->type); if (IN_STACK (etype)) return TRUE; @@ -599,20 +617,21 @@ spillThis (symbol * sym) bitVectUnSetBit (_G.totRegAssigned, sym->key); 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 spilt on stack then free up r0 & r1 if they could have been assigned to some LIVE ranges */ if (!mcs51_ptrRegReq && isSpiltOnStack (sym)) { - mcs51_ptrRegReq++; spillLRWithPtrReg (sym); + mcs51_ptrRegReq++; } if (sym->usl.spillLoc && !sym->remat) @@ -633,10 +652,20 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* get the spillable live ranges */ lrcs = computeSpillable (ic); - /* get all live ranges that are rematerizable */ - if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic))) + /* remove incompatible registers */ + if ((forSym->regType == REG_PTR) || (forSym->regType == REG_GPR)) { + selectS = liveRangesWith (lrcs, bitType, ebp, ic); + + for (sym = setFirstItem (selectS); sym; sym = setNextItem (selectS)) + { + bitVectUnSetBit (lrcs, sym->key); + } + } + /* get all live ranges that are rematerializable */ + if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic))) + { /* return the least used of these */ return leastUsedLR (selectS); } @@ -658,7 +687,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* 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))) @@ -673,8 +701,8 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) return sym; } - /* check if there are any live ranges that not - used in the remainder of the block */ + /* check if there are any live ranges that are + not used in the remainder of the block */ if (!_G.blockSpil && !isiCodeInFunctionCall (ic) && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) @@ -695,7 +723,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* 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++; @@ -705,18 +732,16 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* find live ranges with spillocation */ if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic))) { - sym = leastUsedLR (selectS); sym->usl.spillLoc->allocreq++; return sym; } /* couldn't find then we need to create a spil - location on the stack , for which one? the least - used ofcourse */ + 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++; @@ -727,7 +752,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) this one : happens very rarely but it does happen */ spillThis (forSym); return forSym; - } /*-----------------------------------------------------------------*/ @@ -760,8 +784,8 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) if they could have been assigned to as gprs */ if (!mcs51_ptrRegReq && isSpiltOnStack (ssym)) { - mcs51_ptrRegReq++; spillLRWithPtrReg (ssym); + mcs51_ptrRegReq++; } /* if this was a block level spil then insert push & pop @@ -782,7 +806,6 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) 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); @@ -863,7 +886,22 @@ tryAgain: } /*-----------------------------------------------------------------*/ -/* getRegPtrNoSpil - get it cannot split */ +/* getRegBit - will try for Bit if not spill this */ +/*-----------------------------------------------------------------*/ +static regs *getRegBit (symbol * sym) +{ + regs *reg; + + /* try for a bit type */ + if ((reg = allocReg (REG_BIT))) + return reg; + + spillThis (sym); + return 0; +} + +/*-----------------------------------------------------------------*/ +/* getRegPtrNoSpil - get it cannot be spilt */ /*-----------------------------------------------------------------*/ static regs *getRegPtrNoSpil() { @@ -884,11 +922,10 @@ static regs *getRegPtrNoSpil() } /*-----------------------------------------------------------------*/ -/* getRegGprNoSpil - get it cannot split */ +/* getRegGprNoSpil - get it cannot be spilt */ /*-----------------------------------------------------------------*/ static regs *getRegGprNoSpil() { - regs *reg; if ((reg = allocReg (REG_GPR))) return reg; @@ -903,6 +940,27 @@ static regs *getRegGprNoSpil() return 0; } +/*-----------------------------------------------------------------*/ +/* getRegBitNoSpil - get it cannot be spilt */ +/*-----------------------------------------------------------------*/ +static regs *getRegBitNoSpil() +{ + regs *reg; + + /* try for a ptr type */ + if ((reg = allocReg (REG_BIT))) + return reg; + + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; + + assert(0); + + /* just to make the compiler happy */ + return 0; +} + /*-----------------------------------------------------------------*/ /* symHasReg - symbol has a given register */ /*-----------------------------------------------------------------*/ @@ -918,6 +976,29 @@ symHasReg (symbol * sym, regs * reg) return FALSE; } +/*-----------------------------------------------------------------*/ +/* updateRegUsage - update the registers in use at the start of */ +/* this icode */ +/*-----------------------------------------------------------------*/ +static void +updateRegUsage (iCode * ic) +{ + int reg; + + for (reg=0; regriu &= ~(1<riu |= (1<= 8); + } + } +} + /*-----------------------------------------------------------------*/ /* deassignLRs - check the live to and if they have registers & are */ /* not spilt then free up the registers */ @@ -932,7 +1013,6 @@ deassignLRs (iCode * ic, eBBlock * ebp) for (sym = hTabFirstItem (liveRanges, &k); sym; sym = hTabNextItem (liveRanges, &k)) { - symbol *psym = NULL; /* if it does not end here */ if (sym->liveTo > ic->seq) @@ -993,9 +1073,8 @@ deassignLRs (iCode * ic, eBBlock * ebp) 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]; @@ -1051,8 +1130,8 @@ reassignLR (operand * op) static int willCauseSpill (int nr, int rt) { - /* first check if there are any avlb registers - of te type required */ + /* first check if there are any available registers + of the type required */ if (rt == REG_PTR) { /* special case for pointer type @@ -1063,6 +1142,11 @@ willCauseSpill (int nr, int rt) if (nFreeRegs (REG_GPR) >= nr) return 0; } + else if (rt == REG_BIT) + { + if (nFreeRegs (rt) >= nr) + return 0; + } else { if (mcs51_ptrRegReq) @@ -1159,7 +1243,6 @@ serialRegAssign (eBBlock ** ebbs, int count) /* for all blocks */ for (i = 0; i < count; i++) { - iCode *ic; if (ebbs[i]->noPath && @@ -1167,218 +1250,258 @@ serialRegAssign (eBBlock ** ebbs, int count) ebbs[i]->entryLabel != returnLabel)) continue; - /* of all instructions do */ + /* for all instructions do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { -#if 1 - int reg; + updateRegUsage(ic); + + /* if this is an ipop that means some live + range will have to be assigned again */ + if (ic->op == IPOP) + reassignLR (IC_LEFT (ic)); - // update the registers in use at the start of this icode - for (reg=0; regriu &= ~(1<riu |= (1<op != IFX && + IS_TRUE_SYMOP (IC_RESULT (ic))) + { + OP_SYMBOL (IC_RESULT (ic))->allocreq++; } -#endif - /* 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++; - - /* 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; - int ptrRegSet = 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; + /* 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; + } - /* 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; + /* 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; + int ptrRegSet = 0; + + /* Make sure any spill location is definitely allocated */ + if (sym->isspilt && !sym->remat && sym->usl.spillLoc && + !sym->usl.spillLoc->allocreq) + { + sym->usl.spillLoc->allocreq++; } - /* 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 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 the live range preceeds the point of definition - then ideally we must take into account registers that - have been allocated after sym->liveFrom but freed - before ic->seq. This is complicated, so spill this - symbol instead and let fillGaps handle the allocation. */ - if (sym->liveFrom < ic->seq) { - spillThis (sym); - continue; - } + /* do not try to spil bit registers as it won't work */ + if (sym->regType != REG_BIT) + { + /* 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; + } + + willCS = willCauseSpill (sym->nRegs, sym->regType); + /* if this is a bit variable then don't use precious registers + along with expensive bit-to-char conversions but just spill + it */ + if (willCS && SPEC_NOUN(sym->etype) == V_BIT) + { + 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 */ + spillable = computeSpillable (ic); + if (sym->remat || (willCS && bitVectIsZero (spillable))) + { + spillThis (sym); + continue; + } + + /* If the live range preceeds the point of definition + then ideally we must take into account registers that + have been allocated after sym->liveFrom but freed + before ic->seq. This is complicated, so spill this + symbol instead and let fillGaps handle the allocation. */ + if (sym->liveFrom < ic->seq) + { + spillThis (sym); + continue; + } - /* if it has a spillocation & is used less than - all other live ranges then spill this */ - if (willCS) { - if (sym->usl.spillLoc) { - symbol *leastUsed = leastUsedLR (liveRangesWith (spillable, - allLRs, ebbs[i], ic)); - if (leastUsed && leastUsed->used > sym->used) { - 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)) { - /* if this is local to this block then we might find a block spil */ - if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) { - 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)) + { + /* if this is local to this block then we might find a block spil */ + if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) + { + spillThis (sym); + continue; + } } } } } - /* if we need ptr regs for the right side - then mark it */ - if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic)) - && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) { - mcs51_ptrRegReq++; - ptrRegSet = 1; + /* if we need ptr regs for the right side + then mark it */ + if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic)) + && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) + { + mcs51_ptrRegReq++; + ptrRegSet = 1; } - if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) - && SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) { - mcs51_ptrRegReq++; - ptrRegSet = 1; + if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) + && SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) + { + mcs51_ptrRegReq++; + ptrRegSet = 1; } - if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) - && SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) { - mcs51_ptrRegReq++; - ptrRegSet = 1; + if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) + && SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) + { + mcs51_ptrRegReq++; + ptrRegSet = 1; } - /* else we assign registers to it */ - _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); - _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); - - for (j = 0; j < sym->nRegs; j++) { - sym->regs[j] = NULL; - if (sym->regType == REG_PTR) - sym->regs[j] = getRegPtr (ic, ebbs[i], sym); - else - { - if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) - { - symbol * right = OP_SYMBOL (IC_RIGHT (ic)); - - if (right->regs[j]) + /* else we assign registers to it */ + _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); + + for (j = 0; j < sym->nRegs; j++) + { + sym->regs[j] = NULL; + if (sym->regType == REG_PTR) + sym->regs[j] = getRegPtr (ic, ebbs[i], sym); + else if (sym->regType == REG_BIT) + sym->regs[j] = getRegBit (sym); + else + { + if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) + { + symbol * right = OP_SYMBOL (IC_RIGHT (ic)); + + if (right->regs[j] && (right->regType != REG_BIT)) sym->regs[j] = allocThisReg (right->regs[j]); - } - if (!sym->regs[j]) + } + if (!sym->regs[j]) sym->regs[j] = getRegGpr (ic, ebbs[i], sym); - } + } - /* if the allocation failed which means - this was spilt then break */ - if (!sym->regs[j]) - { - for (i=0; i < sym->nRegs ; i++ ) + /* if the allocation failed which means + this was spilt then break */ + if (!sym->regs[j]) + { + int i; + for (i=0; i < sym->nRegs ; i++ ) sym->regs[i] = NULL; - break; - } + break; + } } - if (!POINTER_SET(ic) && !POINTER_GET(ic)) { - /* 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) { - positionRegs (OP_SYMBOL (IC_RESULT (ic)), - OP_SYMBOL (IC_LEFT (ic))); + if (!POINTER_SET(ic) && !POINTER_GET(ic)) + { + /* 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) + { + positionRegs (OP_SYMBOL (IC_RESULT (ic)), + OP_SYMBOL (IC_LEFT (ic))); } - /* 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))); + /* 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))); } } - if (ptrRegSet) { - mcs51_ptrRegReq--; - ptrRegSet = 0; + if (ptrRegSet) + { + mcs51_ptrRegReq--; + ptrRegSet = 0; } - } } } - /* Check for and fix any problems with uninitialized operands */ - for (i = 0; i < count; i++) - { - iCode *ic; + /* Check for and fix any problems with uninitialized operands */ + for (i = 0; i < count; i++) + { + iCode *ic; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + { + continue; + } - if (ebbs[i]->noPath && - (ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel)) + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + if (SKIP_IC2 (ic)) continue; - for (ic = ebbs[i]->sch; ic; ic = ic->next) - { - if (SKIP_IC2 (ic)) + if (ic->op == IFX) + { + verifyRegsAssigned (IC_COND (ic), ic); continue; + } - if (ic->op == IFX) - { - verifyRegsAssigned (IC_COND (ic), ic); - continue; - } - - if (ic->op == JUMPTABLE) - { - verifyRegsAssigned (IC_JTCOND (ic), ic); - continue; - } + if (ic->op == JUMPTABLE) + { + verifyRegsAssigned (IC_JTCOND (ic), ic); + continue; + } - verifyRegsAssigned (IC_RESULT (ic), ic); - verifyRegsAssigned (IC_LEFT (ic), ic); - verifyRegsAssigned (IC_RIGHT (ic), ic); - } - } + verifyRegsAssigned (IC_RESULT (ic), ic); + verifyRegsAssigned (IC_LEFT (ic), ic); + verifyRegsAssigned (IC_RIGHT (ic), ic); + } + } } /*-----------------------------------------------------------------*/ @@ -1386,171 +1509,228 @@ serialRegAssign (eBBlock ** ebbs, int count) /*-----------------------------------------------------------------*/ static void fillGaps() { - symbol *sym =NULL; - int key =0; - int pass; - iCode *ic = NULL; + symbol *sym =NULL; + int key =0; + int pass; + iCode *ic = NULL; - if (getenv("DISABLE_FILL_GAPS")) return; + if (getenv("DISABLE_FILL_GAPS")) + return; - /* look for liveranges that were spilt by the allocator */ - for (sym = hTabFirstItem(liveRanges,&key) ; sym ; - sym = hTabNextItem(liveRanges,&key)) { + /* look for liveranges that were spilt by the allocator */ + for (sym = hTabFirstItem(liveRanges, &key) ; sym ; + sym = hTabNextItem(liveRanges, &key)) + { + int i; + int pdone = 0; - int i; - int pdone = 0; + if (!sym->spillA || !sym->clashes || sym->remat) + continue; - if (!sym->spillA || !sym->clashes || sym->remat) continue ; + /* if spilt in direct space the original rname is lost */ + if (sym->usl.spillLoc && (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype)))) + continue; + + /* find the liveRanges this one clashes with, that are + still assigned to registers & mark the registers as used*/ + for ( i = 0 ; i < sym->clashes->size ; i ++) + { + int k; + symbol *clr; - /* find the liveRanges this one clashes with, that are - still assigned to registers & mark the registers as used*/ - for ( i = 0 ; i < sym->clashes->size ; i ++) { - int k; - symbol *clr; + if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */ + bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ + continue ; - if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */ - bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ - continue ; + clr = hTabItemWithKey(liveRanges, i); + assert(clr); - clr = hTabItemWithKey(liveRanges,i); - assert(clr); + /* mark these registers as used */ + for (k = 0 ; k < clr->nRegs ; k++ ) + useReg(clr->regs[k]); + } - /* mark these registers as used */ - for (k = 0 ; k < clr->nRegs ; k++ ) - useReg(clr->regs[k]); + if (willCauseSpill(sym->nRegs, sym->regType)) + { + /* NOPE :( clear all registers & and continue */ + freeAllRegs(); + continue ; } - if (willCauseSpill(sym->nRegs,sym->regType)) { - /* NOPE :( clear all registers & and continue */ - freeAllRegs(); - continue ; + ic = NULL; + for (i = 0 ; i < sym->defs->size ; i++ ) + { + if (bitVectBitValue(sym->defs, i)) + { + if (!(ic = hTabItemWithKey(iCodehTab, i))) + continue; + if (ic->op == CAST) + break; + } } - ic = NULL; - for (i = 0 ; i < sym->defs->size ; i++ ) - { - if (bitVectBitValue(sym->defs,i)) - { - if (!(ic = hTabItemWithKey(iCodehTab,i))) - continue; - if (ic->op == CAST) - break; - } - } + D(printf("Attempting fillGaps on %s: [", sym->name)); + /* THERE IS HOPE !!!! */ + for (i=0; i < sym->nRegs ; i++ ) + { + if (sym->regType == REG_PTR) + sym->regs[i] = getRegPtrNoSpil (); + else if (sym->regType == REG_BIT) + sym->regs[i] = getRegBitNoSpil (); + else + { + sym->regs[i] = NULL; + if (ic && ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) + { + symbol * right = OP_SYMBOL (IC_RIGHT (ic)); - D(printf("Atemping fillGaps on %s: [",sym->name)); - /* THERE IS HOPE !!!! */ - for (i=0; i < sym->nRegs ; i++ ) { - if (sym->regType == REG_PTR) - sym->regs[i] = getRegPtrNoSpil (); - else - { - sym->regs[i] = NULL; - if (ic && ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) - { - symbol * right = OP_SYMBOL (IC_RIGHT (ic)); - - if (right->regs[i]) - sym->regs[i] = allocThisReg (right->regs[i]); - } - if (!sym->regs[i]) - sym->regs[i] = getRegGprNoSpil (); - } - D(printf("%s ", sym->regs[i]->name)); - } - D(printf("]\n")); - - /* For all its definitions check if the registers - allocated needs positioning NOTE: we can position - only ONCE if more than One positioning required - then give up. - We may need to perform the checks twice; once to - position the registers as needed, the second to - verify any register repositioning is still - compatible. - */ - sym->isspilt = 0; - for (pass=0; pass<2; pass++) { - D(printf(" checking definitions\n")); - for (i = 0 ; i < sym->defs->size ; i++ ) { - if (bitVectBitValue(sym->defs,i)) { - if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; - D(printf(" ic->seq = %d\n", ic->seq)); - if (SKIP_IC(ic)) continue; - assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */ - /* if left is assigned to registers */ - if (IS_SYMOP(IC_LEFT(ic))) - { - D(printf(" left = ")); - D(printOperand(IC_LEFT(ic),NULL)); - } - if (IS_SYMOP(IC_LEFT(ic)) && - bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) { - pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0); + if (right->regs[i]) + sym->regs[i] = allocThisReg (right->regs[i]); + } + if (!sym->regs[i]) + sym->regs[i] = getRegGprNoSpil (); + } + D(printf("%s ", sym->regs[i]->name)); + } + D(printf("]\n")); + + /* For all its definitions check if the registers + allocated needs positioning NOTE: we can position + only ONCE if more than One positioning required + then give up. + We may need to perform the checks twice; once to + position the registers as needed, the second to + verify any register repositioning is still + compatible. + */ + sym->isspilt = 0; + for (pass=0; pass<2; pass++) + { + D(printf(" checking definitions\n")); + for (i = 0 ; i < sym->defs->size ; i++ ) + { + if (bitVectBitValue(sym->defs,i)) + { + if (!(ic = hTabItemWithKey(iCodehTab,i))) + continue; + D(printf(" ic->seq = %d\n", ic->seq)); + if (SKIP_IC(ic)) + continue; + assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */ + /* if left is assigned to registers */ + if (IS_SYMOP(IC_LEFT(ic))) + { + D(printf(" left = ")); + D(printOperand(IC_LEFT(ic),NULL)); } - if (IS_SYMOP(IC_RIGHT(ic))) - { - D(printf(" right = ")); - D(printOperand(IC_RIGHT(ic),NULL)); - } - if (IS_SYMOP(IC_RIGHT(ic)) && - bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) { - pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0); + if (IS_SYMOP(IC_LEFT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) + { + pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0); + } + if (IS_SYMOP(IC_RIGHT(ic))) + { + D(printf(" right = ")); + D(printOperand(IC_RIGHT(ic),NULL)); } - D(printf(" pdone = %d\n", pdone)); - if (pdone > 1) break; + if (IS_SYMOP(IC_RIGHT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) + { + pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0); + } + D(printf(" pdone = %d\n", pdone)); + if (pdone > 1) + break; } } - D(printf(" checking uses\n")); - for (i = 0 ; i < sym->uses->size ; i++ ) { - if (bitVectBitValue(sym->uses,i)) { - iCode *ic; - if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; - D(printf(" ic->seq = %d\n", ic->seq)); - if (SKIP_IC(ic)) continue; - if (POINTER_SET(ic) || POINTER_GET(ic)) continue ; - - /* if result is assigned to registers */ - if (IS_SYMOP(IC_RESULT(ic))) - { - D(printf(" result = ")); - D(printOperand(IC_RESULT(ic),NULL)); - } - if (IS_SYMOP(IC_RESULT(ic)) && - bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) { - pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0); + D(printf(" checking uses\n")); + for (i = 0 ; i < sym->uses->size ; i++ ) + { + if (bitVectBitValue(sym->uses,i)) + { + iCode *ic; + if (!(ic = hTabItemWithKey(iCodehTab, i))) + continue; + D(printf(" ic->seq = %d\n", ic->seq)); + if (SKIP_IC(ic)) + continue; + if (POINTER_SET(ic) || POINTER_GET(ic)) + continue; + + /* if result is assigned to registers */ + if (IS_SYMOP (IC_RESULT (ic))) + { + D(printf(" result = ")); + D(printOperand(IC_RESULT (ic), NULL)); + } + if (IS_SYMOP (IC_RESULT (ic)) && + bitVectBitValue(_G.totRegAssigned, OP_SYMBOL (IC_RESULT (ic))->key)) + { + pdone += (positionRegs(sym, OP_SYMBOL (IC_RESULT (ic)))>0); } - D(printf(" pdone = %d\n", pdone)); - if (pdone > 1) break; + D(printf(" pdone = %d\n", pdone)); + if (pdone > 1) + break; } } - if (pdone == 0) break; /* second pass only if regs repositioned */ - if (pdone > 1) break; + if (pdone == 0) + break; /* second pass only if regs repositioned */ + if (pdone > 1) + break; } - D(printf(" sym->regs = [")); - for (i=0; i < sym->nRegs ; i++ ) - D(printf("%s ", sym->regs[i]->name)); - D(printf("]\n")); - /* had to position more than once GIVE UP */ - if (pdone > 1) { - /* UNDO all the changes we made to try this */ - sym->isspilt = 1; - for (i=0; i < sym->nRegs ; i++ ) { - sym->regs[i] = NULL; + D(printf(" sym->regs = [")); + for (i=0; i < sym->nRegs ; i++ ) + D(printf("%s ", sym->regs[i]->name)); + D(printf("]\n")); + /* had to position more than once GIVE UP */ + if (pdone > 1) + { + /* UNDO all the changes we made to try this */ + sym->isspilt = 1; + for (i=0; i < sym->nRegs ; i++ ) + { + sym->regs[i] = NULL; } - freeAllRegs(); - D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN")); - continue ; + freeAllRegs(); + D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN")); + continue ; } - D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN")); + D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN")); - _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key); - sym->isspilt = sym->spillA = 0 ; - sym->usl.spillLoc->allocreq--; - freeAllRegs(); + _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key); + sym->isspilt = sym->spillA = 0 ; + sym->usl.spillLoc->allocreq--; + freeAllRegs(); } } +/*-----------------------------------------------------------------*/ +/* findAllBitregs :- returns bit vector of all bit registers */ +/*-----------------------------------------------------------------*/ +static bitVect * +findAllBitregs (void) +{ + bitVect *rmask = newBitVect (mcs51_nRegs); + int j; + + for (j = 0; j < mcs51_nRegs; j++) + { + if (regs8051[j].type == REG_BIT) + rmask = bitVectSetBit (rmask, regs8051[j].rIdx); + } + + return rmask; +} + +/*-----------------------------------------------------------------*/ +/* mcs51_allBitregs :- returns bit vector of all bit registers */ +/*-----------------------------------------------------------------*/ +bitVect * +mcs51_allBitregs (void) +{ + return _G.allBitregs; +} + /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ @@ -1577,8 +1757,7 @@ mcs51_rUmaskForOp (operand * op) for (j = 0; j < sym->nRegs; j++) { if (sym->regs[j]) /* EEP - debug */ - rumask = bitVectSetBit (rumask, - sym->regs[j]->rIdx); + rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx); } return rumask; @@ -1595,33 +1774,26 @@ regsUsedIniCode (iCode * ic) /* do the special cases first */ if (ic->op == IFX) { - rmask = bitVectUnion (rmask, - mcs51_rUmaskForOp (IC_COND (ic))); + rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_COND (ic))); goto ret; } /* for the jumptable */ if (ic->op == JUMPTABLE) { - rmask = bitVectUnion (rmask, - mcs51_rUmaskForOp (IC_JTCOND (ic))); - + rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_JTCOND (ic))); goto ret; } /* of all other cases */ if (IC_LEFT (ic)) - rmask = bitVectUnion (rmask, - mcs51_rUmaskForOp (IC_LEFT (ic))); - + rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_LEFT (ic))); if (IC_RIGHT (ic)) - rmask = bitVectUnion (rmask, - mcs51_rUmaskForOp (IC_RIGHT (ic))); + rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_RIGHT (ic))); if (IC_RESULT (ic)) - rmask = bitVectUnion (rmask, - mcs51_rUmaskForOp (IC_RESULT (ic))); + rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_RESULT (ic))); ret: return rmask; @@ -1648,7 +1820,6 @@ createRegMask (eBBlock ** ebbs, int count) /* for all instructions */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { - int j; if (SKIP_IC2 (ic) || !ic->rlive) @@ -1690,8 +1861,7 @@ createRegMask (eBBlock ** ebbs, int count) /* 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); + ic->rMask = bitVectSetBit (ic->rMask, sym->regs[k]->rIdx); } } } @@ -1703,36 +1873,49 @@ createRegMask (eBBlock ** ebbs, int count) static char * rematStr (symbol * sym) { - char *s = buffer; iCode *ic = sym->rematiCode; - - *s = 0; + int offset = 0; while (1) { + /* if plus adjust offset to right hand side */ + if (ic->op == '+') + { + offset += (int) operandLitValue (IC_RIGHT (ic)); + ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode; + continue; + } - /* if plus or minus print the right hand side */ - if (ic->op == '+' || ic->op == '-') + /* if minus adjust offset to right hand side */ + if (ic->op == '-') { - SNPRINTF (s, sizeof(buffer) - strlen(buffer), - "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)), - ic->op); - s += strlen (s); + offset -= (int) operandLitValue (IC_RIGHT (ic)); ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode; continue; } /* cast then continue */ - if (IS_CAST_ICODE(ic)) { + if (IS_CAST_ICODE(ic)) + { ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode; continue; - } + } /* we reached the end */ - SNPRINTF (s, sizeof(buffer) - strlen(buffer), - "%s", OP_SYMBOL (IC_LEFT (ic))->rname); break; } + if (offset) + { + SNPRINTF (buffer, sizeof(buffer), + "(%s %c 0x%04x)", + OP_SYMBOL (IC_LEFT (ic))->rname, + offset >= 0 ? '+' : '-', + abs (offset) & 0xffff); + } + else + { + strncpyz (buffer, OP_SYMBOL (IC_LEFT (ic))->rname, sizeof(buffer)); + } return buffer; } @@ -1750,16 +1933,13 @@ regTypeNum (eBBlock *ebbs) 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; @@ -1770,19 +1950,19 @@ regTypeNum (eBBlock *ebbs) { if (IS_AGGREGATE (sym->type) || sym->isptr) sym->type = aggrToPtr (sym->type, FALSE); + else if (IS_BIT(sym->type)) + sym->regType = REG_CND; continue; } /* if the symbol has only one definition & that definition is a get_pointer */ if (bitVectnBitsOn (sym->defs) == 1 && - (ic = hTabItemWithKey (iCodehTab, - bitVectFirstBit (sym->defs))) && + (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs))) && POINTER_GET (ic) && !IS_BITVAR (sym->etype) && (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) { - if (ptrPseudoSymSafe (sym, ic)) { ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic)))); @@ -1791,7 +1971,6 @@ regTypeNum (eBBlock *ebbs) /* if in data space or idata space then try to allocate pointer register */ - } /* if not then we require registers */ @@ -1807,13 +1986,12 @@ regTypeNum (eBBlock *ebbs) } /* determine the type of register required */ - if (sym->nRegs == 1 && - IS_PTR (sym->type) && - sym->uptr) + if (sym->nRegs == 1 && IS_PTR (sym->type) && sym->uptr) sym->regType = REG_PTR; + else if (IS_BIT(sym->type)) + sym->regType = REG_BIT; else sym->regType = REG_GPR; - } else /* for the first run we don't provide */ @@ -1821,7 +1999,6 @@ regTypeNum (eBBlock *ebbs) /* see how things go */ sym->nRegs = 0; } - } /*-----------------------------------------------------------------*/ @@ -1948,9 +2125,10 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) /* if the true symbol is defined in far space or on stack then we should not since this will increase register pressure */ - if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) { - return 0; - } + if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) + { + 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 @@ -1971,6 +2149,13 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } } + /* Don't move an assignment out of a critical block */ + if (dic->op == CRITICAL) + { + dic = NULL; + break; + } + if (SKIP_IC2 (dic)) continue; @@ -2030,7 +2215,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) dic = NULL; break; } - } } @@ -2049,28 +2233,14 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) { return 0; } - } - } -#if 0 - /* if assignment then check that right is not a bit */ - if (ASSIGNMENT (dic) && !POINTER_SET (dic)) - { - sym_link *etype = operandType (IC_RIGHT (dic)); - if (IS_BITFIELD (etype)) - { - /* if result is a bit too then it's ok */ - etype = operandType (IC_RESULT (dic)); - if (!IS_BITFIELD (etype)) - return 0; } } -#endif + /* 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))) || @@ -2107,9 +2277,9 @@ pack: } remiCodeFromeBBlock (ebp, ic); - bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + bitVectUnSetBit(OP_DEFS (IC_RESULT (ic)), ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + OP_DEFS(IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); return 1; } @@ -2132,7 +2302,6 @@ findAssignToSym (operand * op, iCode * ic) for (dic = ic->prev; dic; dic = dic->prev) { - /* if definition by assignment */ if (dic->op == '=' && !POINTER_SET (dic) && @@ -2193,7 +2362,6 @@ findAssignToSym (operand * op, iCode * ic) 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) @@ -2307,8 +2475,6 @@ packRegsForSupport (iCode * ic, eBBlock * ebp) return 0; } -#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) - /*-----------------------------------------------------------------*/ /* packRegsForOneuse : - will reduce some registers for single Use */ @@ -2339,34 +2505,34 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) if (ic->op == SEND && ic->argreg != 1) return NULL; - /* this routine will mark the a symbol as used in one - instruction use only && if the defintion is local + /* this routine will mark the symbol as used in one + instruction use only && if the definition is local (ie. within the basic block) && has only one definition && - that definiion is either a return value from a + that definition is either a return value from a function or does not contain any variables in far space */ if (bitVectnBitsOn (OP_USES (op)) > 1) return NULL; - /* if it has only one defintion */ + /* if it has only one definition */ if (bitVectnBitsOn (OP_DEFS (op)) > 1) return NULL; /* has more than one definition */ /* get that definition */ - if (!(dic = - hTabItemWithKey (iCodehTab, - bitVectFirstBit (OP_DEFS (op))))) + if (!(dic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (op))))) return NULL; /* if that only usage is a cast */ - if (dic->op == CAST) { - /* to a bigger type */ - if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > - getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) { - /* than we can not, since we cannot predict the usage of b & acc */ - return NULL; + if (dic->op == CAST) + { + /* to a bigger type */ + if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > + getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) + { + /* then we can not, since we cannot predict the usage of b & acc */ + return NULL; + } } - } /* found the definition now check if it is local */ if (dic->seq < ebp->fSeq || @@ -2386,25 +2552,25 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) } else { - /* otherwise check that the definition does - not contain any symbols in far space */ - if (isOperandInFarSpace (IC_LEFT (dic)) || - isOperandInFarSpace (IC_RIGHT (dic)) || - IS_OP_RUONLY (IC_LEFT (ic)) || - IS_OP_RUONLY (IC_RIGHT (ic))) - { - return NULL; - } + /* otherwise check that the definition does + not contain any symbols in far space */ + if (isOperandInFarSpace (IC_LEFT (dic)) || + isOperandInFarSpace (IC_RIGHT (dic)) || + IS_OP_RUONLY (IC_LEFT (ic)) || + 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 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 (POINTER_GET (dic) && + !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) + return NULL; } /* Make sure no overlapping liverange is already assigned to DPTR */ @@ -2426,11 +2592,10 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) sic = dic; - /* also make sure the intervenening instructions - don't have any thing in far space */ + /* also make sure the intervening instructions + don't have anything in far space */ for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next) { - /* if there is an intervening function call then no */ if (dic->op == CALL || dic->op == PCALL) return NULL; @@ -2469,9 +2634,10 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* if left or right or result is on stack */ if (isOperandOnStack(IC_LEFT(dic)) || isOperandOnStack(IC_RIGHT(dic)) || - isOperandOnStack(IC_RESULT(dic))) { - return NULL; - } + isOperandOnStack(IC_RESULT(dic))) + { + return NULL; + } } OP_SYMBOL (op)->ruonly = 1; @@ -2524,7 +2690,7 @@ bool isCommutativeOp(unsigned int op) /* operandUsesAcc - determines whether the code generated for this */ /* operand will have to use the accumulator */ /*-----------------------------------------------------------------*/ -bool operandUsesAcc(operand *op) +bool operandUsesAcc(operand *op, bool allowBitspace) { if (!op) return FALSE; @@ -2554,7 +2720,7 @@ bool operandUsesAcc(operand *op) if (sym->iaccess && symspace->paged) return TRUE; /* must fetch paged indirect sym via accumulator */ - if (IN_BITSPACE(symspace)) + if (!allowBitspace && IN_BITSPACE(symspace)) return TRUE; /* fetching bit vars uses the accumulator */ if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) @@ -2573,20 +2739,19 @@ packRegsForAccUse (iCode * ic) iCode *uic; /* if this is an aggregate, e.g. a one byte char array */ - if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) { + if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) return; - } /* if we are calling a reentrant function that has stack parameters */ if (ic->op == CALL && - IFFUNC_ISREENT(operandType(IC_LEFT(ic))) && - FUNC_HASSTACKPARM(operandType(IC_LEFT(ic)))) - return; + IFFUNC_ISREENT(operandType(IC_LEFT(ic))) && + FUNC_HASSTACKPARM(operandType(IC_LEFT(ic)))) + return; if (ic->op == PCALL && - IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) && - FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next)) - return; + IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) && + FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next)) + return; /* if + or - then it has to be one byte result */ if ((ic->op == '+' || ic->op == '-') @@ -2608,7 +2773,6 @@ packRegsForAccUse (iCode * ic) getSize (operandType (IC_RESULT (ic))) > 1) return; - /* has only one definition */ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1) return; @@ -2636,7 +2800,7 @@ packRegsForAccUse (iCode * ic) getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1) return; - /* if the usage is not is an assignment + /* if the usage is not an assignment or an arithmetic / bitwise / shift operation then not */ if (uic->op != '=' && !IS_ARITHMETIC_OP (uic) && @@ -2678,10 +2842,10 @@ packRegsForAccUse (iCode * ic) goto accuse; /* if the other operand uses the accumulator then we cannot */ - if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key && - operandUsesAcc(IC_RIGHT(uic))) || + if ( (IC_LEFT (uic)->key == IC_RESULT (ic)->key && + operandUsesAcc (IC_RIGHT (uic), IS_BIT (operandType (IC_LEFT (uic))))) || (IC_RIGHT(uic)->key == IC_RESULT(ic)->key && - operandUsesAcc(IC_LEFT(uic))) ) + operandUsesAcc (IC_LEFT (uic), IS_BIT (operandType (IC_RIGHT (uic))))) ) return; /* make sure this is on the left side if not commutative */ @@ -2710,7 +2874,7 @@ accuse: } /*-----------------------------------------------------------------*/ -/* packForPush - hueristics to reduce iCode for pushing */ +/* packForPush - heuristics to reduce iCode for pushing */ /*-----------------------------------------------------------------*/ static void packForPush (iCode * ic, eBBlock ** ebpp, int blockno) @@ -2735,41 +2899,47 @@ packForPush (iCode * ic, eBBlock ** ebpp, int blockno) if (dic->op != '=' || POINTER_SET (dic)) return; - if (dic->seq < ebp->fSeq) { // Evelyn did this - int i; - for (i=0; iseq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) { - ebp=ebpp[i]; - break; - } + if (dic->seq < ebp->fSeq) // Evelyn did this + { + int i; + for (i=0; iseq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) + { + ebp=ebpp[i]; + break; + } + } + wassert (i!=blockno); // no way to recover from here } - wassert (i!=blockno); // no way to recover from here - } - if (IS_SYMOP(IC_RIGHT(dic))) { - /* make sure the right side does not have any definitions - inbetween */ - dbv = OP_DEFS(IC_RIGHT(dic)); - for (lic = ic; lic && lic != dic ; lic = lic->prev) { - if (bitVectBitValue(dbv,lic->key)) - return ; - } - /* make sure they have the same type */ - if (IS_SPEC(operandType(IC_LEFT(ic)))) + if (IS_SYMOP(IC_RIGHT(dic))) { - sym_link *itype=operandType(IC_LEFT(ic)); - sym_link *ditype=operandType(IC_RIGHT(dic)); + /* make sure the right side does not have any definitions + inbetween */ + dbv = OP_DEFS(IC_RIGHT(dic)); + for (lic = ic; lic && lic != dic ; lic = lic->prev) + { + if (bitVectBitValue(dbv,lic->key)) + return ; + } + /* make sure they have the same type */ + if (IS_SPEC(operandType(IC_LEFT(ic)))) + { + sym_link *itype=operandType(IC_LEFT(ic)); + sym_link *ditype=operandType(IC_RIGHT(dic)); - if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) || - SPEC_LONG(itype)!=SPEC_LONG(ditype)) - return; - } - /* extend the live range of replaced operand if needed */ - if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) { - OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq; + if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) || + SPEC_LONG(itype)!=SPEC_LONG(ditype)) + return; + } + /* extend the live range of replaced operand if needed */ + if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) + { + OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq; + } + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); } - bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); - } /* we now we know that it has one & only one def & use and the that the definition is an assignment */ @@ -2789,12 +2959,12 @@ packRegisters (eBBlock ** ebpp, int blockno) int change = 0; eBBlock *ebp=ebpp[blockno]; - while (1) + do { change = 0; /* look for assignments of the form */ - /* iTempNN = TRueSym (someoperation) SomeOperand */ + /* iTempNN = TrueSym (someoperation) SomeOperand */ /* .... */ /* TrueSym := iTempNN:1 */ for (ic = ebp->sch; ic; ic = ic->next) @@ -2803,10 +2973,8 @@ packRegisters (eBBlock ** ebpp, int blockno) if (ic->op == '=' && !POINTER_SET (ic)) change += packRegsForAssign (ic, ebp); } - - if (!change) - break; } + while (change); for (ic = ebp->sch; ic; ic = ic->next) { @@ -2872,6 +3040,7 @@ packRegisters (eBBlock ** ebpp, int blockno) IS_SYMOP (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic))->remat && !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) && + !isOperandGlobal(IC_RESULT(ic)) && /* due to bug 1618050 */ bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) { OP_SYMBOL (IC_RESULT (ic))->remat = @@ -2913,11 +3082,10 @@ packRegisters (eBBlock ** ebpp, int blockno) } /* mark the pointer usages */ - if (POINTER_SET (ic)) + if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic))) OP_SYMBOL (IC_RESULT (ic))->uptr = 1; - if (POINTER_GET (ic) && - IS_SYMOP(IC_LEFT (ic))) + if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))) OP_SYMBOL (IC_LEFT (ic))->uptr = 1; if (!SKIP_IC2 (ic)) @@ -3002,6 +3170,7 @@ packRegisters (eBBlock ** ebpp, int blockno) /* if pointer set & left has a size more than one and right is not in far space */ if (POINTER_SET (ic) && + IS_SYMOP (IC_RESULT (ic)) && !isOperandInFarSpace (IC_RIGHT (ic)) && !OP_SYMBOL (IC_RESULT (ic))->remat && !IS_OP_RUONLY (IC_RIGHT (ic)) && @@ -3017,7 +3186,6 @@ packRegisters (eBBlock ** ebpp, int blockno) getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) packRegsForOneuse (ic, IC_LEFT (ic), ebp); - /* if this is a cast for intergral promotion then check if it's the only use of the definition of the operand being casted/ if yes then replace @@ -3052,7 +3220,6 @@ packRegisters (eBBlock ** ebpp, int blockno) } 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)), @@ -3084,11 +3251,10 @@ packRegisters (eBBlock ** ebpp, int blockno) packForPush (ic, ebpp, blockno); } - /* pack registers for accumulator use, when the result of an arithmetic or bit wise operation has only one use, that use is immediately following - the defintion and the using iCode has only one + the definition and the using iCode has only one operand or has two operands but one is literal & the result of that operation is not on stack then we can leave the result of this operation in acc:b @@ -3101,8 +3267,9 @@ packRegisters (eBBlock ** ebpp, int blockno) ) && IS_ITEMP (IC_RESULT (ic)) && getSize (operandType (IC_RESULT (ic))) <= 2) - - packRegsForAccUse (ic); + { + packRegsForAccUse (ic); + } } } @@ -3110,8 +3277,10 @@ packRegisters (eBBlock ** ebpp, int blockno) /* assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ void -mcs51_assignRegisters (eBBlock ** ebbs, int count) +mcs51_assignRegisters (ebbIndex * ebbi) { + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; iCode *ic; int i; @@ -3119,7 +3288,15 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) setToNull ((void *) &_G.regAssigned); setToNull ((void *) &_G.totRegAssigned); mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; - mcs51_nRegs = 8; + if ((currFunc && IFFUNC_ISREENT (currFunc->type)) || options.stackAuto) + { + mcs51_nRegs = 16; + } + else + { + mcs51_nRegs = 8; + } + _G.allBitregs = findAllBitregs (); /* change assignments this will remove some live ranges reducing some register pressure */ @@ -3132,7 +3309,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) recomputeLiveRanges (ebbs, count); if (options.dump_pack) - dumpEbbsToFileExt (DUMP_PACK, ebbs, count); + dumpEbbsToFileExt (DUMP_PACK, ebbi); /* first determine for each live range the number of registers & the type of registers required for each */ @@ -3180,7 +3357,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) if (options.dump_rassgn) { - dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpEbbsToFileExt (DUMP_RASSGN, ebbi); dumpLiveRanges (DUMP_LRANGE, liveRanges); }