From: bernhardheld Date: Sat, 31 Dec 2005 13:17:32 +0000 (+0000) Subject: * src/SDCCast.c (decorateType): fix promotion of unary minus X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=e5c62ddb5b835550d3e4f84dbe9939b5c74b87af;p=fw%2Fsdcc * src/SDCCast.c (decorateType): fix promotion of unary minus * src/SDCCsymt.c (computeType): beautified * src/SDCCval.c (cheapestVal): beautified, old non-Ansi version removed, (valUnaryPM, valComplement, valNot): fix sign and promotion * support/regression/tests/uminus.c: speedup by removing superflous test case 'int' * support/regression/tests/onebyte.c: added promotion and signedness tests for unary minus * support/regressions/tests/bug-477927.c: disable warning about uninitialized variables git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4015 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 708f9a3d..86062577 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-12-31 Bernhard Held + + * src/SDCCast.c (decorateType): fix promotion of unary minus + * src/SDCCsymt.c (computeType): beautified + * src/SDCCval.c (cheapestVal): beautified, old non-Ansi version removed, + (valUnaryPM, valComplement, valNot): fix sign and promotion + * support/regression/tests/uminus.c: speedup by removing superflous + test case 'int' + * support/regression/tests/onebyte.c: added promotion and signedness + tests for unary minus + * support/regressions/tests/bug-477927.c: disable warning about + uninitialized variables + 2005-12-28 Bernhard Held * device/lib/Makefile.in: added --std-sdcc99 to CFLAGS diff --git a/src/SDCCast.c b/src/SDCCast.c index 0a608a79..3a91217c 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -3287,11 +3287,15 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.val = valUnaryPM (valFromType (LETYPE (tree))); tree->left = NULL; TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - SPEC_USIGN(TETYPE(tree)) = 0; return tree; } + tree->left = addCast (tree->left, resultType, TRUE); + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + NULL, + resultType, + tree->opval.op)); LRVAL (tree) = 1; - TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree)); return tree; } diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 172acf80..5cb19d06 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1880,28 +1880,34 @@ computeType (sym_link * type1, sym_link * type2, } else if (IS_CHAR (reType)) { - if (op == '|' || op == '^') - return computeTypeOr (etype1, etype2, reType); - else if ( op == '&' - && SPEC_USIGN (etype1) != SPEC_USIGN (etype2)) + /* promotion of some special cases */ + switch (op) { - SPEC_USIGN (reType) = 1; - return rType; - } - else if (op == '*') - { - SPEC_NOUN (reType) = V_INT; - SPEC_USIGN (reType) = 0; - return rType; - } - /* TODO: should be in SDCCast.c */ - else if ( op == '/' - && ( !SPEC_USIGN (etype1) - || !SPEC_USIGN (etype2))) - { - SPEC_NOUN (reType) = V_INT; - SPEC_USIGN (reType) = 0; - return rType; + case '|': + case '^': + return computeTypeOr (etype1, etype2, reType); + case '&': + if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2)) + { + SPEC_USIGN (reType) = 1; + return rType; + } + break; + case '*': + SPEC_NOUN (reType) = V_INT; + SPEC_USIGN (reType) = 0; + return rType; + case '/': + /* if both are unsigned char then no promotion required */ + if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2))) + { + SPEC_NOUN (reType) = V_INT; + SPEC_USIGN (reType) = 0; + return rType; + } + break; + default: + break; } } break; diff --git a/src/SDCCval.c b/src/SDCCval.c index c798df04..29a982d0 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -326,100 +326,49 @@ symbolVal (symbol * sym) return val; } -#if defined(REDUCE_LITERALS) /*--------------------------------------------------------------------*/ /* cheapestVal - convert a val to the cheapest as possible value */ /*--------------------------------------------------------------------*/ -static value *cheapestVal (value *val) { - TYPE_DWORD sval=0; - TYPE_UDWORD uval=0; - - if (IS_FLOAT(val->type) || IS_FIXED(val->type) || IS_CHAR(val->type)) +static value * +cheapestVal (value *val) +{ + if (IS_FLOAT (val->type) || IS_FIXED (val->type) || IS_CHAR (val->type)) return val; - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) { - uval=SPEC_CVAL(val->type).v_ulong; - } else { - sval=SPEC_CVAL(val->type).v_long; - } - } else { - if (SPEC_USIGN(val->type)) { - uval=SPEC_CVAL(val->type).v_uint; - } else { - sval=SPEC_CVAL(val->type).v_int; - } - } - - if (SPEC_USIGN(val->type)) { - if (uval<=0xffff) { - SPEC_LONG(val->type)=0; - SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval; - if (uval<=0xff) { - SPEC_NOUN(val->type)=V_CHAR; - } - } - } else { // not unsigned - if (sval<0) { - if (sval>=-32768) { - SPEC_LONG(val->type)=0; - SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval; - if (sval>=-128) { - SPEC_NOUN(val->type)=V_CHAR; - } - } - } else { // sval>=0 - if (sval<=32767) { - SPEC_LONG(val->type)=0; - SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval; - if (sval<=127) { - SPEC_NOUN(val->type)=V_CHAR; - } - } - } - } - return val; -} - -#else + /* long must not be changed */ + if (SPEC_LONG(val->type)) + return val; -static value *cheapestVal (value *val) -{ - if (IS_FLOAT (val->type) || IS_FIXED (val->type) || IS_CHAR (val->type)) + /* only int can be reduced */ + if (!IS_INT(val->type)) return val; - /* - signed/unsigned must not be changed. - - long must not be changed. + /* unsigned must not be changed */ + if (SPEC_USIGN(val->type)) + return val; - the only possible reduction is from signed int to signed char, + /* the only possible reduction is from signed int to (un)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 < 0) - + if (SPEC_CVAL(val->type).v_int < -128 || + SPEC_CVAL(val->type).v_int > 255) { - SPEC_NOUN(val->type) = V_CHAR; + /* not in the range of (un)signed char */ + return val; } + + SPEC_NOUN(val->type) = V_CHAR; + /* '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 >= 0 && - SPEC_CVAL(val->type).v_int <= 255) - + if (SPEC_CVAL(val->type).v_int >= 0) { - SPEC_NOUN(val->type) = V_CHAR; SPEC_USIGN(val->type) = 1; } return (val); } -#endif /*-----------------------------------------------------------------*/ /* valueFromLit - creates a value from a literal */ @@ -1043,16 +992,16 @@ valUnaryPM (value * val) SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint; else SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int; + + if (SPEC_NOUN(val->etype) == V_CHAR) + { + /* promote to 'signed int', cheapestVal() might reduce it again */ + SPEC_USIGN(val->etype) = 0; + SPEC_NOUN(val->etype) = V_INT; + } + return cheapestVal (val); } } - // -(unsigned 3) now really is signed - SPEC_USIGN(val->etype)=0; - // -(unsigned char)135 now really is an int - if (SPEC_NOUN(val->etype) == V_CHAR) { - if (SPEC_CVAL(val->etype).v_int < -128) { - SPEC_NOUN(val->etype) = V_INT; - } - } return val; } @@ -1076,13 +1025,15 @@ valComplement (value * val) SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint; else SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int; + if (SPEC_NOUN(val->etype) == V_CHAR) - if ( SPEC_CVAL(val->etype).v_int < -128 - || SPEC_CVAL(val->etype).v_int > 127) + { + /* promote to 'signed int', cheapestVal() might reduce it again */ + SPEC_USIGN(val->etype) = 0; SPEC_NOUN(val->etype) = V_INT; + } + return cheapestVal (val); } - // ~(unsigned 3) now really is signed - SPEC_USIGN(val->etype)=0; return val; } @@ -1106,6 +1057,14 @@ valNot (value * val) SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint; else SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int; + + if (SPEC_NOUN(val->etype) == V_CHAR) + { + /* promote to 'signed int', cheapestVal() might reduce it again */ + SPEC_USIGN(val->etype) = 0; + SPEC_NOUN(val->etype) = V_INT; + } + return cheapestVal (val); } return val; } diff --git a/support/regression/tests/bug-477927.c b/support/regression/tests/bug-477927.c index b0ab6c3e..6acc995b 100644 --- a/support/regression/tests/bug-477927.c +++ b/support/regression/tests/bug-477927.c @@ -29,6 +29,11 @@ spoil(UBYTE ignored) UBYTE accu[2]; +#if !defined(PORT_HOST) +# pragma save +# pragma disable_warning 84 +#endif + void testLoopInit(void) { @@ -45,4 +50,6 @@ testLoopInit(void) while(t != 3); } - +#if !defined(PORT_HOST) +# pragma restore +#endif diff --git a/support/regression/tests/onebyte.c b/support/regression/tests/onebyte.c index a6ffc9d1..326f9ad0 100644 --- a/support/regression/tests/onebyte.c +++ b/support/regression/tests/onebyte.c @@ -203,3 +203,28 @@ testComp(void) ASSERT(!(c > uc)); ASSERT(!(c >= uc)); } + +void +testUMinus(void) +{ + signed char {attrL} sc; + unsigned char {attrL} uc; + unsigned int {attrL} us; + unsigned long {attrL} ul; + + ASSERT (-(53ul) > 0); + ul = 53; + ASSERT (-ul > 0); + + ASSERT (-(53u ) > 0); + us = 53; + ASSERT (-us > 0); + + ASSERT (-( 250 ) == -250); + uc = 250; + ASSERT (-uc == -250); + + ASSERT (-(-128 ) == 128); + sc = -128; + ASSERT (-sc == 128); +} diff --git a/support/regression/tests/uminus.c b/support/regression/tests/uminus.c index 1a5732b9..0009840d 100644 --- a/support/regression/tests/uminus.c +++ b/support/regression/tests/uminus.c @@ -1,7 +1,7 @@ /* Test unary minus - lefttype: int, char, short, long - resulttype: int, char, short, long + lefttype: char, short, long + resulttype: char, short, long storage: static, attr: volatile, */ @@ -20,7 +20,6 @@ testUMinus(void) left = -76; result = -left; - + ASSERT(result == 76); } -