* src/SDCCast.c: added an additional type flow in decorateType() of opposite directio...
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 25 Jan 2004 21:33:56 +0000 (21:33 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 25 Jan 2004 21:33:56 +0000 (21:33 +0000)
* src/SDCCast.h: changed prototype of decorateType()
* src/SDCCglue.c (emitRegularMap): updated call of decorateType()
* src/SDCCicode.c (geniCodeDivision) (geniCodeModulus): promotion from 'char' to 'int' can be omitted, if both operands are 'unsigned char'; see feature request #877103
* src/SDCCval.c: updated call of decorateType()
(valBitwise): fixed bug #882876
(valMinus): added promotion
(valLogicAndOr): result is unsigned
(cheapestVal) (constVal): literals from 0...255 are 'unsigned char' now
* src/SDCCsymt.c (computeType),
* src/mcs51/gen.c (genCmpGt) (genCmpLt): literal 'unsigned char' must not cause an unsigned operation
* src/pic/glue (pic14emitRegularMap),
* src/pic16/glue.c (pic16emitRegularMap): updated call of decorateType()

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

ChangeLog
src/SDCCast.c
src/SDCCast.h
src/SDCCglue.c
src/SDCCicode.c
src/SDCCsymt.c
src/SDCCval.c
src/mcs51/gen.c
src/pic/glue.c
src/pic16/glue.c

index 459e8ea70756585e350c033ffe913584d211397b..fbee181b1e691e9d4f5bccc913b38de22ca06bd7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2004-01-25 Bernhard Held <bernhard@bernhardheld.de>
+
+       * src/SDCCast.c: added an additional type flow in decorateType() of
+       opposite direction, see feature request #860006; it's enabled at runtime
+       by setting the environment variable SDCC_NEWTYPEFLOW
+       * src/SDCCast.h: changed prototype of decorateType()
+       * src/SDCCglue.c (emitRegularMap): updated call of decorateType()
+       * src/SDCCicode.c (geniCodeDivision) (geniCodeModulus): promotion from
+       'char' to 'int' can be omitted, if both operands are 'unsigned char';
+       see feature request #877103
+       * src/SDCCval.c: updated call of decorateType()
+       (valBitwise): fixed bug #882876
+       (valMinus): added promotion
+       (valLogicAndOr): result is unsigned
+       (cheapestVal) (constVal): literals from 0...255 are 'unsigned char' now
+       * src/SDCCsymt.c (computeType),
+       * src/mcs51/gen.c (genCmpGt) (genCmpLt): literal 'unsigned char'
+       must not cause an unsigned operation
+       * src/pic/glue (pic14emitRegularMap),
+       * src/pic16/glue.c (pic16emitRegularMap): updated call of decorateType()
+
 2004-01-23 Bernhard Held <bernhard@bernhardheld.de>
 
        * src/pic/pcode.c (PCodeID): commented out left over debug code
index 56d377602d3544ac124199651ae5eea03b7aca42..7cb2e49bb65f86c95a5f2f4be39bca762272bd6f 100644 (file)
@@ -723,7 +723,7 @@ processParms (ast * func,
            actParm->decorated = 0;
            actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
                                         actParm->left);
-           actParm = decorateType(actParm);
+           actParm = decorateType(actParm, RESULT_CHECK);
          } else {
            newType = newAst_LINK(INTTYPE);
          }
@@ -743,13 +743,13 @@ processParms (ast * func,
       if (newType)
        {
          /* cast required; change this op to a cast. */
-         ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
+         ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
 
          actParm->type = EX_OP;
          actParm->opval.op = CAST;
          actParm->left = newType;
          actParm->right = parmCopy;
-         decorateType (actParm);
+         decorateType (actParm, RESULT_CHECK);
        }
       else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
        {
@@ -797,7 +797,7 @@ processParms (ast * func,
   /* if the parameter is castable then add the cast */
   if (compareType (defParm->type, actParm->ftype) < 0)
     {
-      ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
+      ast *pTree = decorateType(resolveSymbols (copyAst (actParm)), RESULT_CHECK);
 
       /* now change the current one to a cast */
       actParm->type = EX_OP;
@@ -807,7 +807,7 @@ processParms (ast * func,
       actParm->etype = defParm->etype;
       actParm->ftype = defParm->type;
       actParm->decorated=0; /* force typechecking */
-      decorateType (actParm);
+      decorateType (actParm, RESULT_CHECK);
     }
 
   /* make a copy and change the regparm type to the defined parm */
@@ -829,8 +829,8 @@ createIvalType (ast * sym, sym_link * type, initList * ilist)
   if (ilist->type == INIT_DEEP)
     ilist = ilist->init.deep;
 
-  iExpr = decorateType (resolveSymbols (list2expr (ilist)));
-  return decorateType (newNode ('=', sym, iExpr));
+  iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
+  return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
 }
 
 /*-----------------------------------------------------------------*/
@@ -860,8 +860,8 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist)
        break;
       sflds->implicit = 1;
       lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
-      lAst = decorateType (resolveSymbols (lAst));
-      rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
+      lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
+      rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
     }
 
   if (iloop) {
@@ -891,9 +891,9 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
   if (IS_CHAR (type->next))
     if ((rast = createIvalCharPtr (sym,
                                   type,
-                       decorateType (resolveSymbols (list2expr (ilist))))))
+                       decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
 
-      return decorateType (resolveSymbols (rast));
+      return decorateType (resolveSymbols (rast), RESULT_CHECK);
 
     /* not the special case             */
     if (ilist->type != INIT_DEEP)
@@ -909,7 +909,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
     {
        ast *aSym;
 
-       aSym = decorateType (resolveSymbols(sym));
+       aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
        
        rast = newNode(ARRAYINIT, aSym, NULL);
        rast->values.constlist = literalL;
@@ -937,7 +937,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
            ast *aSym;
            
            aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
-           aSym = decorateType (resolveSymbols (aSym));
+           aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
            rast = createIval (aSym, type->next, iloop, rast);
            iloop = (iloop ? iloop->next : NULL);
            if (!iloop)
@@ -965,7 +965,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
        DCL_ELEM (type) = size;
     }
 
-    return decorateType (resolveSymbols (rast));
+    return decorateType (resolveSymbols (rast), RESULT_CHECK);
 }
 
 
@@ -1019,7 +1019,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
       // now WE don't need iexpr's symbol anymore
       freeStringSymbol(AST_SYMBOL(iexpr));
 
-      return decorateType (resolveSymbols (rast));
+      return decorateType (resolveSymbols (rast), RESULT_CHECK);
     }
 
   return NULL;
@@ -1038,7 +1038,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist)
   if (ilist->type == INIT_DEEP)
     ilist = ilist->init.deep;
 
-  iexpr = decorateType (resolveSymbols (list2expr (ilist)));
+  iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
 
   /* if character pointer */
   if (IS_CHAR (type->next))
@@ -1076,9 +1076,9 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
     rast = createIvalType (sym, type, ilist);
 
   if (wid)
-    return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
+    return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
   else
-    return decorateType (resolveSymbols (rast));
+    return decorateType (resolveSymbols (rast), RESULT_CHECK);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1294,7 +1294,7 @@ bool constExprTree (ast *cexpr) {
     return TRUE;
   }
 
-  cexpr = decorateType (resolveSymbols (cexpr));
+  cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
 
   switch (cexpr->type) 
     {
@@ -1358,7 +1358,7 @@ bool constExprTree (ast *cexpr) {
 value *
 constExprValue (ast * cexpr, int check)
 {
-  cexpr = decorateType (resolveSymbols (cexpr));
+  cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
 
   /* if this is not a constant then */
   if (!IS_LITERAL (cexpr->ftype))
@@ -1951,7 +1951,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
                                                  rloop))));
 
   rloop->lineno=init->lineno;
-  return decorateType (rloop);
+  return decorateType (rloop, RESULT_CHECK);
 
 }
 
@@ -2005,15 +2005,122 @@ searchLitOp (ast *tree, ast **parent, const char *ops)
 }
 
 /*-----------------------------------------------------------------*/
-/* decorateType - compute type for this tree also does type checking */
-/*          this is done bottom up, since type have to flow upwards */
-/*          it also does constant folding, and paramater checking  */
+/* getResultFromType                                               */
 /*-----------------------------------------------------------------*/
+static RESULT_TYPE
+getResultTypeFromType (sym_link *type)
+{
+  /* type = getSpec (type); */
+  if (IS_BITVAR (type))
+    return RESULT_TYPE_BIT;
+  if (IS_BITFIELD (type))
+    return RESULT_TYPE_CHAR;
+  if (IS_CHAR (type))
+    return RESULT_TYPE_CHAR;
+  if (   IS_INT (type)
+      && !IS_LONG (type))
+    return RESULT_TYPE_INT;
+  return RESULT_TYPE_OTHER;
+}
+
+/*-----------------------------------------------------------------*/
+/* addCast - adds casts to a type specified by RESULT_TYPE         */
+/*-----------------------------------------------------------------*/
+static void
+addCast (ast **tree, RESULT_TYPE resultType)
+{
+  sym_link *newLink;
+  
+  switch (resultType)
+    {
+      case RESULT_TYPE_CHAR:
+       if (getSize ((*tree)->etype) <= 1)
+         return;
+       newLink = newCharLink();
+       break;
+      case RESULT_TYPE_INT:
+#if 0
+        /* casting from long to int costs additional 4 bytes dram! */
+       if (getSize ((*tree)->etype) <= INTSIZE)
+         return;
+       newLink = newIntLink();
+       break;
+#else
+        /* warn ("Loosing significant digits"); */
+       return;
+#endif
+      default:
+       return;
+    }
+  (*tree)->decorated = 0;
+  *tree = newNode (CAST, newAst_LINK (newLink), *tree);
+  /* keep unsigned type */
+  SPEC_USIGN ((*tree)->left->opval.lnk) = IS_UNSIGNED ((*tree)->right->etype) ? 1 : 0;
+  *tree = decorateType (*tree, resultType);
+}
+
+/*-----------------------------------------------------------------*/
+/* resultTypePropagate - decides if resultType can be propagated   */
+/*-----------------------------------------------------------------*/
+static RESULT_TYPE
+resultTypePropagate (ast *tree, RESULT_TYPE resultType)
+{
+  switch (tree->opval.op)
+    {
+      case '=':
+      case '?':
+      case ':':
+      case '|':
+      case '^':
+       return resultType;
+      case '&':
+       if (!tree->right)
+         /* can be unary */
+         return RESULT_TYPE_NONE;
+       else
+         return resultType;
+      default:
+       return RESULT_TYPE_NONE;
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* getLeftResultType - gets type from left branch for propagation  */
+/*-----------------------------------------------------------------*/
+static RESULT_TYPE
+getLeftResultType (ast *tree, RESULT_TYPE resultType)
+{
+  switch (tree->opval.op)
+    {
+      case '=':
+      case CAST:
+       if (IS_PTR (tree->left->ftype))
+         return RESULT_TYPE_NONE;
+       else
+         return getResultTypeFromType (tree->left->etype);
+      case RETURN:
+       if (IS_PTR (currFunc->type->next))
+         return RESULT_TYPE_NONE;
+       else
+         return getResultTypeFromType (currFunc->type->next);
+      default:
+       return 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  */
+/* result is a char and the operand(s) are int's.                     */
+/* It also does constant folding, and parameter checking.             */
+/*--------------------------------------------------------------------*/
 ast *
-decorateType (ast * tree)
+decorateType (ast * tree, RESULT_TYPE resultType)
 {
   int parmNumber;
   sym_link *p;
+  RESULT_TYPE resultTypeProp;
 
   if (!tree)
     return tree;
@@ -2045,7 +2152,7 @@ decorateType (ast * tree)
 
 /*------------------------------------------------------------------*/
 /*----------------------------*/
-  /*   leaf has been reached    */
+/*   leaf has been reached    */
 /*----------------------------*/
   lineno=tree->lineno;
   /* if this is of type value */
@@ -2130,11 +2237,26 @@ decorateType (ast * tree)
          }
       }
     #endif
+
+    /* Before decorating the left branch we've to decide in dependence
+       upon tree->opval.op, if resultType can be propagated */
+    if (getenv ("SDCC_NEWTYPEFLOW"))
+      resultTypeProp = resultTypePropagate (tree, resultType);
+    else
+      resultTypeProp = RESULT_TYPE_NONE; /* provide initialization */
+
+    dtl = decorateType (tree->left, resultTypeProp);
+
+    /* After decorating the left branch there's type information available
+       in tree->left->?type. If the op is e.g. '=' we extract the type
+       information from there and propagate it to the right branch. */
+    if (getenv ("SDCC_NEWTYPEFLOW"))
+      resultTypeProp = getLeftResultType (tree, resultTypeProp);
     
-    dtl = decorateType (tree->left);
-    /* delay right side for '?' operator since conditional macro expansions might
-       rely on this */
-    dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
+    /* delay right side for '?' operator since conditional macro expansions
+       might rely on this */
+    dtr = tree->opval.op == '?' ? tree->right :
+                                  decorateType (tree->right, resultTypeProp);
 
     /* this is to take care of situations
        when the tree gets rewritten */
@@ -2145,25 +2267,28 @@ decorateType (ast * tree)
     if ((dtl && dtl->isError) || (dtr && dtr->isError))
       return tree;
 
-    if (IS_AST_OP(tree) &&
-       (tree->opval.op == CAST || tree->opval.op == '=') &&
-       (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
-       (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
-      // this is a cast/assign to a bigger type
-      if (IS_AST_OP(tree->right) &&
-         IS_INTEGRAL(tree->right->ftype) &&
-         (tree->right->opval.op == LEFT_OP ||
-          tree->right->opval.op == '*' ||
-          tree->right->opval.op == '+' ||
-          tree->right->opval.op == '-') &&
-         tree->right->right) {
-       // we should cast an operand instead of the result
-       tree->right->decorated = 0;
-       tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
-                                    tree->right->left);
-       tree->right = decorateType(tree->right);
+    if (!getenv ("SDCC_NEWTYPEFLOW"))
+      {
+        if (IS_AST_OP(tree) &&
+           (tree->opval.op == CAST || tree->opval.op == '=') &&
+           (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
+           (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
+          /* this is a cast/assign to a bigger type */
+         if (IS_AST_OP(tree->right) &&
+             IS_INTEGRAL(tree->right->ftype) &&
+             (tree->right->opval.op == LEFT_OP ||
+              tree->right->opval.op == '*' ||
+              tree->right->opval.op == '+' ||
+              tree->right->opval.op == '-') &&
+              tree->right->right) {
+           /* we should cast an operand instead of the result */
+           tree->right->decorated = 0;
+           tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
+                                        tree->right->left);
+           tree->right = decorateType(tree->right, RESULT_CHECK);
+          }
+        }
       }
-    }
   }
 
   /* depending on type of operator do */
@@ -2378,11 +2503,15 @@ decorateType (ast * tree)
            ast *otree = optimizeGetHbit (tree);
 
            if (otree != tree)
-             return decorateType (otree);
+             return decorateType (otree, RESULT_CHECK);
          }
 
-         TTYPE (tree) =
-           computeType (LTYPE (tree), RTYPE (tree), FALSE);
+         if (getenv ("SDCC_NEWTYPEFLOW"))
+           {
+             addCast (&tree->left,  resultType);
+             addCast (&tree->right, resultType);
+           }
+         TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
          TETYPE (tree) = getSpec (TTYPE (tree));
 
           /* if left is a literal exchange left & right */
@@ -2406,11 +2535,12 @@ decorateType (ast * tree)
                  litTree->left = tree->right;
                  tree->right = tTree;
                  /* both operands in tTree are literal now */
-                 decorateType (parent);
+                 decorateType (parent, RESULT_CHECK);
                }
            }
 
          LRVAL (tree) = RRVAL (tree) = 1;
+         
          return tree;
        }
 
@@ -2504,11 +2634,11 @@ decorateType (ast * tree)
       {
        ast *wtree = optimizeRRCRLC (tree);
        if (wtree != tree)
-         return decorateType (wtree);
+         return decorateType (wtree, RESULT_CHECK);
        
        wtree = optimizeSWAP (tree);
        if (wtree != tree)
-         return decorateType (wtree);
+         return decorateType (wtree, RESULT_CHECK);
       }
 
       /* if left is a literal exchange left & right */
@@ -2532,7 +2662,7 @@ decorateType (ast * tree)
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in tTree are literal now */
-             decorateType (parent);
+             decorateType (parent, RESULT_CHECK);
            }
         }
       /* fall through */
@@ -2589,11 +2719,16 @@ decorateType (ast * tree)
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in litTree are literal now */
-             decorateType (parent);
+             decorateType (parent, RESULT_CHECK);
            }
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
+      if (getenv ("SDCC_NEWTYPEFLOW"))
+        {
+          addCast (&tree->left,  resultType);
+          addCast (&tree->right, resultType);
+        }
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
@@ -2628,7 +2763,7 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           TRUE));
+               ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
 
       /* if right is a literal and */
       /* left is also a division by a literal then */
@@ -2648,15 +2783,15 @@ decorateType (ast * tree)
                  litTree->right->lineno = tree->lineno;
 
                  tree->right->opval.val = constVal ("1");
-                 decorateType (parent);
+                 decorateType (parent, RESULT_CHECK);
                }
              else
                {
                  /* litTree->left is literal: no gcse possible.
-                    We can't call decorateType(parent), because
+                    We can't call decorateType(parent, RESULT_CHECK), because
                     this would cause an infinit loop. */
                  parent->decorated = 1;
-                 decorateType (litTree);
+                 decorateType (litTree, RESULT_CHECK);
                }
            }
        }
@@ -2694,7 +2829,7 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           TRUE));
+               ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2799,16 +2934,26 @@ decorateType (ast * tree)
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in litTree are literal now */
-             decorateType (parent);
+             decorateType (parent, RESULT_CHECK);
            }
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      TETYPE (tree) = getSpec (TTYPE (tree) =
-                              computeType (LTYPE (tree),
-                                           RTYPE (tree),
-                                           TRUE));
-
+      if (!getenv ("SDCC_NEWTYPEFLOW"))
+        TETYPE (tree) = getSpec (TTYPE (tree) =
+                                computeType (LTYPE (tree),
+                                             RTYPE (tree),
+                                             TRUE));
+      else
+       {
+          addCast (&tree->left,  resultType);
+          addCast (&tree->right, resultType);
+         TETYPE (tree) = getSpec (TTYPE (tree) =
+                                  computeType (LTYPE (tree),
+                                               RTYPE (tree),
+                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+       }
+      
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2926,7 +3071,7 @@ decorateType (ast * tree)
                      tree->opval.op = '-';
                    }
                }
-             decorateType (parent);
+             decorateType (parent, RESULT_CHECK);
            }
        }
 
@@ -2936,10 +3081,21 @@ decorateType (ast * tree)
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 LTYPE (tree));
       else
-       TETYPE (tree) = getSpec (TTYPE (tree) =
-                                computeType (LTYPE (tree),
-                                             RTYPE (tree),
-                                             FALSE));
+        if (!getenv ("SDCC_NEWTYPEFLOW"))
+          TETYPE (tree) = getSpec (TTYPE (tree) =
+                                  computeType (LTYPE (tree),
+                                               RTYPE (tree),
+                                               FALSE));
+       else
+          {
+           addCast (&tree->left,  resultType);
+            addCast (&tree->right, resultType);
+            TETYPE (tree) = getSpec (TTYPE (tree) =
+                                    computeType (LTYPE (tree),
+                                                 RTYPE (tree),
+                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+          }
+       
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -3036,10 +3192,20 @@ decorateType (ast * tree)
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 LTYPE (tree));
       else
-       TETYPE (tree) = getSpec (TTYPE (tree) =
-                                computeType (LTYPE (tree),
-                                             RTYPE (tree),
-                                             FALSE));
+        if (!getenv ("SDCC_NEWTYPEFLOW"))
+          TETYPE (tree) = getSpec (TTYPE (tree) =
+                                  computeType (LTYPE (tree),
+                                               RTYPE (tree),
+                                               FALSE));
+       else
+         {
+           addCast (&tree->left,  resultType);
+           addCast (&tree->right, resultType);
+           TETYPE (tree) = getSpec (TTYPE (tree) =
+                                    computeType (LTYPE (tree),
+                                                 RTYPE (tree),
+                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
 
@@ -3080,7 +3246,7 @@ decorateType (ast * tree)
                      tree->right = tTree;
                    }
                }
-             decorateType (litParent);
+             decorateType (litParent, RESULT_CHECK);
            }
        }
       return tree;
@@ -3182,11 +3348,20 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       if (tree->opval.op == LEFT_OP)
        {
-         /* promote char to int */
-         TETYPE (tree) = getSpec (TTYPE (tree) =
-                                  computeType (LTYPE (tree),
-                                               LTYPE (tree), /* no, not RTYPE! */
-                                               TRUE));
+         if (!getenv ("SDCC_NEWTYPEFLOW"))
+           /* promote char to int */
+           TETYPE (tree) = getSpec (TTYPE (tree) =
+                                    computeType (LTYPE (tree),
+                                                 LTYPE (tree), /* no, not RTYPE! */
+                                                 TRUE));
+         else
+           {
+             addCast (&tree->left,  resultType);
+             TETYPE (tree) = getSpec (TTYPE (tree) =
+                                      computeType (LTYPE (tree),
+                                                   RTYPE (tree),
+                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+           }
        }
       else /* RIGHT_OP */
        {
@@ -3496,7 +3671,9 @@ decorateType (ast * tree)
        }
       /* if unsigned value < 0  then always false */
       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
-      if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  &&
+      if (SPEC_USIGN(LETYPE(tree)) &&
+          !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
+          IS_LITERAL(RTYPE(tree))  &&
          ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
        {
          if (tree->opval.op == '<')
@@ -3513,7 +3690,7 @@ decorateType (ast * tree)
                                     tree->right); /* val 0 */
              tree->right->lineno = tree->lineno;
              tree->right->left->lineno = tree->lineno;
-             decorateType (tree->right);
+             decorateType (tree->right, RESULT_CHECK);
            }
         }
       /* if they are both literal then */
@@ -3630,20 +3807,22 @@ decorateType (ast * tree)
       /*----------------------------*/
     case '?':
       /* the type is value of the colon operator (on the right) */
-      assert(IS_COLON_OP(tree->right));
+      assert (IS_COLON_OP (tree->right));
       /* if already known then replace the tree : optimizer will do it
         but faster to do it here */
-      if (IS_LITERAL (LTYPE(tree))) {    
-         if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
-             return decorateType(tree->right->left) ;
-         } else {
-             return decorateType(tree->right->right) ;
-         }
-      } else {
-         tree->right = decorateType(tree->right);
-         TTYPE (tree) = RTYPE(tree);
+      if (IS_LITERAL (LTYPE (tree)))
+       {
+         if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
+            return decorateType (tree->right->left, resultTypeProp);
+         else
+           return decorateType (tree->right->right, resultTypeProp);
+       }
+      else
+       {
+         tree->right = decorateType (tree->right, resultTypeProp);
+         TTYPE (tree) = RTYPE (tree);
          TETYPE (tree) = getSpec (TTYPE (tree));
-      }
+       }
       return tree;
 
     case ':':
@@ -3790,7 +3969,7 @@ decorateType (ast * tree)
          goto errorTreeReturn;
        }
 
-      tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
+      tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
       tree->opval.op = '=';
 
       return tree;
@@ -3897,13 +4076,14 @@ decorateType (ast * tree)
          goto errorTreeReturn;
        }
 
-      /* if there is going to be a casing required then add it */
+      /* if there is going to be a casting required then add it */
       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
        {
          tree->right =
            decorateType (newNode (CAST,
-                          newAst_LINK (copyLinkChain (currFunc->type->next)),
-                                  tree->right));
+                         newAst_LINK (copyLinkChain (currFunc->type->next)),
+                                       tree->right),
+                         RESULT_CHECK);
        }
 
       RRVAL (tree) = 1;
@@ -3952,9 +4132,9 @@ decorateType (ast * tree)
       /*----------------------------*/
     case FOR:
 
-      decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
-      decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
-      decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
+      decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
+      decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
+      decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
 
       /* if the for loop is reversible then
          reverse it otherwise do what we normally
@@ -3973,7 +4153,7 @@ decorateType (ast * tree)
                                          AST_FOR (tree, initExpr),
                                          AST_FOR (tree, condExpr),
                                          AST_FOR (tree, loopExpr),
-                                         tree->left));
+                                         tree->left), RESULT_CHECK);
       }
     default:
       TTYPE (tree) = TETYPE (tree) = NULL;
@@ -4189,7 +4369,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
       return NULL;
     }
 
-  caseVal = decorateType (resolveSymbols (caseVal));
+  caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
   /* if not a constant then error  */
   if (!IS_LITERAL (caseVal->ftype))
     {
@@ -4547,7 +4727,7 @@ optimizeGetHbit (ast * tree)
       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
     return tree;
 
-  return decorateType (newNode (GETHBIT, tree->left->left, NULL));
+  return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
 
 }
 
@@ -4814,7 +4994,7 @@ optimizeCompare (ast * root)
          break;
        }
 
-      return decorateType (optExpr);
+      return decorateType (optExpr, RESULT_CHECK);
     }
 
   vleft = (root->left->type == EX_VALUE ?
@@ -4888,7 +5068,7 @@ optimizeCompare (ast * root)
              break;
            }
        }
-      return decorateType (resolveSymbols (optExpr));
+      return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
     }                          /* end-of-if of BITVAR */
 
 noOptimize:
@@ -5034,7 +5214,8 @@ createFunction (symbol * name, ast * body)
   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
 
   body = resolveSymbols (body);        /* resolve the symbols */
-  body = decorateType (body);  /* propagateType & do semantic checks */
+  body = decorateType (body, RESULT_TYPE_NONE);        /* propagateType & do semantic checks */
+                                       
 
   ex = newAst_VALUE (symbolVal (name));        /* create name */
   ex = newNode (FUNCTION, ex, body);
@@ -5065,7 +5246,7 @@ createFunction (symbol * name, ast * body)
     {
       GcurMemmap = statsg;
       codeOutFile = statsg->oFile;
-      eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
+      eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
       staticAutos = NULL;
     }
 
index 649960e7f0177e762dc4082370bc70cb3cac3086..5546f10702ddc8d77e2d479d2d4b6f76dde50020 100644 (file)
@@ -170,6 +170,16 @@ ast;
                          x == AND_ASSIGN || x == OR_ASSIGN || x == INC_OP || x == DEC_OP)
 #define IS_DEREF_OP(x) (( x->opval.op == '*' && x->right == NULL) || x->opval.op == '.')
 
+typedef enum
+{
+  RESULT_TYPE_NONE = 0,
+  RESULT_CHECK = 0, /* TODO: replace all occurences with the appropriate type and remove me */
+  RESULT_TYPE_BIT,
+  RESULT_TYPE_CHAR,
+  RESULT_TYPE_INT,
+  RESULT_TYPE_OTHER
+} RESULT_TYPE;
+
 /* forward declarations for global variables */
 extern ast *staticAutos;
 extern FILE *codeOutFile;
@@ -196,7 +206,7 @@ ast *createDefault (ast *, ast *, ast *);
 ast *forLoopOptForm (ast *);
 ast *argAst (ast *);
 ast *resolveSymbols (ast *);
-ast *decorateType (ast *);
+ast *decorateType (ast *, RESULT_TYPE);
 ast *createWhile (symbol *, symbol *, symbol *, ast *, ast *);
 ast *createIf (ast *, ast *, ast *);
 ast *createDo (symbol *, symbol *, symbol *, ast *, ast *);
index e0f6834317db377117e020d2ef17c9a1450a70a5..fbf94e769ef963840aa333b199078c7000c011be 100644 (file)
@@ -308,7 +308,7 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                      sym->name);
            }
            ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
-                           decorateType (resolveSymbols (list2expr (sym->ival))));
+                           decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
          }
          codeOutFile = statsg->oFile;
 
index 48cc6eabca252a2b42a071114759de04c8582bce..d166b186643f7ecd168bda05c92453a905692b0d 100644 (file)
@@ -2059,7 +2059,9 @@ geniCodeDivision (operand * left, operand * right)
   sym_link *ltype = operandType (left);
   sym_link *letype = getSpec (ltype);
 
-  resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
+  resType = usualBinaryConversions (&left, &right,
+              (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
+             FALSE);
 
   /* if the right is a literal & power of 2
      and left is unsigned then make it a
@@ -2098,7 +2100,9 @@ geniCodeModulus (operand * left, operand * right)
     return operandFromValue (valMod (left->operand.valOperand,
                                     right->operand.valOperand));
 
-  resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
+  resType = usualBinaryConversions (&left, &right,
+              (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
+             FALSE);
 
   /* now they are the same size */
   ic = newiCode ('%', left, right);
index 4b4e00c415d2b9b4fe3e0205de41d813fb1c5985..d3bfee79b661bfee51ab05509da4d5798c60753d 100644 (file)
@@ -1554,9 +1554,16 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
     SPEC_NOUN (reType) = V_INT;
 
   if (   (   (   SPEC_USIGN (etype1)
-             && (getSize (etype1) >= getSize (reType)))
+              /* if this operand is promoted to a larger
+                type don't check it's signedness */
+             && (getSize (etype1) >= getSize (reType))
+             /* We store signed literals in the range 0...255 as
+                'unsigned char'. If there was no promotion to 'signed int'
+                they must not force an unsigned operation: */
+             && !(IS_CHAR (etype1) && IS_LITERAL (etype1)))
          || (   SPEC_USIGN (etype2)
-             && (getSize (etype2) >= getSize (reType))))
+             && (getSize (etype2) >= getSize (reType))
+             && !(IS_CHAR (etype2) && IS_LITERAL (etype2))))
       && !IS_FLOAT (reType))
     SPEC_USIGN (reType) = 1;
   else
index 6d1e5cc91c0c9e6fda22157e8dd7f9f88d72d881..0020b56c5723debdcffa2476c430a7500b5c22bb 100644 (file)
@@ -119,7 +119,7 @@ convertIListToConstList(initList *src, literalList **lList)
            return FALSE;
        }
 
-       if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
+       if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_CHECK)))
        {
            return FALSE;
        }
@@ -275,7 +275,7 @@ resolveIvalSym (initList * ilist)
     return;
 
   if (ilist->type == INIT_NODE)
-    ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
+    ilist->init.node = decorateType (resolveSymbols (ilist->init.node), RESULT_CHECK);
 
   if (ilist->type == INIT_DEEP)
     resolveIvalSym (ilist->init.deep);
@@ -389,18 +389,17 @@ static value *cheapestVal (value *val)
       !SPEC_USIGN(val->type) &&
       !SPEC_LONG(val->type) &&
       SPEC_CVAL(val->type).v_int >= -128 &&
-      SPEC_CVAL(val->type).v_int <=  127)
+      SPEC_CVAL(val->type).v_int <     0)
 
     {
       SPEC_NOUN(val->type) = V_CHAR;
     }
-  /* this could be too aggressive:
-     'unsigned char' promotes to 'signed int', so that we can
+  /* 'unsigned char' promotes to 'signed int', so that we can
      reduce it the other way */
   if (IS_INT(val->type) &&
       !SPEC_USIGN(val->type) &&
       !SPEC_LONG(val->type) &&
-      SPEC_CVAL(val->type).v_int >= 128 &&
+      SPEC_CVAL(val->type).v_int >=   0 &&
       SPEC_CVAL(val->type).v_int <= 255)
 
     {
@@ -526,19 +525,8 @@ value *constVal (char *s)
                                     the programer wants */
       SPEC_NOUN (val->type) = V_INT;
     }
-    else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
-#if 0
-      if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
-          dval<=0xff) {
-        SPEC_USIGN (val->type) = 1;
-      } else {
-       SPEC_NOUN (val->type) = V_INT;
-      }
-#else
-      /* this is quite agressive: 'unsigned char' will be promoted to 'signed int',
-         so that the signedness of a char shouldn't matter */
+    else { /* store char's always as unsigned; this helps other optimizations */
       SPEC_USIGN (val->type) = 1;
-#endif
     }
     if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
       SPEC_LONG (val->type) = 1;
@@ -1267,7 +1255,7 @@ valMinus (value * lval, value * rval)
   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
   SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
                                                    rval->etype,
-                                                   FALSE));
+                                                   TRUE));
   if (IS_FLOAT (val->type))
     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
   else  if (SPEC_LONG (val->type))
@@ -1455,9 +1443,9 @@ valBitwise (value * lval, value * rval, int op)
 
   /* create a new value */
   val = newValue ();
-  val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
-                            rval->type : lval->type);
+  val->type = computeType (lval->etype, rval->etype, FALSE);
   val->etype = getSpec (val->type);
+  SPEC_SCLS (val->etype) = S_LITERAL;
 
   switch (op)
     {
@@ -1465,19 +1453,19 @@ valBitwise (value * lval, value * rval, int op)
       if (SPEC_LONG (val->type))
        {
          if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
-             (unsigned long) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
+             (TYPE_UDWORD) floatFromVal (rval);
          else
-           SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
-             (long) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
+             (TYPE_DWORD) floatFromVal (rval);
        }
       else
        {
          if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
-             (unsigned) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
+             (TYPE_UWORD) floatFromVal (rval);
          else
-           SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
        }
       break;
 
@@ -1485,20 +1473,20 @@ valBitwise (value * lval, value * rval, int op)
       if (SPEC_LONG (val->type))
        {
          if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
-             (unsigned long) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
+             (TYPE_UDWORD) floatFromVal (rval);
          else
-           SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
-             (long) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
+             (TYPE_DWORD) floatFromVal (rval);
        }
       else
        {
          if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
-             (unsigned) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
+             (TYPE_UWORD) floatFromVal (rval);
          else
            SPEC_CVAL (val->type).v_int =
-             (int) floatFromVal (lval) | (int) floatFromVal (rval);
+             (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
        }
 
       break;
@@ -1507,24 +1495,24 @@ valBitwise (value * lval, value * rval, int op)
       if (SPEC_LONG (val->type))
        {
          if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
-             (unsigned long) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
+             (TYPE_UDWORD) floatFromVal (rval);
          else
-           SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
-             (long) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
+             (TYPE_DWORD) floatFromVal (rval);
        }
       else
        {
          if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
-             (unsigned) floatFromVal (rval);
+           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
+             (TYPE_UWORD) floatFromVal (rval);
          else
            SPEC_CVAL (val->type).v_int =
-             (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
+             (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
        }
       break;
     }
-
+    
   return cheapestVal(val);
 }
 
@@ -1541,7 +1529,7 @@ valLogicAndOr (value * lval, value * rval, int op)
   val->type = val->etype = newCharLink ();
   val->type->class = SPECIFIER;
   SPEC_SCLS (val->type) = S_LITERAL;   /* will remain literal */
-  SPEC_USIGN (val->type) = 0;
+  SPEC_USIGN (val->type) = 1;
 
   switch (op)
     {
index 20ad91eb614a24e23ca385f96c88d7801676ccc6..c3a96b8da557695ed7b713414ab8f3f2acfcd6e5 100644 (file)
@@ -4334,7 +4334,8 @@ genCmpGt (iCode * ic, iCode * ifx)
 
   letype = getSpec (operandType (left));
   retype = getSpec (operandType (right));
-  sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
+  sign = !((SPEC_USIGN (letype) && !(IS_CHAR (letype) && IS_LITERAL (letype))) ||
+           (SPEC_USIGN (retype) && !(IS_CHAR (retype) && IS_LITERAL (retype))));
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
@@ -4363,8 +4364,8 @@ genCmpLt (iCode * ic, iCode * ifx)
 
   letype = getSpec (operandType (left));
   retype = getSpec (operandType (right));
-  sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
-
+  sign = !((SPEC_USIGN (letype) && !(IS_CHAR (letype) && IS_LITERAL (letype))) ||
+           (SPEC_USIGN (retype) && !(IS_CHAR (retype) && IS_LITERAL (retype))));
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
index 654d9c331d3f052de7b5b64274419b071229a897..dbedaff604f21969879ccaa68e478114cfef8f44 100644 (file)
@@ -212,7 +212,7 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
        ival = initAggregates (sym, sym->ival, NULL);
       else
        ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
-                       decorateType (resolveSymbols (list2expr (sym->ival))));
+                       decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
       codeOutFile = statsg->oFile;
       GcurMemmap = statsg;
       eBBlockFromiCode (iCodeFromAst (ival));
index f02dd928d0897273c1e7ef4c682918abdd723c82..1a6cf051223cd879c004e9c1481f910d6a380294 100644 (file)
@@ -240,7 +240,7 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                ival = initAggregates (sym, sym->ival, NULL);
                        else
                                ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
-                                       decorateType (resolveSymbols (list2expr (sym->ival))));
+                                       decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
                        codeOutFile = statsg->oFile;
                        GcurMemmap = statsg;
                        eBBlockFromiCode (iCodeFromAst (ival));