X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCopt.c;h=ce59ec5732292088a803bdeb40f8991717c793e8;hb=c37413e10ff08713c0689e1a3ef1b90d8ad343aa;hp=8b0902091af79002cb69bd6f7da1db7940aa8022;hpb=f3c58eecc1a1b343561a68d85a60b7999f7dd9d9;p=fw%2Fsdcc diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 8b090209..ce59ec57 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -324,6 +324,8 @@ found: } +extern operand *geniCodeRValue (operand *, bool); + /*-----------------------------------------------------------------*/ /* convilong - converts int or long mults or divs to fcalls */ /*-----------------------------------------------------------------*/ @@ -338,8 +340,34 @@ convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) int su; int bytesPushed=0; - remiCodeFromeBBlock (ebp, ic); - + // Easy special case which avoids function call: modulo by a literal power + // of two can be replaced by a bitwise AND. + if (op == '%' && isOperandLiteral(IC_RIGHT(ic))) + { + unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic))); + + // See if literal value is a power of 2. + while (litVal && !(litVal & 1)) + { + litVal >>= 1; + } + if (litVal) + { + // discard first high bit set. + litVal >>= 1; + } + + if (!litVal) + { + ic->op = BITWISEAND; + IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1); + return; + } + } + + remiCodeFromeBBlock (ebp, ic); + + /* depending on the type */ for (bwd = 0; bwd < 3; bwd++) { @@ -897,7 +925,9 @@ eBBlockFromiCode (iCode * ic) if (!options.lessPedantic) { // this is a good place to check missing return values if (currFunc) { - if (!IS_VOID(currFunc->etype)) { + // the user is on his own with naked functions... + if (!IS_VOID(currFunc->etype) + && !FUNC_ISNAKED(currFunc->type)) { eBBlock *bp; // make sure all predecessors of the last block end in a return for (bp=setFirstItem(ebbs[saveCount-1]->predList); @@ -939,8 +969,6 @@ eBBlockFromiCode (iCode * ic) setToNull ((void **) &graphEdges); ebbs = NULL; - currFunc=NULL; - return NULL; }