* src/SDCCval.c (cheapestVal, valueFromLit): use TYPE_* types
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 5 Aug 2003 15:47:45 +0000 (15:47 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 5 Aug 2003 15:47:45 +0000 (15:47 +0000)
* src/SDCCval.c (constVal): changed default to signed; hex and octal constants are unsigned; added recognition of "u" flag for unsigned
* src/SDCCval.c (valMult): fixed signdness, added warning for overflow
* src/SDCCval.c (valDiv, valMod): fixed signdness
* src/SDCCicode.c (operandOperation): fixed critical typo; fixed signedness of modulo, left and right shift

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2807 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/SDCCicode.c
src/SDCCval.c

index 1e70b3be73c0691ee5e2567edf9490e905a5b8a8..472b64f2887aa30e4cd1997e597886140a10c67c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2003-08-05  Bernhard Held <bernhard@bernhardheld.de>
+
+       * src/SDCCval.c (cheapestVal, valueFromLit): use TYPE_* types
+       * src/SDCCval.c (constVal): changed default to signed; hex and octal
+       constants are unsigned; added recognition of "u" flag for unsigned
+       * src/SDCCval.c (valMult): fixed signdness, added warning for overflow
+       * src/SDCCval.c (valDiv, valMod): fixed signdness
+       * src/SDCCicode.c (operandOperation): fixed critical typo; fixed
+       signedness of modulo, left and right shift
+
 2003-08-04  Jesus Calvino-Fraga <jesusc@ece.ubc.ca>
 
        Fixed some warnings when building with MSVC:
index f368ac4ed66635f101e6e749bf66748683510528..f7f9f89efa93e7f84a062d8427366357194b48ff 100644 (file)
@@ -1043,7 +1043,7 @@ operandOperation (operand * left, operand * right,
   let = getSpec(operandType(left));
   if (right) {
     assert (isOperandLiteral (right));
-    ret = getSpec(operandType(left));
+    ret = getSpec(operandType(right));
   }
 
   switch (op)
@@ -1081,41 +1081,34 @@ operandOperation (operand * left, operand * right,
          retval = right;
       }
       else
-       retval = operandFromLit ((SPEC_USIGN(let) ?
-                                 (TYPE_UDWORD) operandLitValue (left) :
-                                 (TYPE_DWORD) operandLitValue (left)) %
-                                (SPEC_USIGN(ret) ?
-                                 (TYPE_UDWORD) operandLitValue (right) :
-                                 (TYPE_DWORD) operandLitValue (right)));
-
+        {
+          if (SPEC_USIGN(let) || SPEC_USIGN(ret))
+           /* one of the operands is unsigned */
+           retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
+                                    (TYPE_UDWORD) operandLitValue (right));
+         else
+           /* both operands are signed */
+           retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
+                                    (TYPE_DWORD) operandLitValue (right));
+        }
       break;
     case LEFT_OP:
-      retval = operandFromLit ((SPEC_USIGN(let) ?
-                                 (TYPE_UDWORD) operandLitValue (left) :
-                                 (TYPE_UDWORD) operandLitValue (left)) <<
-                                (SPEC_USIGN(ret) ?
-                                 (TYPE_UDWORD) operandLitValue (right) :
-                                 (TYPE_UDWORD) operandLitValue (right)));
+      /* The number of left shifts is always unsigned. Signed doesn't make
+        sense here. Shifting by a negative number is impossible. */
+      retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
+                              (TYPE_UDWORD) operandLitValue (right));
       break;
     case RIGHT_OP: {
-      double lval = operandLitValue(left), rval = operandLitValue(right);
-      double res=0;
-      switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0))
-       {
-       case 0: // left=unsigned right=unsigned
-         res=(TYPE_UDWORD)lval >> (TYPE_UDWORD)rval;
-         break;
-       case 1: // left=unsigned right=signed
-         res=(TYPE_UDWORD)lval >> (TYPE_DWORD)rval;
-         break;
-       case 2: // left=signed right=unsigned
-         res=(TYPE_DWORD)lval >> (TYPE_UDWORD)rval;
-         break;
-       case 3: // left=signed right=signed
-         res=(TYPE_DWORD)lval >> (TYPE_DWORD)rval;
-         break;
-       }
-      retval = operandFromLit (res);
+      /* The number of right shifts is always unsigned. Signed doesn't make
+        sense here. Shifting by a negative number is impossible. */
+      if (SPEC_USIGN(let))
+        /* unsigned: logic shift right */
+        retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
+                                (TYPE_UDWORD) operandLitValue (right));
+      else
+        /* signed: arithmetic shift right */
+        retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
+                                (TYPE_UDWORD) operandLitValue (right));
       break;
     }
     case EQ_OP:
index edd9c25b82ee14dc58df776f56013e9341f10713..5a49f4dc0003c178507db417f482b3ffff5717f3 100644 (file)
@@ -319,8 +319,8 @@ symbolVal (symbol * sym)
 /* cheapestVal - convert a val to the cheapest as possible value      */
 /*--------------------------------------------------------------------*/
 value *cheapestVal (value *val) {
-  long sval=0;
-  unsigned long uval=0;
+  TYPE_DWORD  sval=0;
+  TYPE_UDWORD uval=0;
 
   if (IS_FLOAT(val->type) || IS_CHAR(val->type))
     return val;
@@ -378,9 +378,9 @@ valueFromLit (double lit)
 {
   char buffer[50];
 
-  if ((((long) lit) - lit) == 0)
+  if ((((TYPE_DWORD) lit) - lit) == 0)
     {
-      SNPRINTF (buffer, sizeof(buffer), "%ld", (long) lit);
+      SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
       return constVal (buffer);
     }
 
@@ -428,7 +428,7 @@ value *constVal (char *s)
   SPEC_SCLS (val->type) = S_LITERAL;
   // let's start with an unsigned char
   SPEC_NOUN (val->type) = V_CHAR;
-  SPEC_USIGN (val->type) = 1;
+  SPEC_USIGN (val->type) = 0;
 
   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
 
@@ -454,6 +454,7 @@ value *constVal (char *s)
     unsigned long sval;
     sscanf (s, scanFmt, &sval);
     dval=sval;
+    SPEC_USIGN (val->type) = 1;
   } else {
     sscanf (s, scanFmt, &dval);
   }
@@ -465,8 +466,12 @@ value *constVal (char *s)
     SPEC_LONG (val->type) = 1;
   }
 
+  /* set the unsigned flag if 'uU' is found */
+  if (strchr (s, 'u') || strchr (s, 'U')) {
+    SPEC_USIGN (val->type) = 1;
+  }
+
   if (dval<0) { // "-28u" will still be signed and negative
-    SPEC_USIGN (val->type) = 0;
     if (dval<-128) { // check if we have to promote to int
       SPEC_NOUN (val->type) = V_INT;
     }
@@ -474,10 +479,16 @@ value *constVal (char *s)
       SPEC_LONG (val->type) = 1;
     }
   } else { // >=0
-    if (dval>0xff) { // check if we have to promote to int
+    if (dval>0xff && SPEC_USIGN (val->type)) { // check if we have to promote to int
+      SPEC_NOUN (val->type) = V_INT;
+    }
+    else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
       SPEC_NOUN (val->type) = V_INT;
     }
-    if (dval>0xffff) { // check if we have to promote to long int
+    if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
+      SPEC_LONG (val->type) = 1;
+    }
+    else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
       SPEC_LONG (val->type) = 1;
     }
   }
@@ -769,7 +780,6 @@ value *
 charVal (char *s)
 {
   value *val;
-//  unsigned uValue ;
 
   val = newValue ();
 
@@ -1017,23 +1027,39 @@ valMult (value * lval, value * rval)
   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_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
-  SPEC_LONG (val->type) = 1;
+  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));
 
   if (IS_FLOAT (val->type))
     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
   else
     {
+      /* signed and unsigned mul are the same, as long as the precision of the
+         result isn't bigger than the precision of the operands. */
       if (SPEC_LONG (val->type))
-       {
-         if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
-             (unsigned long) floatFromVal (rval);
-         else
-           SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
-             (long) floatFromVal (rval);
-       }
+        SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
+                                       (TYPE_UDWORD) floatFromVal (rval);
+      else
+        {
+          TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
+                           (TYPE_UWORD) floatFromVal (rval);
+          
+          SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
+          if (!options.lessPedantic)
+            {
+              if (SPEC_USIGN (val->type))
+                {
+                  if (ul != SPEC_CVAL (val->type).v_uint)
+                    werror (W_INT_OVL);
+                }
+              else /* signed result */
+                {
+                  if ((TYPE_DWORD) ul != SPEC_CVAL (val->type).v_int)
+                    werror (W_INT_OVL);
+                }
+            }
+        }
     }
   return cheapestVal(val);
 }
@@ -1058,7 +1084,7 @@ 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;
-  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
+  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
 
   if (IS_FLOAT (val->type))
@@ -1102,7 +1128,7 @@ valMod (value * lval, value * rval)
   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_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
+  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
 
   if (SPEC_LONG (val->type))