From 15f7f3d75ebe0d7cf0ef84dea8abcd19cbdaa009 Mon Sep 17 00:00:00 2001 From: bernhardheld Date: Thu, 26 Feb 2004 20:04:51 +0000 Subject: [PATCH] * src/Makefile.in (dep): include SLIBOBJS in dependency check * src/SDCCast.c (decorateType): catch another small optimization with '?' operator * src/SDCCsymt.c (computeType): added comments and cosmetic changes * src/SDCCval.c (valMult, valDiv, valMod, valPlus, valMinus, valShift): modified to finally use computeType() all over SDCC, see Feature Request #877103 * src/SDCCval.h: cosmetic git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3234 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 13 +++++++- src/Makefile.in | 5 +-- src/SDCCast.c | 2 +- src/SDCCsymt.c | 58 ++++++++++++++++++++++++++-------- src/SDCCval.c | 82 +++++++++++++++++++------------------------------ src/SDCCval.h | 3 +- 6 files changed, 95 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index e31cf03c..35fa24b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-02-26 Bernhard Held + + * src/Makefile.in (dep): include SLIBOBJS in dependency check + * src/SDCCast.c (decorateType): catch another small optimization + with '?' operator + * src/SDCCsymt.c (computeType): added comments and cosmetic changes + * src/SDCCval.c (valMult, valDiv, valMod, valPlus, valMinus, valShift): + modified to finally use computeType() all over SDCC, + see Feature Request #877103 + * src/SDCCval.h: cosmetic + 2004-02-23 Bernhard Held * src/SDCCast.c (decorateType): fixed bug #902362 @@ -15,7 +26,7 @@ * src/pic16/ralloc.c (packRegsForAccUse): disabled functions with #if to eliminate build warnings. - * src/pic16/gen.c (pic16_popGet): fixed for gcc 2.95.4 + * src/pic16/gen.c (pic16_popGet): fixed for gcc 2.95.4 2004-02-20 Vangelis Rokas Hans-Juergen Dorn diff --git a/src/Makefile.in b/src/Makefile.in index 1c3d85b2..a7d91aa5 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -37,6 +37,7 @@ else OBJECTS += SDCClex.o endif +SLIBSOURCES = $(patsubst %.o,$(SLIB)/%.c,$(SLIBOBJS)) SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) TARGET = $(PRJDIR)/bin/sdcc$(EXEEXT) @@ -85,8 +86,8 @@ installdirs: # --------------------- dep: Makefile.dep -Makefile.dep: $(SOURCES) $(SPECIAL) *.h $(PRJDIR)/*.h - $(CPP) $(CPPFLAGS) $(M_OR_MM) $(SOURCES) >Makefile.dep +Makefile.dep: $(SOURCES) $(SLIBSOURCES) $(SPECIAL) *.h $(PRJDIR)/*.h + $(CPP) $(CPPFLAGS) $(M_OR_MM) $(SOURCES) $(SLIBSOURCES) >Makefile.dep include Makefile.dep include clean.mk diff --git a/src/SDCCast.c b/src/SDCCast.c index 143d7b2d..5308992c 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -2288,7 +2288,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) resultTypeProp = resultTypePropagate (tree, resultType); if (tree->opval.op == '?') - dtl = decorateType (tree->left, RESULT_TYPE_NONE); + dtl = decorateType (tree->left, RESULT_TYPE_IFX); else dtl = decorateType (tree->left, resultTypeProp); diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index e462c2b4..43996bf3 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1556,25 +1556,57 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt) if (IS_CHAR (reType) && promoteCharToInt) SPEC_NOUN (reType) = V_INT; + /* SDCC's sign promotion: + - if one or both operands are unsigned, the resultant type will be unsigned + (except char, see below) + - if an operand is promoted to a larger type (char -> int, int -> long), + the larger type will be signed + + SDCC tries hard to avoid promotion to int and does 8 bit calculation as + much as possible. We're leaving ISO IEC 9899 here and have to extrapolate + the standard. The standard demands, that the result has to be the same + "as if" the promotion would have been performed: + + - if the result of an operation with two char's is promoted to a + larger type, the result will be signed. + + More sophisticated is the last one: + - if the result of an operation with two char's is a char again, + the result will only then be unsigned, if both operands are + unsigned. In all other cases the result will be signed. + + This seems to be contradictionary to the first two rules, but it makes + real sense (all types are char's): + + A signed char can be negative; this must be preserved in the result + -1 * 100 = -100; + + Only if both operands are unsigned it's safe to make the result + unsigned; this helps to avoid overflow: + 2 * 100 = 200; + + Homework: - why is (200 * 200 < 0) true? + - why is { char l = 200, r = 200; (r * l > 0) } true? + */ + if (!IS_FLOAT (reType) - && ( ( SPEC_USIGN (etype1) - /* if this operand is promoted to a larger - type don't check it's signedness */ - && (getSize (etype1) >= getSize (reType)) - /* char has to handled as it would have - been promoted to int */ + && ( (SPEC_USIGN (etype1) + /* if this operand is promoted to a larger type, + then it will be promoted to a signed type */ + && !(getSize (etype1) < getSize (reType)) + /* char require special handling */ && !IS_CHAR (etype1)) - /* same for 2nd operand */ - || ( SPEC_USIGN (etype2) - && (getSize (etype2) >= getSize (reType)) + || /* same for 2nd operand */ + (SPEC_USIGN (etype2) + && !(getSize (etype2) < getSize (reType)) && !IS_CHAR (etype2)) - /* if both are unsigned char and not promoted - let the result be unsigned too */ - || ( SPEC_USIGN (etype1) + || /* if both are 'unsigned char' and not promoted + let the result be unsigned too */ + ( SPEC_USIGN (etype1) && SPEC_USIGN (etype2) && IS_CHAR (etype1) && IS_CHAR (etype2) - && !promoteCharToInt))) + && IS_CHAR (reType)))) SPEC_USIGN (reType) = 1; else SPEC_USIGN (reType) = 0; diff --git a/src/SDCCval.c b/src/SDCCval.c index 542ca575..c5f25568 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -1084,14 +1084,11 @@ valMult (value * lval, value * rval) /* create a new value */ val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - 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_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val->type = val->etype = computeType (lval->etype, + rval->etype, + TRUE); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ + 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 @@ -1136,14 +1133,10 @@ valDiv (value * lval, value * rval) /* create a new value */ val = newValue (); - val->type = val->etype = newLink(SPECIFIER); - SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || - IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); - SPEC_SCLS (val->etype) = S_LITERAL; - SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - FALSE)); + val->type = val->etype = computeType (lval->etype, + rval->etype, + TRUE); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval); @@ -1177,14 +1170,11 @@ valMod (value * lval, value * rval) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - SPEC_NOUN (val->type) = V_INT; /* type is int */ - SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + rval->etype, + TRUE); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ if (SPEC_LONG (val->type)) { @@ -1216,15 +1206,12 @@ valPlus (value * lval, value * rval) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - 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_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + rval->etype, + TRUE); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ + if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval); else if (SPEC_LONG (val->type)) @@ -1257,15 +1244,12 @@ valMinus (value * lval, value * rval) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - 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_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + rval->etype, + TRUE); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ + if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval); else if (SPEC_LONG (val->type)) @@ -1298,14 +1282,12 @@ valShift (value * lval, value * rval, int lr) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newIntLink (); - SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - 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); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + NULL, + /* promote left shift */ + lr ? TRUE : FALSE); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) && /* left shift */ diff --git a/src/SDCCval.h b/src/SDCCval.h index d49495a8..363b5e45 100644 --- a/src/SDCCval.h +++ b/src/SDCCval.h @@ -20,10 +20,11 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include "SDCCsymt.h" #ifndef SDCCVAL_H #define SDCCVAL_H +#include "SDCCsymt.h" + /* value wrapper */ typedef struct value { -- 2.30.2