* device/lib/Makefile.in: remove abspath for PORTDIR, introduced in
[fw/sdcc] / src / SDCCopt.c
index e88c3050d8b1dcad192dc7d7893aaa3bf6c266ef..c799bed2de0d887594170d6d07572d85bd821638 100644 (file)
@@ -58,6 +58,7 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
   operand *left;
   operand *right;
   symbol *func = NULL;
+  char *filename = ic->filename;
   int lineno = ic->lineno;
   int bytesPushed=0;
 
@@ -68,7 +69,12 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
   left = IC_LEFT (ic);
   right = IC_RIGHT (ic);
 
-  if(IS_FLOAT(operandType( IC_RIGHT( ic ) ))) {
+  if (IS_SYMOP (left))
+      bitVectUnSetBit (OP_USES (left), ic->key);
+  if (IS_SYMOP (right))
+      bitVectUnSetBit (OP_USES (right), ic->key);
+
+  if (IS_FLOAT (operandType (right))) {
     switch (ic->op)
       {
       case '+':
@@ -103,7 +109,7 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
         break;
       }
   } else
-  if(IS_FIXED16X16 (operandType (IC_RIGHT(ic)))) {
+  if (IS_FIXED16X16 (operandType (right))) {
     switch (ic->op)
       {
       case '+':
@@ -138,7 +144,7 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
         break;
       }
   }
-  
+
 
   /* if float support routines NOT compiled as reentrant */
   if (!options.float_rent)
@@ -147,31 +153,37 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
       /* first one */
       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
         {
-          newic = newiCode (SEND, IC_LEFT (ic), NULL);
+          newic = newiCode (SEND, left, NULL);
           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
         }
       else
         {
-          newic = newiCode ('=', NULL, IC_LEFT (ic));
+          newic = newiCode ('=', NULL, left);
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
         }
 
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
+      if (IS_SYMOP (left))
+          OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
 
       /* second one */
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
         {
-          newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+          newic = newiCode (SEND, right, NULL);
           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
         }
       else
         {
-          newic = newiCode ('=', NULL, IC_RIGHT (ic));
+          newic = newiCode ('=', NULL, right);
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
+      if (IS_SYMOP (right))
+          OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
 
     }
   else
@@ -187,12 +199,14 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
         {
           newic = newiCode (IPUSH, right, NULL);
           newic->parmPush = 1;
-          //bytesPushed+=4;
           bytesPushed += getSize(operandType(right));
         }
 
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
+      if (IS_SYMOP (right))
+          OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
 
       /* insert push left */
       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
@@ -204,17 +218,23 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
         {
           newic = newiCode (IPUSH, left, NULL);
           newic->parmPush = 1;
-          //bytesPushed+=4;
           bytesPushed += getSize(operandType(left));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
+      if (IS_SYMOP (left))
+          OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
+
     }
   /* insert the call */
   newic = newiCode (CALL, operandFromSymbol (func), NULL);
   IC_RESULT (newic) = IC_RESULT (ic);
+  bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+  OP_USES (IC_RESULT (newic)) = bitVectSetBit (OP_USES (IC_RESULT (newic)), newic->key);
+  newic->filename = filename;
   newic->lineno = lineno;
-  newic->parmBytes+=bytesPushed;
+  newic->parmBytes += bytesPushed;
   ebp->hasFcall = 1;
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
@@ -226,9 +246,9 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
         if(!SPEC_EXTR(func->etype)) {
             memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
 
-                SPEC_EXTR(func->etype) = 1;
-                seg = SPEC_OCLS( func->etype );
-                addSet(&seg->syms, func);
+            SPEC_EXTR(func->etype) = 1;
+            seg = SPEC_OCLS( func->etype );
+            addSet(&seg->syms, func);
         }
   }
 
@@ -276,7 +296,7 @@ found:
   if (!options.float_rent)
     {
       /* first one */
-      if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) 
+      if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
         {
           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
@@ -287,6 +307,7 @@ found:
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = linenno;
 
     }
@@ -304,8 +325,8 @@ found:
         bytesPushed += getSize(operandType(IC_RIGHT(ic)));
       }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = linenno;
-
     }
 
   /* make the call */
@@ -317,26 +338,27 @@ found:
     FUNC_HASFCALL (currFunc->type) = 1;
 
   if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
-       /* normally these functions aren't marked external, so we can use their
-        * _extern field to marked as already added to symbol table */
-
-       if(!SPEC_EXTR(func->etype)) {
-           memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
-               
-               SPEC_EXTR(func->etype) = 1;
-               seg = SPEC_OCLS( func->etype );
-               addSet(&seg->syms, func);
-       }
+        /* normally these functions aren't marked external, so we can use their
+         * _extern field to marked as already added to symbol table */
+
+        if(!SPEC_EXTR(func->etype)) {
+            memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+            SPEC_EXTR(func->etype) = 1;
+            seg = SPEC_OCLS( func->etype );
+            addSet(&seg->syms, func);
+        }
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
   newic->lineno = linenno;
 }
 
 /*----------------------------------------------------------------------*/
 /* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
 /*----------------------------------------------------------------------*/
-static void 
+static void
 cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
 {
   iCode *ip, *newic;
@@ -353,13 +375,13 @@ cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
-       {
-         if (compareType (type, __multypes[bwd][su]) == 1)
-           {
-             func = __fp16x16conv[0][bwd][su];
-             goto found;
-           }
-       }
+        {
+          if (compareType (type, __multypes[bwd][su]) == 1)
+            {
+              func = __fp16x16conv[0][bwd][su];
+              goto found;
+            }
+        }
     }
   assert (0);
 found:
@@ -379,6 +401,7 @@ found:
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = linenno;
 
     }
@@ -396,8 +419,8 @@ found:
           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = linenno;
-
     }
 
   /* make the call */
@@ -422,6 +445,7 @@ found:
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
   newic->lineno = linenno;
 }
 
@@ -434,6 +458,7 @@ cnvFromFloatCast (iCode * ic, eBBlock * ebp)
   iCode *ip, *newic;
   symbol *func = NULL;
   sym_link *type = operandType (IC_LEFT (ic));
+  char *filename = ic->filename;
   int lineno = ic->lineno;
   int bwd, su;
   int bytesPushed=0;
@@ -471,6 +496,7 @@ found:
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
@@ -489,6 +515,7 @@ found:
           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
@@ -515,18 +542,20 @@ found:
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
   newic->lineno = lineno;
 }
 
 /*--------------------------------------------------------------------------*/
 /* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
 /*--------------------------------------------------------------------------*/
-static void 
+static void
 cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
 {
   iCode *ip, *newic;
   symbol *func = NULL;
   sym_link *type = operandType (IC_LEFT (ic));
+  char *filename = ic->filename;
   int lineno = ic->lineno;
   int bwd, su;
   int bytesPushed=0;
@@ -547,13 +576,13 @@ cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
             }
         }
     }
-    
+
   if (compareType (type, floatType) == 1)
     {
       func = __fp16x16conv[1][3][0];
       goto found;
     }
-    
+
   assert (0);
 found:
 
@@ -571,8 +600,8 @@ found:
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
-
     }
   else
     {
@@ -589,8 +618,8 @@ found:
           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
-
     }
 
   /* make the call */
@@ -602,19 +631,20 @@ found:
     FUNC_HASFCALL (currFunc->type) = 1;
 
   if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
-       /* normally these functions aren't marked external, so we can use their
-        * _extern field to marked as already added to symbol table */
-
-       if(!SPEC_EXTR(func->etype)) {
-           memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
-               
-               SPEC_EXTR(func->etype) = 1;
-               seg = SPEC_OCLS( func->etype );
-               addSet(&seg->syms, func);
-       }
+        /* normally these functions aren't marked external, so we can use their
+         * _extern field to marked as already added to symbol table */
+
+        if(!SPEC_EXTR(func->etype)) {
+            memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+                SPEC_EXTR(func->etype) = 1;
+                seg = SPEC_OCLS( func->etype );
+                addSet(&seg->syms, func);
+        }
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
   newic->lineno = lineno;
 }
 
@@ -624,25 +654,59 @@ extern operand *geniCodeRValue (operand *, bool);
 /* convilong - converts int or long mults or divs to fcalls        */
 /*-----------------------------------------------------------------*/
 static void
-convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
+convilong (iCode * ic, eBBlock * ebp)
 {
+  int op = ic->op;
   symbol *func = NULL;
   iCode *ip = ic->next;
   iCode *newic;
+  char *filename = ic->filename;
   int lineno = ic->lineno;
   int bwd;
   int su;
   int bytesPushed=0;
+  sym_link *leftType = operandType (IC_LEFT (ic));
+  sym_link *rightType = operandType (IC_RIGHT (ic));
 
   remiCodeFromeBBlock (ebp, ic);
 
+  if (getSize (leftType) == 1 && getSize (rightType) == 1)
+    {
+      int muldivmod;
+
+      if (op == '*')
+        muldivmod = 0;
+      else if (op == '/')
+        muldivmod = 1;
+      else if (op == '%')
+        muldivmod = 2;
+      else
+        muldivmod = -1;
+
+      for (su = 0; su < 4 && muldivmod >= 0; su++)
+        {
+          if ((compareType (leftType, __multypes[0][su%2]) == 1) &&
+              (compareType (rightType, __multypes[0][su/2]) == 1))
+            {
+              func = __muldiv[muldivmod][0][su];
+              goto found;
+            }
+        }
+    }
+
   /* depending on the type */
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
         {
-          if (compareType (type, __multypes[bwd][su]) == 1)
+          if (compareType (leftType, __multypes[bwd][su]) == 1)
             {
+              if ((op=='*' || op=='/' || op=='%') &&
+                  compareType (rightType, __multypes[bwd][su]) != 1)
+                {
+                  assert(0);
+                }
+
               if (op == '*')
                 func = __muldiv[0][bwd][su];
               else if (op == '/')
@@ -679,6 +743,7 @@ found:
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
       /* second one */
@@ -692,6 +757,7 @@ found:
           IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
@@ -712,6 +778,7 @@ found:
           bytesPushed += getSize(operandType(IC_RIGHT(ic)));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
       /* insert push left */
@@ -728,6 +795,7 @@ found:
           bytesPushed += getSize(operandType(IC_LEFT(ic)));
         }
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
@@ -735,6 +803,7 @@ found:
   /* for the result */
   newic = newiCode (CALL, operandFromSymbol (func), NULL);
   IC_RESULT (newic) = IC_RESULT (ic);
+  newic->filename = filename;
   newic->lineno = lineno;
   newic->parmBytes+=bytesPushed; // to clear the stack after the call
   ebp->hasFcall = 1;
@@ -778,10 +847,9 @@ convertToFcall (eBBlock ** ebbs, int count)
              converted to function calls */
           if ((IS_CONDITIONAL (ic) ||
                IS_ARITHMETIC_OP (ic)) &&
-             (IS_FLOAT (operandType (IC_RIGHT (ic)))
-               || IS_FIXED( operandType (IC_RIGHT (ic)))))
+              (IS_FLOAT (operandType (IC_RIGHT (ic))) ||
+               IS_FIXED( operandType (IC_RIGHT (ic)))))
             {
-
               cnvToFcall (ic, ebbs[i]);
             }
 
@@ -792,10 +860,10 @@ convertToFcall (eBBlock ** ebbs, int count)
                 cnvFromFloatCast (ic, ebbs[i]);
               else if (IS_FLOAT (operandType (IC_LEFT (ic))))
                 cnvToFloatCast (ic, ebbs[i]);
-             if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
-               cnvFromFixed16x16Cast (ic, ebbs[i]);
-             else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
-               cnvToFixed16x16Cast (ic, ebbs[i]);
+              if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
+                cnvFromFixed16x16Cast (ic, ebbs[i]);
+              else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
+                cnvToFixed16x16Cast (ic, ebbs[i]);
             }
 
           // Easy special case which avoids function call: modulo by a literal power
@@ -803,7 +871,7 @@ convertToFcall (eBBlock ** ebbs, int count)
           if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
               IS_UNSIGNED(operandType(IC_LEFT(ic))))
             {
-              unsigned litVal = fabs(operandLitValue(IC_RIGHT(ic)));
+              unsigned litVal = abs((unsigned) double2ul (operandLitValue(IC_RIGHT(ic))));
 
               /* modulo by 1: no remainder */
               if (litVal == 1)
@@ -848,7 +916,7 @@ convertToFcall (eBBlock ** ebbs, int count)
                     }
                   else
                     {
-                      convilong (ic, ebbs[i], leftType, ic->op);
+                      convilong (ic, ebbs[i]);
                     }
                 }
             }
@@ -859,7 +927,7 @@ convertToFcall (eBBlock ** ebbs, int count)
 
               if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
                 {
-                  convilong (ic, ebbs[i], type, ic->op);
+                  convilong (ic, ebbs[i]);
                 }
             }
         }
@@ -1232,7 +1300,7 @@ killDeadCode (ebbIndex * ebbi)
                       symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
                       symbol * prereqv = resultsym->prereqv;
 
-                     if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
+                      if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
                         {
                           operand * newreqv;
 
@@ -1277,7 +1345,7 @@ killDeadCode (ebbIndex * ebbi)
             }                   /* end of all instructions */
 
           if (!ebbs[i]->sch && !ebbs[i]->noPath)
-           disconBBlock (ebbs[i], ebbi);
+            disconBBlock (ebbs[i], ebbi);
 
         }                       /* end of for all blocks */
 
@@ -1449,7 +1517,7 @@ eBBlockFromiCode (iCode * ic)
 
   /* replace the local variables with their
      register equivalents : the liveRange computation
-     along with the register allocation will determine 
+     along with the register allocation will determine
      if it finally stays in the registers */
   replaceRegEqv (ebbi);
 
@@ -1481,7 +1549,7 @@ eBBlockFromiCode (iCode * ic)
     {
       change += cseAllBlocks (ebbi, FALSE);
       if (options.dump_gcse)
-       dumpEbbsToFileExt (DUMP_GCSE, ebbi);
+        dumpEbbsToFileExt (DUMP_GCSE, ebbi);
     }
   else
     {
@@ -1511,7 +1579,7 @@ eBBlockFromiCode (iCode * ic)
       computeDataFlow (ebbi);
       change += cseAllBlocks (ebbi, FALSE);
       if (options.dump_loop)
-       dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
+        dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
 
       /* if loop optimizations caused a change then do
          dead code elimination once more : this will
@@ -1520,7 +1588,7 @@ eBBlockFromiCode (iCode * ic)
       killDeadCode (ebbi);
 
       if (options.dump_loop)
-       dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
+        dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
 
     }
 
@@ -1535,9 +1603,9 @@ eBBlockFromiCode (iCode * ic)
        && !FUNC_ISNAKED(currFunc->type)) {
         eBBlock *bp;
         // make sure all predecessors of the last block end in a return
-       for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList); 
+        for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
              bp;
-            bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
+             bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
           if (bp->ech->op != RETURN) {
             werrorfl (bp->ech->filename, bp->ech->lineno,
                       W_VOID_FUNC, currFunc->name);
@@ -1554,7 +1622,7 @@ eBBlockFromiCode (iCode * ic)
   /* convert operations with support routines
      written in C to function calls : I am doing
      this at this point since I want all the
-     operations to be as they are for optimzations */
+     operations to be as they are for optimizations */
   convertToFcall (ebbi->bbOrder, ebbi->count);
 
   /* compute the live ranges */