X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fralloc.c;h=d4d3ad42160229eccca7d57a03a6a7e27a63adb7;hb=1e40748d55945b89eef6825943a29a31a05bb1f4;hp=5ec469bab7a86bc72b1b541145d1393d8ed58151;hpb=6401e66edb7cff7794e45b323eddab1a5de0e0af;p=fw%2Fsdcc diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 5ec469ba..d4d3ad42 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; @@ -61,26 +62,34 @@ int mcs51_ptrRegReq; /* one byte pointer register required */ 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 (); @@ -238,6 +247,15 @@ computeSpillable (iCode * ic) } +/*-----------------------------------------------------------------*/ +/* 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); +} + /*-----------------------------------------------------------------*/ /* noSpilLoc - return true if a variable has no spil location */ /*-----------------------------------------------------------------*/ @@ -257,7 +275,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) @@ -360,7 +378,7 @@ leastUsedLR (set * 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; @@ -505,13 +523,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 @@ -620,8 +645,6 @@ spillThis (symbol * sym) return; } - - /*-----------------------------------------------------------------*/ /* selectSpil - select a iTemp to spil : rather a simple procedure */ /*-----------------------------------------------------------------*/ @@ -635,10 +658,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); } @@ -660,7 +693,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))) @@ -697,7 +729,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++; @@ -707,7 +738,6 @@ 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; @@ -718,7 +748,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) used ofcourse */ if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic))) { - /* return a created spil location */ sym = createStackSpil (leastUsedLR (selectS)); sym->usl.spillLoc->allocreq++; @@ -865,7 +894,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() { @@ -886,7 +930,7 @@ static regs *getRegPtrNoSpil() } /*-----------------------------------------------------------------*/ -/* getRegGprNoSpil - get it cannot split */ +/* getRegGprNoSpil - get it cannot be spilt */ /*-----------------------------------------------------------------*/ static regs *getRegGprNoSpil() { @@ -905,6 +949,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 */ /*-----------------------------------------------------------------*/ @@ -920,6 +985,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 */ @@ -1053,8 +1141,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 @@ -1065,6 +1153,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) @@ -1169,21 +1262,11 @@ 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; - - // update the registers in use at the start of this icode - for (reg=0; regriu &= ~(1<riu |= (1<op == IPOP) @@ -1216,6 +1299,13 @@ serialRegAssign (eBBlock ** ebbs, int count) 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 it does not need or is spilt or is already assigned to registers or will not live beyond this instructions */ @@ -1232,11 +1322,20 @@ serialRegAssign (eBBlock ** ebbs, int count) 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 */ - willCS = willCauseSpill (sym->nRegs, sym->regType); spillable = computeSpillable (ic); if (sym->remat || (willCS && bitVectIsZero (spillable))) { spillThis (sym); @@ -1301,13 +1400,15 @@ serialRegAssign (eBBlock ** ebbs, int count) 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]) + if (right->regs[j] && (right->regType != REG_BIT)) sym->regs[j] = allocThisReg (right->regs[j]); } if (!sym->regs[j]) @@ -1318,6 +1419,7 @@ serialRegAssign (eBBlock ** ebbs, int count) this was spilt then break */ if (!sym->regs[j]) { + int i; for (i=0; i < sym->nRegs ; i++ ) sym->regs[i] = NULL; break; @@ -1440,11 +1542,13 @@ static void fillGaps() } } - D(printf("Atemping fillGaps on %s: [",sym->name)); + 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; @@ -1553,6 +1657,33 @@ static void fillGaps() } } +/*-----------------------------------------------------------------*/ +/* 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 */ /*-----------------------------------------------------------------*/ @@ -1579,8 +1710,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; @@ -1705,21 +1835,23 @@ 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; } @@ -1730,11 +1862,21 @@ rematStr (symbol * sym) 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; } @@ -1772,6 +1914,8 @@ 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; } @@ -1809,13 +1953,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 */ @@ -1973,6 +2116,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; @@ -2053,20 +2203,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } } } -#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 || @@ -2309,8 +2446,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 */ @@ -2341,16 +2476,16 @@ 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 */ @@ -2388,25 +2523,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 */ @@ -2428,11 +2563,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; @@ -2526,7 +2660,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; @@ -2556,7 +2690,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)) @@ -2610,7 +2744,6 @@ packRegsForAccUse (iCode * ic) getSize (operandType (IC_RESULT (ic))) > 1) return; - /* has only one definition */ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1) return; @@ -2638,7 +2771,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) && @@ -2680,10 +2813,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 */ @@ -2712,7 +2845,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) @@ -2812,6 +2945,47 @@ packRegisters (eBBlock ** ebpp, int blockno) for (ic = ebp->sch; ic; ic = ic->next) { + /* Fix for bug #979599: */ + /* P0 &= ~1; */ + + /* Look for two subsequent iCodes with */ + /* iTemp := _c; */ + /* _c = iTemp & op; */ + /* and replace them by */ + /* iTemp := _c; */ + /* _c = _c & op; */ + if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') && + ic->prev && + ic->prev->op == '=' && + IS_ITEMP (IC_LEFT (ic)) && + IC_LEFT (ic) == IC_RESULT (ic->prev) && + isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev))) + { + iCode* ic_prev = ic->prev; + symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev)); + + ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic)); + if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) + { + bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key); + if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */ + prev_result_sym->liveTo == ic->seq) + { + prev_result_sym->liveTo = ic_prev->seq; + } + } + bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key); + + bitVectSetBit (ic->rlive, IC_RESULT (ic)->key); + + if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) + { + bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key); + bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key); + remiCodeFromeBBlock (ebp, ic_prev); + hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL); + } + } /* if this is an itemp & result of an address of a true sym then mark this as rematerialisable */ @@ -2874,11 +3048,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)) @@ -2924,8 +3097,7 @@ packRegisters (eBBlock ** ebpp, int blockno) this is the only usage then mark the itemp as a conditional */ if ((IS_CONDITIONAL (ic) || - (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)) || - (POINTER_GET (ic) && getSize (operandType (IC_RESULT (ic))) <=1)) && + (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) && ic->next && ic->next->op == IFX && bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 && isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) && @@ -2964,6 +3136,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)) && @@ -2979,9 +3152,8 @@ packRegisters (eBBlock ** ebpp, int blockno) getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) packRegsForOneuse (ic, IC_LEFT (ic), ebp); - - /* if this is cast for intergral promotion then - check if only use of the definition of the + /* 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 the result of that arithmetic operation with this result and get rid of the cast */ @@ -3014,7 +3186,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)), @@ -3072,8 +3243,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; @@ -3081,7 +3254,16 @@ 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 */ @@ -3094,7 +3276,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 */ @@ -3142,7 +3324,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) if (options.dump_rassgn) { - dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpEbbsToFileExt (DUMP_RASSGN, ebbi); dumpLiveRanges (DUMP_LRANGE, liveRanges); }