From 6e551299320c9c4b6771a4bee0e45a95903753d8 Mon Sep 17 00:00:00 2001 From: bernhardheld Date: Sat, 13 Sep 2003 21:54:29 +0000 Subject: [PATCH] * src/SDCCval.c (cheapestVal): reenabled to reduce int to char * src/SDCCval.c (constVal): added reduction from int to char * src/SDCCval.c (valMult, valDiv): fixed sign handling * src/SDCCval.c (valShift): fixed after change of cheapestVal() * src/SDCCval.c (valCompare): fixed EQ_OP and NE_OP; they have to ignore the sign * support/regression/tests/shifts.c: fixed git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2888 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 16 ++- src/SDCCval.c | 196 ++++++++++++++++++++++-------- support/regression/tests/shifts.c | 6 +- 3 files changed, 158 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ce68d88..71444964 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-09-13 Bernhard Held + + * src/SDCCval.c (cheapestVal): reenabled to reduce int to char + * src/SDCCval.c (constVal): added reduction from int to char + * src/SDCCval.c (valMult, valDiv): fixed sign handling + * src/SDCCval.c (valShift): fixed after change of cheapestVal() + * src/SDCCval.c (valCompare): fixed EQ_OP and NE_OP; they have + to ignore the sign + * support/regression/tests/shifts.c: fixed + 2003-09-13 Erik Petrich * src/z80/gen.c (genXor): Fixed bug #805445 @@ -14,7 +24,7 @@ * src/SDCCsymt.c * src/SDCCval.c * src/SDCC.y - * src/SDCCsymt.h + * src/SDCCsymt.h * src/pic/gen.c * src/pic/ralloc.c * src/pic16/gen.c @@ -87,7 +97,7 @@ * src/mcs51/gen.c (leftRightUseAcc), * src/ds390/gen.c (leftRightUseAcc): handle IFX and JUMPTABLE iCode properly now. Use getSize instead of nRegs since a & b - aren't part of the nRegs tally. + aren't part of the nRegs tally. 2003-08-31 Vangelis Rokas @@ -1319,7 +1329,7 @@ An sfr/sbit can have an "at #" AND an initializer * src/SDCCsymt.c (checkSClass): * src/SDCCmem.c (allocGlobal): - * src/SDCCmem.c (allocLocal): + * src/SDCCmem.c (allocLocal): * src/SDCCast.c (createBlock): 2003-03-17 Bernhard Held diff --git a/src/SDCCval.c b/src/SDCCval.c index b1f5e390..0bdace5e 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -118,21 +118,21 @@ convertIListToConstList(initList *src, literalList **lList) { return FALSE; } - + if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node)))) { return FALSE; } iLoop = iLoop->next; } - + // We've now established that the initializer list contains only literal values. - + iLoop = src->init.deep; while (iLoop) { double val = AST_LIT_VALUE(iLoop->init.node); - + if (last && last->literalValue == val) { last->count++; @@ -369,6 +369,43 @@ static value *cheapestVal (value *val) { } return val; } + +#else + +static value *cheapestVal (value *val) +{ + /* - signed/unsigned must no be changed. + - long must not be changed. + + the only possible reduction is from signed int to signed char, + because it's automatically promoted back to signed int. + + a reduction from unsigned int to unsigned char is a bug, + because an _unsigned_ char is promoted to _signed_ int! */ + if (IS_INT(val->type) && + !SPEC_USIGN(val->type) && + !SPEC_LONG(val->type) && + SPEC_CVAL(val->type).v_int >= -128 && + SPEC_CVAL(val->type).v_int <= 127) + + { + SPEC_NOUN(val->type) = V_CHAR; + } + /* this could be too aggressive: + 'unsigned char' promotes to 'signed int', so that we can + reduce it the other way */ + if (IS_INT(val->type) && + !SPEC_USIGN(val->type) && + !SPEC_LONG(val->type) && + SPEC_CVAL(val->type).v_int >= 128 && + SPEC_CVAL(val->type).v_int <= 255) + + { + SPEC_NOUN(val->type) = V_CHAR; + SPEC_USIGN(val->type) = 1; + } + return (val); +} #endif /*-----------------------------------------------------------------*/ @@ -427,7 +464,7 @@ value *constVal (char *s) val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */ SPEC_SCLS (val->type) = S_LITERAL; - // let's start with an unsigned char + // let's start with a signed char SPEC_NOUN (val->type) = V_CHAR; SPEC_USIGN (val->type) = 0; @@ -479,16 +516,26 @@ value *constVal (char *s) SPEC_LONG (val->type) = 1; } } else { // >=0 - if (dval>0xff && SPEC_USIGN (val->type)) { // check if we have to promote to int + if (dval>0xff || /* check if we have to promote to int */ + SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned + char. After an integral promotion it will + be a signed int; this certainly isn't what + the programer wants */ SPEC_NOUN (val->type) = V_INT; } else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int +#if 0 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */ dval<=0xff) { SPEC_USIGN (val->type) = 1; } else { - SPEC_NOUN (val->type) = V_INT; + SPEC_NOUN (val->type) = V_INT; } +#else + /* this is quite agressive: 'unsigned char' will be promoted to 'signed int', + so that the signedness of a char shouldn't matter */ + SPEC_USIGN (val->type) = 1; +#endif } if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long SPEC_LONG (val->type) = 1; @@ -1040,9 +1087,19 @@ valMult (value * lval, value * rval) SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - + /* both signed char and unsigned char are promoted to signed int */ + if (IS_CHAR (lval->etype)) + { + SPEC_USIGN (lval->etype) = 0; + SPEC_NOUN (lval->etype) = V_INT; + } + if (IS_CHAR (rval->etype)) + { + SPEC_USIGN (rval->etype) = 0; + SPEC_NOUN (rval->etype) = V_INT; + } + SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval); /* signed and unsigned mul are the same, as long as the precision of the @@ -1057,7 +1114,7 @@ valMult (value * lval, value * rval) SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul; if (!options.lessPedantic && - ul != SPEC_CVAL (val->type).v_uint) + ul != (TYPE_UWORD) ul) werror (W_INT_OVL); } else /* int */ @@ -1067,14 +1124,10 @@ valMult (value * lval, value * rval) SPEC_CVAL (val->type).v_int = (TYPE_WORD) l; if (!options.lessPedantic && - l != SPEC_CVAL (val->type).v_int) + l != (TYPE_WORD) l) werror (W_INT_OVL); } -#ifdef REDUCE_LITERALS return cheapestVal(val); -#else - return val; -#endif } /*------------------------------------------------------------------*/ @@ -1097,6 +1150,17 @@ valDiv (value * lval, value * rval) SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); SPEC_SCLS (val->etype) = S_LITERAL; + /* both signed char and unsigned char are promoted to signed int */ + if (IS_CHAR (lval->etype)) + { + SPEC_USIGN (lval->etype) = 0; + SPEC_NOUN (lval->etype) = V_INT; + } + if (IS_CHAR (rval->etype)) + { + SPEC_USIGN (rval->etype) = 0; + SPEC_NOUN (rval->etype) = V_INT; + } SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); @@ -1124,11 +1188,7 @@ valDiv (value * lval, value * rval) } } } -#ifdef REDUCE_LITERALS return cheapestVal(val); -#else - return val; -#endif } /*------------------------------------------------------------------*/ @@ -1167,11 +1227,7 @@ valMod (value * lval, value * rval) } } -#ifdef REDUCE_LITERALS return cheapestVal(val); -#else - return val; -#endif } /*------------------------------------------------------------------*/ @@ -1209,11 +1265,7 @@ valPlus (value * lval, value * rval) (long) floatFromVal (rval); } } -#ifdef REDUCE_LITERALS return cheapestVal(val); -#else - return val; -#endif } /*------------------------------------------------------------------*/ @@ -1263,11 +1315,7 @@ valMinus (value * lval, value * rval) } } } -#ifdef REDUCE_LITERALS return cheapestVal(val); -#else - return val; -#endif } /*------------------------------------------------------------------*/ @@ -1282,26 +1330,25 @@ valShift (value * lval, value * rval, int lr) val = newValue (); val->type = val->etype = newIntLink (); SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype)); - SPEC_LONG (val->type) = 1; + SPEC_NOUN (val->etype) = V_INT; + /* 'unsigned char' promotes to 'signed int' */ + if (!IS_CHAR (lval->etype)) + SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype); + SPEC_LONG (val->type) = SPEC_LONG (lval->etype); - if (SPEC_LONG (val->type)) + if (SPEC_USIGN (val->type)) { - if (SPEC_USIGN (val->type)) - SPEC_CVAL (val->type).v_ulong = lr ? - (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \ - (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval); - else - SPEC_CVAL (val->type).v_long = lr ? - (long) floatFromVal (lval) << (long) floatFromVal (rval) : \ - (long) floatFromVal (lval) >> (long) floatFromVal (rval); + SPEC_CVAL (val->type).v_ulong = lr ? + (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \ + (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval); + } + else + { + SPEC_CVAL (val->type).v_long = lr ? + (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \ + (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval); } - -#ifdef REDUCE_LITERALS return cheapestVal(val); -#else - return val; -#endif } /*------------------------------------------------------------------*/ @@ -1339,11 +1386,56 @@ valCompare (value * lval, value * rval, int ctype) break; case EQ_OP: - SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval); + if (SPEC_NOUN(lval->type) == V_FLOAT || + SPEC_NOUN(rval->type) == V_FLOAT) + { + SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval); + } + else + { + /* integrals: ignore signedness */ + TYPE_UDWORD l, r; + + l = (TYPE_UDWORD) floatFromVal (lval); + if (SPEC_NOUN(lval->type) == V_CHAR) + l &= 0xffff; /* promote to int */ + else if (!SPEC_LONG (lval->type)) + l &= 0xffff; + + r = (TYPE_UDWORD) floatFromVal (rval); + if (SPEC_NOUN(rval->type) == V_CHAR) + r &= 0xffff; /* promote to int */ + else if (!SPEC_LONG (rval->type)) + r &= 0xffff; + + SPEC_CVAL (val->type).v_int = l == r; + } break; - case NE_OP: - SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval); + if (SPEC_NOUN(lval->type) == V_FLOAT || + SPEC_NOUN(rval->type) == V_FLOAT) + { + SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval); + } + else + { + /* integrals: ignore signedness */ + TYPE_UDWORD l, r; + + l = (TYPE_UDWORD) floatFromVal (lval); + if (SPEC_NOUN(lval->type) == V_CHAR) + l &= 0xffff; /* promote to int */ + else if (!SPEC_LONG (lval->type)) + l &= 0xffff; + + r = (TYPE_UDWORD) floatFromVal (rval); + if (SPEC_NOUN(rval->type) == V_CHAR) + r &= 0xffff; /* promote to int */ + else if (!SPEC_LONG (rval->type)) + r &= 0xffff; + + SPEC_CVAL (val->type).v_int = l != r; + } break; } @@ -1431,11 +1523,7 @@ valBitwise (value * lval, value * rval, int op) break; } -#ifdef REDUCE_LITERALS return cheapestVal(val); -#else - return val; -#endif } /*------------------------------------------------------------------*/ diff --git a/support/regression/tests/shifts.c b/support/regression/tests/shifts.c index c709c5a2..80c8768f 100644 --- a/support/regression/tests/shifts.c +++ b/support/regression/tests/shifts.c @@ -59,9 +59,9 @@ testShiftByteMultiples(void) ASSERT(i>>24 == ({type})({vals} >> 24)); i = ({type}){vals}; - ASSERT(({type})(i<<8) == ({type})({vals} << 8));; - ASSERT(({type})(i<<16) == ({type})({vals} << 16)); - ASSERT(({type})(i<<24) == ({type})({vals} << 24)); + ASSERT( ({type})(i<<8) == ({type})({vals} << 8));; + ASSERT((({type}) i<<16) == (({type}) {vals} << 16)); + ASSERT((({type}) i<<24) == (({type}) {vals} << 24)); } static void -- 2.30.2