* packihx/,
[fw/sdcc] / src / SDCCast.c
index 86fad20a2c504b803c58a6f1326c60858f92d4ca..66452408a22bd8a0763695d22b88918b499262ae 100644 (file)
@@ -1467,8 +1467,11 @@ constExprValue (ast * cexpr, int check)
     }
 
   /* return the value */
-  return cexpr->opval.val;
-
+  if (IS_AST_VALUE (cexpr))
+    {
+      return cexpr->opval.val;
+    }
+   return NULL;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2250,7 +2253,7 @@ getLeftResultType (ast *tree, RESULT_TYPE resultType)
 /*--------------------------------------------------------------------*/
 /* decorateType - compute type for this tree, also does type checking.*/
 /* This is done bottom up, since type has to flow upwards.            */
-/* resultType flows top-down and forces e.g. char-arithmetik, if the  */
+/* resultType flows top-down and forces e.g. char-arithmetic, if the  */
 /* result is a char and the operand(s) are int's.                     */
 /* It also does constant folding, and parameter checking.             */
 /*--------------------------------------------------------------------*/
@@ -3626,6 +3629,13 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       changePointer(LTYPE(tree));
       checkTypeSanity(LETYPE(tree), "(cast)");
 
+      /* if 'from' and 'to' are the same remove the superflous cast, */
+      /* this helps other optimizations */
+      if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
+        {
+          return tree->right;
+        }
+
       /* If code memory is read only, then pointers to code memory */
       /* implicitly point to constants -- make this explicit       */
       {
@@ -3913,6 +3923,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                 goto errorTreeReturn;
               }
         }
+
       /* if unsigned value < 0  then always false */
       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
       if (SPEC_USIGN(LETYPE(tree)) &&
@@ -3940,9 +3951,23 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                                      tree->right); /* val 0 */
               tree->right->lineno = tree->lineno;
               tree->right->left->lineno = tree->lineno;
-              decorateType (tree->right, RESULT_TYPE_NONE);
+              tree->decorated = 0;
+              return decorateType (tree, resultType);
             }
         }
+
+      /* 'ifx (op == 0)' -> 'ifx (!(op))' */
+      if (IS_LITERAL(RTYPE(tree))  &&
+          floatFromVal (valFromType (RETYPE (tree))) == 0 &&
+          tree->opval.op == EQ_OP &&
+          resultType == RESULT_TYPE_IFX)
+        {
+          tree->opval.op = '!';
+          tree->right = NULL;
+          tree->decorated = 0;
+          return decorateType (tree, resultType);
+        }
+
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) &&
@@ -3989,7 +4014,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      TTYPE (tree) = TETYPE (tree) = newCharLink ();
+      TTYPE (tree) = TETYPE (tree) = newBoolLink ();
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -5220,12 +5245,12 @@ optimizeRRCRLC (ast * root)
      into a RRC operation
      note : by 7 I mean (number of bits required to hold the
      variable -1 ) */
-  /* if the root operations is not a | operation the not */
+  /* if the root operation is not a | operation then not */
   if (!IS_BITOR (root))
     return root;
 
   /* I have to think of a better way to match patterns this sucks */
-  /* that aside let start looking for the first case : I use a the
+  /* that aside let's start looking for the first case : I use a
      negative check a lot to improve the efficiency */
   /* (?expr << 1) | (?expr >> 7) */
   if (IS_LEFT_OP (root->left) &&
@@ -5383,7 +5408,7 @@ optimizeSWAP (ast * root)
      into a SWAP : operation ..
      note : by 4 I mean (number of bits required to hold the
      variable /2 ) */
-  /* if the root operations is not a | operation the not */
+  /* if the root operation is not a | operation then not */
   if (!IS_BITOR (root))
     return root;