* packihx/,
[fw/sdcc] / src / SDCCicode.c
index 6f8be2731863e2479e27b627f60b5a3ec9e4c30e..8ad10a8d9fde7eb0af19fcc3ea4a940009c792e2 100644 (file)
@@ -233,7 +233,7 @@ printOperand (operand * op, FILE * file)
       opetype = getSpec (operandType (op));
       if (IS_FLOAT (opetype))
         fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
-      if (IS_FIXED16X16 (opetype))
+      else if (IS_FIXED16X16 (opetype))
         fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
       else
         fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
@@ -725,14 +725,15 @@ newiTempLabel (char *s)
 }
 
 /*-----------------------------------------------------------------*/
-/* newiTempPreheaderLabel - creates a new preheader label          */
+/* newiTempLoopHeaderLabel - creates a new loop header label       */
 /*-----------------------------------------------------------------*/
 symbol *
-newiTempPreheaderLabel ()
+newiTempLoopHeaderLabel (bool pre)
 {
   symbol *itmplbl;
 
-  SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
+  SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d",
+            iTempLblNum++);
   itmplbl = newSymbol (buffer, 1);
 
   itmplbl->isitmp = 1;
@@ -1327,15 +1328,12 @@ operandOperation (operand * left, operand * right,
                                  (TYPE_UDWORD) operandLitValue (right));
       break;
     case EQ_OP:
-      if (IS_FLOAT (let) ||
-          IS_FLOAT (ret))
+      if (IS_FLOAT (let) || IS_FLOAT (ret))
         {
           retval = operandFromLit (operandLitValue (left) ==
                                    operandLitValue (right));
         }
-      else
-      if (IS_FIXED16X16 (let) ||
-          IS_FIXED16X16 (ret))
+      else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
         {
           retval = operandFromLit (operandLitValue (left) ==
                                    operandLitValue (right));
@@ -1841,7 +1839,7 @@ setOperandType (operand * op, sym_link * type)
 /*-----------------------------------------------------------------*/
 /* Get size in byte of ptr need to access an array                 */
 /*-----------------------------------------------------------------*/
-static int
+static unsigned int
 getArraySizePtr (operand * op)
 {
   sym_link *ltype = operandType(op);
@@ -2412,11 +2410,7 @@ geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
           size  = operandFromLit (getSize (ltype->next));
           SPEC_USIGN (getSpec (operandType (size))) = 1;
           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-          right = geniCodeMultiply (right,
-                                    size,
-                                    (getArraySizePtr(left) >= INTSIZE) ?
-                                      RESULT_TYPE_INT :
-                                      RESULT_TYPE_CHAR);
+          right = geniCodeMultiply (right, size, resultType);
           /* 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: */
@@ -2515,6 +2509,14 @@ geniCodeArray (operand * left, operand * right, int lvl)
   operand *size;
   sym_link *ltype = operandType (left);
   bool indexUnsigned;
+  RESULT_TYPE resultType;
+
+  resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
+  if (DCL_ELEM (ltype))
+    {
+      if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
+        resultType = RESULT_TYPE_CHAR;
+    }
 
   if (IS_PTR (ltype))
     {
@@ -2523,22 +2525,13 @@ geniCodeArray (operand * left, operand * right, int lvl)
           left = geniCodeRValue (left, FALSE);
         }
 
-      return geniCodeDerefPtr (geniCodeAdd (left,
-                                            right,
-                                            (getArraySizePtr(left) >= INTSIZE) ?
-                                              RESULT_TYPE_INT :
-                                              RESULT_TYPE_CHAR,
-                                            lvl),
+      return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
                                lvl);
     }
   size = operandFromLit (getSize (ltype->next));
   SPEC_USIGN (getSpec (operandType (size))) = 1;
   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-  right = geniCodeMultiply (right,
-                            size,
-                            (getArraySizePtr(left) >= INTSIZE) ?
-                              RESULT_TYPE_INT :
-                              RESULT_TYPE_CHAR);
+  right = geniCodeMultiply (right, size, resultType);
   /* 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)
@@ -2646,8 +2639,7 @@ geniCodePostInc (operand * op)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (rvtype))
     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (rvtype))
+  else if (IS_FIXED16X16 (rvtype))
     ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('+', rv, operandFromLit (size));
@@ -2687,8 +2679,7 @@ geniCodePreInc (operand * op, bool lvalue)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (roptype))
     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (roptype))
+  else if (IS_FIXED16X16 (roptype))
     ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('+', rop, operandFromLit (size));
@@ -2738,8 +2729,7 @@ geniCodePostDec (operand * op)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (rvtype))
     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (rvtype))
+  else if (IS_FIXED16X16 (rvtype))
     ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('-', rv, operandFromLit (size));
@@ -2779,8 +2769,7 @@ geniCodePreDec (operand * op, bool lvalue)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (roptype))
     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (roptype))
+  else if (IS_FIXED16X16 (roptype))
     ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('-', rop, operandFromLit (size));
@@ -2854,7 +2843,7 @@ geniCodeAddressOf (operand * op)
       return op;
     }
 
-  /* other wise make this of the type coming in */
+  /* otherwise make this of the type coming in */
   ic = newiCode (ADDRESS_OF, op, NULL);
   IC_RESULT (ic) = newiTempOperand (p, 1);
   IC_RESULT (ic)->isaddr = 0;
@@ -3068,7 +3057,7 @@ geniCodeLogic (operand * left, operand * right, int op)
         }
     }
 
-  ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
+  ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
 
   ic = newiCode (op, left, right);
   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
@@ -3271,12 +3260,16 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
       isOperandGlobal (left))
     {
       symbol *sym = NULL;
+      operand *newRight;
 
       if (IS_TRUE_SYMOP (right))
         sym = OP_SYMBOL (right);
       ic = newiCode ('=', NULL, right);
-      IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
-      SPIL_LOC (right) = sym;
+      IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
+      /* avoid double fetch from volatile right, see bug 1369874 */
+      if (!isOperandVolatile (right, FALSE))
+        SPIL_LOC (newRight) = sym;
+      right = newRight;
       ADDTOCHAIN (ic);
     }
 
@@ -3638,8 +3631,6 @@ geniCodeIfx (ast * tree,int lvl)
         {
           if (tree->falseLabel)
             geniCodeGoto (tree->falseLabel);
-          else
-            assert (0);
         }
       goto exit;
     }