* device/lib/medium/Makefile: added for new memory model medium
[fw/sdcc] / src / SDCCcse.c
index 4b524b0bf5fb1b82e0a148e3da5e11687f523563..a2cc6ef0130079eafb106019b0a3caca65ba1ac0 100644 (file)
@@ -492,7 +492,7 @@ DEFSETFUNC (findPrevIc)
   /* if iCodes are not the same */
   /* see the operands maybe interchanged */
   if (ic->op == cdp->diCode->op &&
-      (ic->op == '+' || ic->op == '*') &&
+      IS_ASSOCIATIVE(ic) &&
       isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
       isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
     {
@@ -818,7 +818,8 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
     case '+':
       /* if adding the same thing change to left shift by 1 */
       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
-          !IS_FLOAT (operandType (IC_RESULT (ic))))
+          !(IS_FLOAT (operandType (IC_RESULT (ic)))
+            || IS_FIXED(operandType (IC_RESULT (ic)))))
         {
           ic->op = LEFT_OP;
           IC_RIGHT (ic) = operandFromLit (1);
@@ -829,8 +830,10 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
           operandLitValue (IC_LEFT (ic)) == 0.0)
         {
-          if (compareType (operandType (IC_RESULT (ic)),
-                           operandType (IC_RIGHT (ic)))<0)
+          int typematch;
+          typematch = compareType (operandType (IC_RESULT (ic)),
+                                   operandType (IC_RIGHT (ic)));
+          if (typematch<0)
             {
               ic->op = CAST;
               IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
@@ -839,6 +842,12 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               ic->op = '=';
               IC_LEFT (ic) = NULL;
+              if (typematch==0)
+                {
+                  /* for completely different types, preserve the source type */
+                  IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+                  setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+                }
             }
           SET_ISADDR (IC_RESULT (ic), 0);
           SET_ISADDR (IC_RIGHT (ic), 0);
@@ -847,8 +856,10 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
           operandLitValue (IC_RIGHT (ic)) == 0.0)
         {
-          if (compareType (operandType (IC_RESULT (ic)),
-                           operandType (IC_LEFT (ic)))<0)
+          int typematch;
+          typematch = compareType (operandType (IC_RESULT (ic)),
+                                   operandType (IC_LEFT (ic)));
+          if (typematch<0)
             {
               ic->op = CAST;
               IC_RIGHT (ic) = IC_LEFT (ic);
@@ -859,6 +870,12 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
               ic->op = '=';
               IC_RIGHT (ic) = IC_LEFT (ic);
               IC_LEFT (ic) = NULL;
+              if (typematch==0)
+                {
+                  /* for completely different types, preserve the source type */
+                  IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+                  setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+                }
             }
           SET_ISADDR (IC_RIGHT (ic), 0);
           SET_ISADDR (IC_RESULT (ic), 0);
@@ -1735,6 +1752,9 @@ static int isSignedOp (iCode *ic)
     case RRC:
     case RLC:
     case GETHBIT:
+    case GETABIT:
+    case GETBYTE:
+    case GETWORD:
     case RIGHT_OP:
     case CAST:
     case ARRAYINIT: