From: MaartenBrock Date: Sun, 5 Oct 2008 20:35:35 +0000 (+0000) Subject: * src/ds390/main.c (_ds390_genInitStartup): added X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=a24b75e7d87bf0a98c986653268766e8823967a8;p=fw%2Fsdcc * src/ds390/main.c (_ds390_genInitStartup): added * src/SDCCpeeph.c (getPatternVar): new, added, (labelInRange): fixed bug 2115959 * src/mcs51/peeph.def (rules 193.x to 198.x): check for labelInRange * src/SDCCicode.h: added newiTempOperand * src/SDCCcse.c (algebraicOpts): fixed bug for x*-1, added optimizations for 0/x and x/-1, see also patch 2142900 * support/regression/tests/onebyte.c (testMul): added test cases git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5248 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index f30c728c..7e0b8201 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-10-05 Maarten Brock + + * src/ds390/main.c (_ds390_genInitStartup): added + * src/SDCCpeeph.c (getPatternVar): new, added, + (labelInRange): fixed bug 2115959 + * src/mcs51/peeph.def (rules 193.x to 198.x): check for labelInRange + * src/SDCCicode.h: added newiTempOperand + * src/SDCCcse.c (algebraicOpts): fixed bug for x*-1, + added optimizations for 0/x and x/-1, see also patch 2142900 + * support/regression/tests/onebyte.c (testMul): added test cases + 2008-09-20 Borut Razem * src/pic16/glue.c: diff --git a/src/SDCCcse.c b/src/SDCCcse.c index dc92aced..1b43a428 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -1038,6 +1038,25 @@ algebraicOpts (iCode * ic, eBBlock * ebp) } if (rightValue == -1.0) { + /* '*' can have two unsigned chars as operands */ + /* and an unsigned int as result. */ + if (IS_INTEGRAL (operandType (IC_LEFT (ic)))) + { + if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) && + (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic))))) + { + operand * op; + iCode * newic; + /* Widen to int. */ + op = operandFromOperand (IC_RESULT (ic)); + op->type = TYPE; + setOperandType (op, INTTYPE); + newic = newiCode (CAST, op, IC_LEFT (ic)); + IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE); + addiCodeToeBBlock (ebp, newic, ic); + IC_LEFT (ic) = IC_RESULT (newic); + } + } /* convert x * -1 to -x */ ic->op = UNARYMINUS; IC_RIGHT (ic) = NULL; @@ -1054,20 +1073,59 @@ algebraicOpts (iCode * ic, eBBlock * ebp) IC_LEFT (ic) = NULL; IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic)); IC_RESULT (ic)->isaddr = 0; - break; + return; } - /* if this is a division then check if right */ - /* is one then change it to an assignment */ - if (IS_OP_LITERAL (IC_RIGHT (ic)) && - operandLitValue (IC_RIGHT (ic)) == 1.0) + /* if this is a division then check if left is zero */ + /* and right is not then change it to an assignment */ + if (IS_OP_LITERAL (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic)) && + (operandLitValue (IC_LEFT (ic)) == 0.0) && (operandLitValue (IC_RIGHT (ic)) != 0.0)) { - ic->op = '='; IC_RIGHT (ic) = IC_LEFT (ic); IC_LEFT (ic) = NULL; SET_RESULT_RIGHT (ic); return; } + /* if this is a division then check if right */ + /* is one then change it to an assignment */ + if (IS_OP_LITERAL (IC_RIGHT (ic))) + { + double rightValue = operandLitValue (IC_RIGHT (ic)); + if (rightValue == 1.0) + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + if (rightValue == -1.0) + { + /* '/' can have two unsigned chars as operands */ + /* and an unsigned int as result. */ + if (IS_INTEGRAL (operandType (IC_LEFT (ic)))) + { + if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) && + (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic))))) + { + operand * op; + iCode * newic; + /* Widen to int. */ + op = operandFromOperand (IC_RESULT (ic)); + op->type = TYPE; + setOperandType (op, INTTYPE); + newic = newiCode (CAST, op, IC_LEFT (ic)); + IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE); + addiCodeToeBBlock (ebp, newic, ic); + IC_LEFT (ic) = IC_RESULT (newic); + } + } + /* convert x / -1 to -x */ + ic->op = UNARYMINUS; + IC_RIGHT (ic) = NULL; + return; + } + } break; /* if both are the same for an comparison operators */ case EQ_OP: @@ -2187,7 +2245,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, mine and type is a pointer then delete pointerGets to take care of aliasing */ if (ASSIGNMENT (ic) && - IS_SYMOP (IC_RESULT (ic)) && + IS_SYMOP (IC_RESULT (ic)) && OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) && IS_PTR (operandType (IC_RESULT (ic)))) { diff --git a/src/SDCCicode.h b/src/SDCCicode.h index 48ef88fe..d2c69a1f 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -339,6 +339,7 @@ bool isOperandInDirSpace (operand *); bool isOperandInCodeSpace (operand *); operand *opFromOpWithDU (operand *, bitVect *, bitVect *); iCode *copyiCode (iCode *); +operand *newiTempOperand (sym_link *, char); operand *newiTempFromOp (operand *); iCode *getBuiltinParms (iCode *,int *, operand **); int isiCodeInFunctionCall (iCode *); diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index e413d499..5a7447ff 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -60,6 +60,37 @@ void peepRules2pCode(peepRule *); void pic16_peepRules2pCode(peepRule *); #endif +/*-----------------------------------------------------------------*/ +/* getPatternVar - finds a pattern variable */ +/*-----------------------------------------------------------------*/ + +static char* +getPatternVar (hTab *vars, char **cmdLine) +{ + int varNumber; + char *digitend; + + if (!cmdLine || !*cmdLine || !**cmdLine) + return NULL; /* no parameters given */ + + while (**cmdLine && ISCHARSPACE(**cmdLine)) + (*cmdLine)++; /* skip whitespace */ + + if (**cmdLine != '%') + goto error; + (*cmdLine)++; + if (!ISCHARDIGIT (**cmdLine)) + goto error; + varNumber = strtol (*cmdLine, &digitend, 10); + *cmdLine = digitend; + return hTabItemWithKey (vars, varNumber); + +error: + fprintf (stderr, + "*** internal error: peephole restriction malformed: %s\n", *cmdLine); + return NULL; +} + /*-----------------------------------------------------------------*/ /* pcDistance - finds a label backward or forward */ /*-----------------------------------------------------------------*/ @@ -135,40 +166,52 @@ FBYNAME (useAcallAjmp) } /*-----------------------------------------------------------------*/ -/* labelInRange - will check to see if label %5 is within range */ +/* labelInRange - will check to see if label is within range */ /*-----------------------------------------------------------------*/ FBYNAME (labelInRange) { - /* assumes that %5 pattern variable has the label name */ - char *lbl = hTabItemWithKey (vars, 5); int dist = 0; + char *lbl = getPatternVar (vars, &cmdLine); if (!lbl) - return FALSE; + { + /* If no parameters given, assume that %5 pattern variable + has the label name for backward compatibility */ + lbl = hTabItemWithKey (vars, 5); + } - /* Don't optimize jumps in a jump table; a more generic test */ - if (currPl->ic && currPl->ic->op == JUMPTABLE) + if (!lbl) return FALSE; - /* if the previous two instructions are "ljmp"s then don't - do it since it can be part of a jump table */ - if (currPl->prev && currPl->prev->prev && - strstr (currPl->prev->line, "ljmp") && - strstr (currPl->prev->prev->line, "ljmp")) - return FALSE; + do + { + /* Don't optimize jumps in a jump table; a more generic test */ + if (currPl->ic && currPl->ic->op == JUMPTABLE) + return FALSE; - /* calculate the label distance : the jump for reladdr can be - +/- 127 bytes, here I am assuming that an average 8051 - instruction is 2 bytes long, so if the label is more than - 63 intructions away, the label is considered out of range - for a relative jump. we could get more precise this will - suffice for now since it catches > 90% cases */ - dist = (pcDistance (currPl, lbl, TRUE) + - pcDistance (currPl, lbl, FALSE)); - -/* changed to 127, now that pcDistance return actual number of bytes */ - if (!dist || dist > 127) - return FALSE; + /* if the previous two instructions are "ljmp"s then don't + do it since it can be part of a jump table */ + if (currPl->prev && currPl->prev->prev && + strstr (currPl->prev->line, "ljmp") && + strstr (currPl->prev->prev->line, "ljmp")) + return FALSE; + + /* calculate the label distance : the jump for reladdr can be + +/- 127 bytes, here I am assuming that an average 8051 + instruction is 2 bytes long, so if the label is more than + 63 intructions away, the label is considered out of range + for a relative jump. we could get more precise this will + suffice for now since it catches > 90% cases */ + dist = (pcDistance (currPl, lbl, TRUE) + + pcDistance (currPl, lbl, FALSE)); + + /* changed to 127, now that pcDistance return actual number of bytes */ + if (!dist || dist > 127) + return FALSE; + + lbl = getPatternVar (vars, &cmdLine); + } + while (lbl); return TRUE; } @@ -1703,13 +1746,11 @@ bindVar (int key, char **s, hTab ** vtab) static bool matchLine (char *s, char *d, hTab ** vars) { - if (!s || !(*s)) return FALSE; while (*s && *d) { - /* skip white space in both */ while (ISCHARSPACE (*s)) s++; @@ -2423,7 +2464,7 @@ readFileIntoBuffer (char *fname) } } - /* if some charaters left over */ + /* if some characters left over */ if (nch) { lb[nch] = '\0'; diff --git a/src/ds390/main.c b/src/ds390/main.c index ba67a622..8b82663f 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -310,6 +310,44 @@ _ds390_genIVT (struct dbuf_s * oBuf, symbol ** interrupts, int maxInterrupts) return TRUE; } +static void +_ds390_genInitStartup (FILE *of) +{ + fprintf (of, "__sdcc_gsinit_startup:\n"); + /* if external stack is specified then the + higher order byte of the xdatalocation is + going into P2 and the lower order going into + spx */ + if (options.useXstack) + { + fprintf (of, "\tmov\tP2,#0x%02x\n", + (((unsigned int) options.xdata_loc) >> 8) & 0xff); + fprintf (of, "\tmov\t_spx,#0x%02x\n", + (unsigned int) options.xdata_loc & 0xff); + } + + // This should probably be a port option, but I'm being lazy. + // on the 400, the firmware boot loader gives us a valid stack + // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code) + if (!TARGET_IS_DS400) + { + /* initialise the stack pointer. JCF: aslink takes care of the location */ + fprintf (of, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */ + } + + fprintf (of, "\tlcall\t__sdcc_external_startup\n"); + fprintf (of, "\tmov\ta,dpl\n"); + fprintf (of, "\tjz\t__sdcc_init_data\n"); + fprintf (of, "\tljmp\t__sdcc_program_startup\n"); + fprintf (of, "__sdcc_init_data:\n"); + + // if the port can copy the XINIT segment to XISEG + if (port->genXINIT) + { + port->genXINIT(of); + } +} + /* Generate code to copy XINIT to XISEG */ static void _ds390_genXINIT (FILE * of) { fprintf (of, "; _ds390_genXINIT() start\n"); @@ -952,7 +990,7 @@ PORT ds390_port = NULL, /* no genAssemblerEnd */ _ds390_genIVT, _ds390_genXINIT, - NULL, /* genInitStartup */ + _ds390_genInitStartup, _ds390_reset_regparm, _ds390_regparm, NULL, @@ -1286,7 +1324,7 @@ PORT tininative_port = _tininative_genAssemblerEnd, _tininative_genIVT, NULL, - NULL, /* genInitStartup */ + _ds390_genInitStartup, _ds390_reset_regparm, _ds390_regparm, NULL, @@ -1539,7 +1577,7 @@ PORT ds400_port = NULL, /* no genAssemblerEnd */ _ds400_genIVT, _ds390_genXINIT, - NULL, /* genInitStartup */ + _ds390_genInitStartup, _ds390_reset_regparm, _ds390_regparm, NULL, diff --git a/src/mcs51/peeph.def b/src/mcs51/peeph.def index 6f18fc5a..d2206dcb 100644 --- a/src/mcs51/peeph.def +++ b/src/mcs51/peeph.def @@ -1743,7 +1743,7 @@ replace { cjne %13,%14,%8 sjmp %7 %3: -} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) +} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) replace { cjne %1,%2,%3 @@ -1767,7 +1767,7 @@ replace { cjne %13,%14,%8 sjmp %7 %3: -} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) +} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) replace { cjne @%1,%2,%3 @@ -1791,7 +1791,7 @@ replace { cjne @%1,%14,%8 sjmp %7 %3: -} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) +} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) replace { cjne %1,%2,%3 @@ -1809,7 +1809,7 @@ replace { cjne %13,%14,%8 sjmp %7 %3: -} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) +} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3) replace { jnz %3 @@ -1829,7 +1829,7 @@ replace { cjne %10,%11,%8 sjmp %7 %3: -} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) +} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) replace { cjne %1,%2,%3 @@ -1849,7 +1849,7 @@ replace { cjne %10,%11,%8 sjmp %7 %3: -} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) +} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) replace { cjne @%1,%2,%3 @@ -1869,7 +1869,7 @@ replace { cjne @%1,%11,%8 sjmp %7 %3: -} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) +} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) replace { cjne %1,%2,%3 @@ -1885,7 +1885,7 @@ replace { cjne %10,%11,%8 sjmp %7 %3: -} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) +} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2) replace { jnz %3 @@ -1901,7 +1901,7 @@ replace { cjne %5,%6,%8 sjmp %7 %3: -} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) +} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) replace { cjne %1,%2,%3 @@ -1917,7 +1917,7 @@ replace { cjne %5,%6,%8 sjmp %7 %3: -} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) +} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) replace { cjne @%1,%2,%3 @@ -1933,7 +1933,7 @@ replace { cjne @%1,%6,%8 sjmp %7 %3: -} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) +} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) replace { cjne %1,%2,%3 @@ -1947,7 +1947,7 @@ replace { cjne %5,%6,%8 sjmp %7 %3: -} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) +} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1) replace { cjne %1,%2,%3 @@ -1959,7 +1959,7 @@ replace { cjne %1,%2,%5 sjmp %4 %3: -} if labelRefCount(%3 1), labelRefCountChange(%3 -1) +} if labelInRange(%5), labelRefCount(%3 1), labelRefCountChange(%3 -1) replace { sjmp %1 diff --git a/support/regression/tests/onebyte.c b/support/regression/tests/onebyte.c index ea5d8147..d44e1b01 100644 --- a/support/regression/tests/onebyte.c +++ b/support/regression/tests/onebyte.c @@ -33,6 +33,9 @@ testMul (void) ucL = 128; cR = 1; ur8 = ucL * cR; ur8b = cR * ucL; ASSERT (ur8 == 128); ASSERT (ur8b == 128); ucL = 128; ucR = 5; r16 = ucL * ucR; r16b = ucR * ucL; ASSERT (r16 == 640); ASSERT (r16b == 640); ucL = 128; ucR = 1; ur8 = ucL * ucR; ur8b = ucR * ucL; ASSERT (ur8 == 128); ASSERT (ur8b == 128); + + ucL = 254; cR = -1; r16 = ucL * cR; ASSERT (r16 == -254); + cL = -128; cR = -1; r16 = cL * cR; ASSERT (r16 == 128); } void