]> git.gag.com Git - fw/sdcc/blobdiff - src/SDCCicode.c
* src/SDCCicode.c (geniCodeArray): applied patch from Stas Sergeev proposed in FR...
[fw/sdcc] / src / SDCCicode.c
index a6a2193a5cbe7116fccc9e8d259bf759c97ede25..48cc6eabca252a2b42a071114759de04c8582bce 100644 (file)
@@ -1202,8 +1202,9 @@ operandOperation (operand * left, operand * right,
     case LEFT_OP:
       /* 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));
+      retval = operandFromValue (valCastLiteral (type,
+                                ((TYPE_UDWORD) operandLitValue (left) <<
+                                 (TYPE_UDWORD) operandLitValue (right))));
       break;
     case RIGHT_OP:
       /* The number of right shifts is always unsigned. Signed doesn't make
@@ -1732,7 +1733,7 @@ getArraySizePtr (operand * op)
 /*-----------------------------------------------------------------*/
 /* perform "usual unary conversions"                               */
 /*-----------------------------------------------------------------*/
-operand *
+static operand *
 usualUnaryConversions (operand * op)
 {
   if (IS_INTEGRAL (operandType (op)))
@@ -1763,12 +1764,19 @@ usualBinaryConversions (operand ** op1, operand ** op2,
      This if for 'mul a,b', which takes two chars and returns an int */
   if (   isMul
       /* && promoteCharToInt   superfluous, already handled by computeType() */
-      && IS_CHAR (getSpec (ltype))
-      && IS_CHAR (getSpec (rtype))
-      && !(IS_UNSIGNED (getSpec (rtype)) ^ IS_UNSIGNED (getSpec (ltype)))
       && IS_INT  (getSpec (ctype)))
-    return ctype;
+    {
+      sym_link *retype = getSpec (rtype);
+      sym_link *letype = getSpec (ltype);
 
+      if (   IS_CHAR (letype)
+         && IS_CHAR (retype)
+         && IS_UNSIGNED (letype)
+         && IS_UNSIGNED (retype))
+       {
+         return ctype;
+       }
+    }
   *op1 = geniCodeCast (ctype, *op1, TRUE);
   *op2 = geniCodeCast (ctype, *op2, TRUE);
 
@@ -2215,6 +2223,7 @@ geniCodeAdd (operand * left, operand * right, int lvl)
       if (getSize (ltype->next) != 1)
         {
          size  = operandFromLit (getSize (ltype->next));
+         SPEC_USIGN (getSpec (operandType (size))) = 1;
          indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
          right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
          /* Even if right is a 'unsigned char',
@@ -2298,6 +2307,7 @@ operand *
 geniCodeArray (operand * left, operand * right,int lvl)
 {
   iCode *ic;
+  operand *size;
   sym_link *ltype = operandType (left);
   bool indexUnsigned;
 
@@ -2310,9 +2320,10 @@ geniCodeArray (operand * left, operand * right,int lvl)
 
       return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
     }
+  size = operandFromLit (getSize (ltype->next));
+  SPEC_USIGN (getSpec (operandType (size))) = 1;
   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-  right = geniCodeMultiply (right,
-                           operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
+  right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
      It doesn't make sense when accessing arrays, so let's fix it here: */
   if (indexUnsigned)
@@ -2730,6 +2741,7 @@ geniCodeLeftShift (operand * left, operand * right)
 {
   iCode *ic;
 
+  left = usualUnaryConversions (left);
   ic = newiCode (LEFT_OP, left, right);
   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
   ADDTOCHAIN (ic);
@@ -3776,7 +3788,7 @@ ast2iCode (ast * tree,int lvl)
        return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
 
     case '-':
-      if (right) 
+      if (right)
        return geniCodeSubtract (geniCodeRValue (left, FALSE),
                                 geniCodeRValue (right, FALSE));
       else
@@ -3796,11 +3808,11 @@ ast2iCode (ast * tree,int lvl)
     case RIGHT_OP:
       return geniCodeRightShift (geniCodeRValue (left, FALSE),
                                 geniCodeRValue (right, FALSE));
-    case CAST: 
+    case CAST:
 #if 0 // this indeed needs a second thought
       {
        operand *op;
-       
+
        // let's keep this simple: get the rvalue we need
        op=geniCodeRValue (right, FALSE);
        // now cast it to whatever we want
@@ -4000,7 +4012,7 @@ ast2iCode (ast * tree,int lvl)
        return NULL;
     
     case CRITICAL:
-       geniCodeCritical (tree, lvl);    
+       geniCodeCritical (tree, lvl);
     }
 
   return NULL;