Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / src / SDCCopt.c
index b837e93532986cb39a235f2619701d271aa59387..c799bed2de0d887594170d6d07572d85bd821638 100644 (file)
@@ -1,9 +1,9 @@
 /*-------------------------------------------------------------------------
   SDCCopt.c - calls all the optimizations routines and does some of the
               hackier transformations, these include translating iCodes
 /*-------------------------------------------------------------------------
   SDCCopt.c - calls all the optimizations routines and does some of the
               hackier transformations, these include translating iCodes
-             to function calls and replacing local variables with their
-             register equivalents etc. Also contains the driver routine
-             for dead code elimination
+              to function calls and replacing local variables with their
+              register equivalents etc. Also contains the driver routine
+              for dead code elimination
 
              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
 
 
              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
 
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
 -------------------------------------------------------------------------*/
 
+#include <math.h>
 #include "common.h"
 
 /*-----------------------------------------------------------------*/
 #include "common.h"
 
 /*-----------------------------------------------------------------*/
@@ -38,7 +39,7 @@ char flowChanged = 0;
 /*-----------------------------------------------------------------*/
 /* printSymName - prints the symbol names                          */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* printSymName - prints the symbol names                          */
 /*-----------------------------------------------------------------*/
-int 
+int
 printSymName (void *vsym)
 {
   symbol *sym = vsym;
 printSymName (void *vsym)
 {
   symbol *sym = vsym;
@@ -49,7 +50,7 @@ printSymName (void *vsym)
 /*-----------------------------------------------------------------*/
 /* cnvToFcall - does the actual conversion to function call        */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* cnvToFcall - does the actual conversion to function call        */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 cnvToFcall (iCode * ic, eBBlock * ebp)
 {
   iCode *ip;
 cnvToFcall (iCode * ic, eBBlock * ebp)
 {
   iCode *ip;
@@ -57,49 +58,93 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
   operand *left;
   operand *right;
   symbol *func = NULL;
   operand *left;
   operand *right;
   symbol *func = NULL;
+  char *filename = ic->filename;
   int lineno = ic->lineno;
   int bytesPushed=0;
 
   int lineno = ic->lineno;
   int bytesPushed=0;
 
-  ip = ic->next;               /* insertion point */
+  ip = ic->next;                /* insertion point */
   /* remove it from the iCode */
   remiCodeFromeBBlock (ebp, ic);
 
   left = IC_LEFT (ic);
   right = IC_RIGHT (ic);
 
   /* remove it from the iCode */
   remiCodeFromeBBlock (ebp, ic);
 
   left = IC_LEFT (ic);
   right = IC_RIGHT (ic);
 
-  switch (ic->op)
-    {
-    case '+':
-      func = __fsadd;
-      break;
-    case '-':
-      func = __fssub;
-      break;
-    case '/':
-      func = __fsdiv;
-      break;
-    case '*':
-      func = __fsmul;
-      break;
-    case EQ_OP:
-      func = __fseq;
-      break;
-    case NE_OP:
-      func = __fsneq;
-      break;
-    case '<':
-      func = __fslt;
-      break;
-    case '>':
-      func = __fsgt;
-      break;
-    case LE_OP:
-      func = __fslteq;
-      break;
-    case GE_OP:
-      func = __fsgteq;
-      break;
-    }
+  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 '+':
+        func = __fsadd;
+        break;
+      case '-':
+        func = __fssub;
+        break;
+      case '/':
+        func = __fsdiv;
+        break;
+      case '*':
+        func = __fsmul;
+        break;
+      case EQ_OP:
+        func = __fseq;
+        break;
+      case NE_OP:
+        func = __fsneq;
+        break;
+      case '<':
+        func = __fslt;
+        break;
+      case '>':
+        func = __fsgt;
+        break;
+      case LE_OP:
+        func = __fslteq;
+        break;
+      case GE_OP:
+        func = __fsgteq;
+        break;
+      }
+  } else
+  if (IS_FIXED16X16 (operandType (right))) {
+    switch (ic->op)
+      {
+      case '+':
+        func = __fps16x16_add;
+        break;
+      case '-':
+        func = __fps16x16_sub;
+        break;
+      case '/':
+        func = __fps16x16_div;
+        break;
+      case '*':
+        func = __fps16x16_mul;
+        break;
+      case EQ_OP:
+        func = __fps16x16_eq;
+        break;
+      case NE_OP:
+        func = __fps16x16_neq;
+        break;
+      case '<':
+        func = __fps16x16_lt;
+        break;
+      case '>':
+        func = __fps16x16_gt;
+        break;
+      case LE_OP:
+        func = __fps16x16_lteq;
+        break;
+      case GE_OP:
+        func = __fps16x16_gteq;
+        break;
+      }
+  }
+
 
   /* if float support routines NOT compiled as reentrant */
   if (!options.float_rent)
 
   /* if float support routines NOT compiled as reentrant */
   if (!options.float_rent)
@@ -107,32 +152,38 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
 
       /* first one */
       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
 
       /* first one */
       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
-       {
-         newic = newiCode (SEND, IC_LEFT (ic), NULL);
-         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
-       }
+        {
+          newic = newiCode (SEND, left, NULL);
+          newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+        }
       else
       else
-       {
-         newic = newiCode ('=', NULL, IC_LEFT (ic));
-         IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
-       }
+        {
+          newic = newiCode ('=', NULL, left);
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
+        }
 
       addiCodeToeBBlock (ebp, newic, ip);
 
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
       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))
 
       /* second one */
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
-       {
-         newic = newiCode (SEND, IC_RIGHT (ic), NULL);
-         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
-       }
+        {
+          newic = newiCode (SEND, right, NULL);
+          newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
+        }
       else
       else
-       {
-         newic = newiCode ('=', NULL, IC_RIGHT (ic));
-         IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
-       }
+        {
+          newic = newiCode ('=', NULL, right);
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
       newic->lineno = lineno;
+      if (IS_SYMOP (right))
+          OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
 
     }
   else
 
     }
   else
@@ -140,57 +191,65 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
 
       /* push right */
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
 
       /* push right */
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
-       {
-         newic = newiCode (SEND, right, NULL);
-         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
-       }
+        {
+          newic = newiCode (SEND, right, NULL);
+          newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
+        }
       else
       else
-       {
-         newic = newiCode (IPUSH, right, NULL);
-         newic->parmPush = 1;
-         //bytesPushed+=4;
-         bytesPushed += getSize(operandType(right));
-       }
+        {
+          newic = newiCode (IPUSH, right, NULL);
+          newic->parmPush = 1;
+          bytesPushed += getSize(operandType(right));
+        }
 
       addiCodeToeBBlock (ebp, newic, ip);
 
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
       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))
 
       /* insert push left */
       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
-       {
-         newic = newiCode (SEND, left, NULL);
-         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
-       }
+        {
+          newic = newiCode (SEND, left, NULL);
+          newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+        }
       else
       else
-       {
-         newic = newiCode (IPUSH, left, NULL);
-         newic->parmPush = 1;
-         //bytesPushed+=4;
-         bytesPushed += getSize(operandType(left));
-       }
+        {
+          newic = newiCode (IPUSH, left, NULL);
+          newic->parmPush = 1;
+          bytesPushed += getSize(operandType(left));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
       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);
     }
   /* 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->lineno = lineno;
-  newic->parmBytes+=bytesPushed;
+  newic->parmBytes += bytesPushed;
   ebp->hasFcall = 1;
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
   ebp->hasFcall = 1;
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
-    
-  if(TARGET_IS_PIC16) {
-       /* 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);
-       }
+
+  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);
+        }
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
@@ -199,7 +258,7 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
 /*-----------------------------------------------------------------*/
 /* cnvToFloatCast - converts casts to floats to function calls     */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* cnvToFloatCast - converts casts to floats to function calls     */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 cnvToFloatCast (iCode * ic, eBBlock * ebp)
 {
   iCode *ip, *newic;
 cnvToFloatCast (iCode * ic, eBBlock * ebp)
 {
   iCode *ip, *newic;
@@ -216,14 +275,20 @@ cnvToFloatCast (iCode * ic, eBBlock * ebp)
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
-       {
-         if (compareType (type, __multypes[bwd][su]) == 1)
-           {
-             func = __conv[0][bwd][su];
-             goto found;
-           }
-       }
+        {
+          if (compareType (type, __multypes[bwd][su]) == 1)
+            {
+              func = __conv[0][bwd][su];
+              goto found;
+            }
+        }
     }
     }
+
+  if(compareType (type, fixed16x16Type) == 1) {
+    func = __fp16x16conv[0][3][0];
+    goto found;
+  }
+
   assert (0);
 found:
 
   assert (0);
 found:
 
@@ -231,37 +296,132 @@ found:
   if (!options.float_rent)
     {
       /* first one */
   if (!options.float_rent)
     {
       /* first one */
-       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) 
-           {
-               newic = newiCode (SEND, IC_RIGHT (ic), NULL);
-               newic->argreg = SPEC_ARGREG(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);
+        }
       else
       else
-       {
-         newic = newiCode ('=', NULL, IC_RIGHT (ic));
-         IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
-       }
+        {
+          newic = newiCode ('=', NULL, IC_RIGHT (ic));
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = linenno;
 
     }
   else
     {
       /* push the left */
       newic->lineno = linenno;
 
     }
   else
     {
       /* push the left */
-       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
-           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
-           newic->argreg = SPEC_ARGREG(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);
+      }
+      else
+      {
+        newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
+        newic->parmPush = 1;
+        bytesPushed += getSize(operandType(IC_RIGHT(ic)));
+      }
+      addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
+      newic->lineno = linenno;
+    }
+
+  /* make the call */
+  newic = newiCode (CALL, operandFromSymbol (func), NULL);
+  IC_RESULT (newic) = IC_RESULT (ic);
+  newic->parmBytes+=bytesPushed;
+  ebp->hasFcall = 1;
+  if (currFunc)
+    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);
+        }
+  }
+
+  addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
+  newic->lineno = linenno;
+}
+
+/*----------------------------------------------------------------------*/
+/* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
+/*----------------------------------------------------------------------*/
+static void
+cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
+{
+  iCode *ip, *newic;
+  symbol *func = NULL;
+  sym_link *type = operandType (IC_RIGHT (ic));
+  int linenno = ic->lineno;
+  int bwd, su;
+  int bytesPushed=0;
+
+  ip = ic->next;
+  /* remove it from the iCode */
+  remiCodeFromeBBlock (ebp, ic);
+  /* depending on the type */
+  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;
+            }
+        }
+    }
+  assert (0);
+found:
+
+  /* if float support routines NOT compiled as reentrant */
+  if (!options.float_rent)
+    {
+      /* first one */
+        if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
+            {
+                newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+                newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+            }
       else
       else
-       {
-         newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
-         newic->parmPush = 1;
-         bytesPushed += getSize(operandType(IC_RIGHT(ic)));
-       }
+        {
+          newic = newiCode ('=', NULL, IC_RIGHT (ic));
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = linenno;
 
     }
       newic->lineno = linenno;
 
     }
+  else
+    {
+      /* push the left */
+        if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
+            newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+            newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+        }
+      else
+        {
+          newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
+          newic->parmPush = 1;
+          bytesPushed += getSize(operandType(IC_RIGHT(ic)));
+        }
+      addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
+      newic->lineno = linenno;
+    }
 
   /* make the call */
   newic = newiCode (CALL, operandFromSymbol (func), NULL);
 
   /* make the call */
   newic = newiCode (CALL, operandFromSymbol (func), NULL);
@@ -271,32 +431,34 @@ found:
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
 
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
 
-  if(TARGET_IS_PIC16) {
-       /* 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);
-       }
+  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);
+        }
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
   newic->lineno = linenno;
 }
 
 /*-----------------------------------------------------------------*/
 /* cnvFromFloatCast - converts casts From floats to function calls */
 /*-----------------------------------------------------------------*/
   newic->lineno = linenno;
 }
 
 /*-----------------------------------------------------------------*/
 /* cnvFromFloatCast - converts casts From floats to function calls */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
 {
   iCode *ip, *newic;
   symbol *func = NULL;
   sym_link *type = operandType (IC_LEFT (ic));
 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;
   int lineno = ic->lineno;
   int bwd, su;
   int bytesPushed=0;
@@ -309,13 +471,13 @@ cnvFromFloatCast (iCode * ic, eBBlock * ebp)
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
-       {
-         if (compareType (type, __multypes[bwd][su]) == 1)
-           {
-             func = __conv[1][bwd][su];
-             goto found;
-           }
-       }
+        {
+          if (compareType (type, __multypes[bwd][su]) == 1)
+            {
+              func = __conv[1][bwd][su];
+              goto found;
+            }
+        }
     }
   assert (0);
 found:
     }
   assert (0);
 found:
@@ -324,16 +486,17 @@ found:
   if (!options.float_rent)
     {
       /* first one */
   if (!options.float_rent)
     {
       /* first one */
-       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
-           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
-           newic->argreg = SPEC_ARGREG(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);
+        }
       else
       else
-       {
-         newic = newiCode ('=', NULL, IC_RIGHT (ic));
-         IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
-       }
+        {
+          newic = newiCode ('=', NULL, IC_RIGHT (ic));
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
       newic->lineno = lineno;
 
     }
@@ -341,17 +504,18 @@ found:
     {
 
       /* push the left */
     {
 
       /* push the left */
-       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
-           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
-           newic->argreg = SPEC_ARGREG(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);
+        }
       else
       else
-       {
-         newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
-         newic->parmPush = 1;
-         bytesPushed += getSize(operandType(IC_RIGHT(ic)));
-       }
+        {
+          newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
+          newic->parmPush = 1;
+          bytesPushed += getSize(operandType(IC_RIGHT(ic)));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
       newic->lineno = lineno;
 
     }
@@ -364,20 +528,123 @@ found:
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
 
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
 
-  if(TARGET_IS_PIC16) {
-       /* 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);
-       }
+  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);
+        }
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
+  newic->lineno = lineno;
+}
+
+/*--------------------------------------------------------------------------*/
+/* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
+/*--------------------------------------------------------------------------*/
+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;
+
+  ip = ic->next;
+  /* remove it from the iCode */
+  remiCodeFromeBBlock (ebp, ic);
+
+  /* depending on the type */
+  for (bwd = 0; bwd < 3; bwd++)
+    {
+      for (su = 0; su < 2; su++)
+        {
+          if (compareType (type, __multypes[bwd][su]) == 1)
+            {
+              func = __fp16x16conv[1][bwd][su];
+              goto found;
+            }
+        }
+    }
+
+  if (compareType (type, floatType) == 1)
+    {
+      func = __fp16x16conv[1][3][0];
+      goto found;
+    }
+
+  assert (0);
+found:
+
+  /* if float support routines NOT compiled as reentrant */
+  if (!options.float_rent)
+    {
+      /* first one */
+        if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
+            newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+            newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+        }
+      else
+        {
+          newic = newiCode ('=', NULL, IC_RIGHT (ic));
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
+        }
+      addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
+      newic->lineno = lineno;
+    }
+  else
+    {
+
+      /* push the left */
+        if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
+            newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+            newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+        }
+      else
+        {
+          newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
+          newic->parmPush = 1;
+          bytesPushed += getSize(operandType(IC_RIGHT(ic)));
+        }
+      addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
+      newic->lineno = lineno;
+    }
+
+  /* make the call */
+  newic = newiCode (CALL, operandFromSymbol (func), NULL);
+  IC_RESULT (newic) = IC_RESULT (ic);
+  newic->parmBytes+=bytesPushed;
+  ebp->hasFcall = 1;
+  if (currFunc)
+    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);
+        }
+  }
+
+  addiCodeToeBBlock (ebp, newic, ip);
+  newic->filename = filename;
   newic->lineno = lineno;
 }
 
   newic->lineno = lineno;
 }
 
@@ -386,45 +653,79 @@ extern operand *geniCodeRValue (operand *, bool);
 /*-----------------------------------------------------------------*/
 /* convilong - converts int or long mults or divs to fcalls        */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* convilong - converts int or long mults or divs to fcalls        */
 /*-----------------------------------------------------------------*/
-static void 
-convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
+static void
+convilong (iCode * ic, eBBlock * ebp)
 {
 {
+  int op = ic->op;
   symbol *func = NULL;
   iCode *ip = ic->next;
   iCode *newic;
   symbol *func = NULL;
   iCode *ip = ic->next;
   iCode *newic;
+  char *filename = ic->filename;
   int lineno = ic->lineno;
   int bwd;
   int su;
   int bytesPushed=0;
   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;
+            }
+        }
+    }
 
 
-  remiCodeFromeBBlock (ebp, ic);    
-    
   /* depending on the type */
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
   /* depending on the type */
   for (bwd = 0; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
-       {
-         if (compareType (type, __multypes[bwd][su]) == 1)
-           {
-             if (op == '*')
-               func = __muldiv[0][bwd][su];
-             else if (op == '/')
-               func = __muldiv[1][bwd][su];
-             else if (op == '%')
-               func = __muldiv[2][bwd][su];
+        {
+          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 == '/')
+                func = __muldiv[1][bwd][su];
+              else if (op == '%')
+                func = __muldiv[2][bwd][su];
               else if (op == RRC)
               else if (op == RRC)
-               func = __rlrr[1][bwd][su];
+                func = __rlrr[1][bwd][su];
               else if (op == RLC)
               else if (op == RLC)
-               func = __rlrr[0][bwd][su];
+                func = __rlrr[0][bwd][su];
               else if (op == RIGHT_OP)
               else if (op == RIGHT_OP)
-               func = __rlrr[1][bwd][su];
+                func = __rlrr[1][bwd][su];
               else if (op == LEFT_OP)
               else if (op == LEFT_OP)
-               func = __rlrr[0][bwd][su];
-             else
-               assert (0);
-             goto found;
-           }
-       }
+                func = __rlrr[0][bwd][su];
+              else
+                assert (0);
+              goto found;
+            }
+        }
     }
   assert (0);
 found:
     }
   assert (0);
 found:
@@ -432,29 +733,31 @@ found:
   if (!options.intlong_rent)
     {
       /* first one */
   if (!options.intlong_rent)
     {
       /* first one */
-       if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
-           newic = newiCode (SEND, IC_LEFT (ic), NULL);
-           newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
-       }
+        if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) {
+            newic = newiCode (SEND, IC_LEFT (ic), NULL);
+            newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+        }
       else
       else
-       {
-         newic = newiCode ('=', NULL, IC_LEFT (ic));
-         IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
-       }
+        {
+          newic = newiCode ('=', NULL, IC_LEFT (ic));
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
       /* second one */
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
       newic->lineno = lineno;
 
       /* second one */
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) {
-         newic = newiCode (SEND, IC_RIGHT (ic), NULL);
-         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
+          newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+          newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
       }
       else
       }
       else
-       {
-         newic = newiCode ('=', NULL, IC_RIGHT (ic));
-         IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
-       }
+        {
+          newic = newiCode ('=', NULL, IC_RIGHT (ic));
+          IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
       newic->lineno = lineno;
 
     }
@@ -465,32 +768,34 @@ found:
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
         {
           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
       if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
         {
           newic = newiCode (SEND, IC_RIGHT (ic), NULL);
-         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
+          newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
         }
       else
         }
       else
-       {
-         newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
-         newic->parmPush = 1;
+        {
+          newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
+          newic->parmPush = 1;
 
 
-         bytesPushed += getSize(operandType(IC_RIGHT(ic)));
-       }
+          bytesPushed += getSize(operandType(IC_RIGHT(ic)));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
       /* insert push left */
       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
         {
           newic = newiCode (SEND, IC_LEFT (ic), NULL);
       newic->lineno = lineno;
 
       /* insert push left */
       if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
         {
           newic = newiCode (SEND, IC_LEFT (ic), NULL);
-         newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
+          newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
         }
       else
         }
       else
-       {
-         newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
-         newic->parmPush = 1;
+        {
+          newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
+          newic->parmPush = 1;
 
 
-         bytesPushed += getSize(operandType(IC_LEFT(ic)));
-       }
+          bytesPushed += getSize(operandType(IC_LEFT(ic)));
+        }
       addiCodeToeBBlock (ebp, newic, ip);
       addiCodeToeBBlock (ebp, newic, ip);
+      newic->filename = filename;
       newic->lineno = lineno;
 
     }
       newic->lineno = lineno;
 
     }
@@ -498,23 +803,24 @@ found:
   /* for the result */
   newic = newiCode (CALL, operandFromSymbol (func), NULL);
   IC_RESULT (newic) = IC_RESULT (ic);
   /* 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;
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
 
   newic->lineno = lineno;
   newic->parmBytes+=bytesPushed; // to clear the stack after the call
   ebp->hasFcall = 1;
   if (currFunc)
     FUNC_HASFCALL (currFunc->type) = 1;
 
-  if(TARGET_IS_PIC16) {
-       /* 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);
-       }
+  if(TARGET_IS_PIC || TARGET_IS_PIC16) {
+        /* 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);
   }
 
   addiCodeToeBBlock (ebp, newic, ip);
@@ -523,7 +829,7 @@ found:
 /*-----------------------------------------------------------------*/
 /* convertToFcall - converts some operations to fcalls             */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* convertToFcall - converts some operations to fcalls             */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 convertToFcall (eBBlock ** ebbs, int count)
 {
   int i;
 convertToFcall (eBBlock ** ebbs, int count)
 {
   int i;
@@ -535,34 +841,46 @@ convertToFcall (eBBlock ** ebbs, int count)
 
       /* for all instructions in the block do */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
 
       /* for all instructions in the block do */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       {
-
-         /* floating point operations are
-            converted to function calls */
-         if ((IS_CONDITIONAL (ic) ||
-              IS_ARITHMETIC_OP (ic)) &&
-             (IS_FLOAT (operandType (IC_RIGHT (ic)))))
-           {
-
-             cnvToFcall (ic, ebbs[i]);
-           }
-
-         /* casting is a little different */
-         if (ic->op == CAST)
-           {
-             if (IS_FLOAT (operandType (IC_RIGHT (ic))))
-               cnvFromFloatCast (ic, ebbs[i]);
-             else if (IS_FLOAT (operandType (IC_LEFT (ic))))
-               cnvToFloatCast (ic, ebbs[i]);
-           }
+        {
+
+          /* floating point operations are
+             converted to function calls */
+          if ((IS_CONDITIONAL (ic) ||
+               IS_ARITHMETIC_OP (ic)) &&
+              (IS_FLOAT (operandType (IC_RIGHT (ic))) ||
+               IS_FIXED( operandType (IC_RIGHT (ic)))))
+            {
+              cnvToFcall (ic, ebbs[i]);
+            }
+
+          /* casting is a little different */
+          if (ic->op == CAST)
+            {
+              if (IS_FLOAT (operandType (IC_RIGHT (ic))))
+                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]);
+            }
 
           // Easy special case which avoids function call: modulo by a literal power
           // of two can be replaced by a bitwise AND.
           if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
               IS_UNSIGNED(operandType(IC_LEFT(ic))))
             {
 
           // Easy special case which avoids function call: modulo by a literal power
           // of two can be replaced by a bitwise AND.
           if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
               IS_UNSIGNED(operandType(IC_LEFT(ic))))
             {
-              unsigned litVal = abs(operandLitValue(IC_RIGHT(ic)));
+              unsigned litVal = abs((unsigned) double2ul (operandLitValue(IC_RIGHT(ic))));
 
 
+              /* modulo by 1: no remainder */
+              if (litVal == 1)
+                {
+                  ic->op = '=';
+                  IC_RIGHT (ic) = operandFromLit(0);
+                  IC_LEFT (ic) = NULL;
+                  continue;
+                }
               // See if literal value is a power of 2.
               while (litVal && !(litVal & 1))
                 {
               // See if literal value is a power of 2.
               while (litVal && !(litVal & 1))
                 {
@@ -582,12 +900,12 @@ convertToFcall (eBBlock ** ebbs, int count)
                 }
             }
 
                 }
             }
 
-         /* if long / int mult or divide or mod */
-         if (ic->op == '*' || ic->op == '/' || ic->op == '%')
-           {
-             sym_link *leftType = operandType (IC_LEFT (ic));
+          /* if long / int mult or divide or mod */
+          if (ic->op == '*' || ic->op == '/' || ic->op == '%')
+            {
+              sym_link *leftType = operandType (IC_LEFT (ic));
 
 
-             if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
+              if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
                 {
                   sym_link *rightType = operandType (IC_RIGHT (ic));
 
                 {
                   sym_link *rightType = operandType (IC_RIGHT (ic));
 
@@ -598,21 +916,21 @@ convertToFcall (eBBlock ** ebbs, int count)
                     }
                   else
                     {
                     }
                   else
                     {
-                      convilong (ic, ebbs[i], leftType, ic->op);
+                      convilong (ic, ebbs[i]);
                     }
                 }
                     }
                 }
-           }
-          
+            }
+
           if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
             {
           if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
             {
-             sym_link *type = operandType (IC_LEFT (ic));
+              sym_link *type = operandType (IC_LEFT (ic));
 
 
-             if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
+              if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
                 {
                 {
-                  convilong (ic, ebbs[i], type, ic->op);
+                  convilong (ic, ebbs[i]);
                 }
             }
                 }
             }
-       }
+        }
     }
 }
 
     }
 }
 
@@ -625,26 +943,26 @@ isLocalWithoutDef (symbol * sym)
 {
   if (!IS_AUTO (sym))
     return 0;
 {
   if (!IS_AUTO (sym))
     return 0;
-  
+
   if (IS_VOLATILE (sym->type))
     return 0;
   if (IS_VOLATILE (sym->type))
     return 0;
-  
+
   if (sym->_isparm)
     return 0;
   if (sym->_isparm)
     return 0;
-  
+
   if (IS_AGGREGATE (sym->type))
     return 0;
   if (IS_AGGREGATE (sym->type))
     return 0;
-  
+
   if (sym->addrtaken)
     return 0;
   if (sym->addrtaken)
     return 0;
-  
+
   return !sym->defs;
 }
 
 /*-----------------------------------------------------------------*/
 /* replaceRegEqv - replace all local variables with their reqv     */
 /*-----------------------------------------------------------------*/
   return !sym->defs;
 }
 
 /*-----------------------------------------------------------------*/
 /* replaceRegEqv - replace all local variables with their reqv     */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 replaceRegEqv (ebbIndex * ebbi)
 {
   eBBlock ** ebbs = ebbi->bbOrder;
 replaceRegEqv (ebbIndex * ebbi)
 {
   eBBlock ** ebbs = ebbi->bbOrder;
@@ -663,121 +981,121 @@ replaceRegEqv (ebbIndex * ebbi)
       iCode *ic;
 
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
       iCode *ic;
 
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       {
+        {
 
 
-         if (SKIP_IC2 (ic))
-           continue;
+          if (SKIP_IC2 (ic))
+            continue;
 
 
-         if (ic->op == IFX)
-           {
-             if (IC_COND (ic) &&
-                 IS_TRUE_SYMOP (IC_COND (ic)) &&
+          if (ic->op == IFX)
+            {
+              if (IC_COND (ic) &&
+                  IS_TRUE_SYMOP (IC_COND (ic)) &&
                   isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
                   isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
-               {
-                 werrorfl (ic->filename, ic->lineno,
-                         W_LOCAL_NOINIT,
-                         OP_SYMBOL (IC_COND (ic))->name);
-                 OP_REQV (IC_COND (ic)) = NULL;
-                 OP_SYMBOL (IC_COND (ic))->allocreq = 1;
-               }
-             
-             if (IS_TRUE_SYMOP (IC_COND (ic)) &&
-                 OP_REQV (IC_COND (ic)))
-               IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
-                                            OP_SYMBOL (IC_COND (ic))->defs,
-                                           OP_SYMBOL (IC_COND (ic))->uses);
-
-             continue;
-           }
-
-         
-         if (ic->op == JUMPTABLE)
-           {
-             if (IC_JTCOND (ic) &&
-                 IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
+                {
+                  werrorfl (ic->filename, ic->lineno,
+                          W_LOCAL_NOINIT,
+                          OP_SYMBOL (IC_COND (ic))->name);
+                  OP_REQV (IC_COND (ic)) = NULL;
+                  OP_SYMBOL (IC_COND (ic))->allocreq = 1;
+                }
+
+              if (IS_TRUE_SYMOP (IC_COND (ic)) &&
+                  OP_REQV (IC_COND (ic)))
+                IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
+                                             OP_SYMBOL (IC_COND (ic))->defs,
+                                            OP_SYMBOL (IC_COND (ic))->uses);
+
+              continue;
+            }
+
+
+          if (ic->op == JUMPTABLE)
+            {
+              if (IC_JTCOND (ic) &&
+                  IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
                   isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
                   isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
-               {
-                 werrorfl (ic->filename, ic->lineno,
-                         W_LOCAL_NOINIT,
-                         OP_SYMBOL (IC_JTCOND (ic))->name);
-                 OP_REQV (IC_JTCOND (ic)) = NULL;
-                 OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
-               }
-             
-             if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
-                 OP_REQV (IC_JTCOND (ic)))
-               IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
-                                          OP_SYMBOL (IC_JTCOND (ic))->defs,
-                                         OP_SYMBOL (IC_JTCOND (ic))->uses);
-             continue;
-           }
-
-         if (ic->op == RECEIVE)
-           {
-             if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
-               OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
-           }
-
-         /* general case */
-         if (IC_RESULT (ic) &&
-             IS_TRUE_SYMOP (IC_RESULT (ic)) &&
-             OP_REQV (IC_RESULT (ic)))
-           {
-             if (POINTER_SET (ic))
-               {
-                 IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
-                                          OP_SYMBOL (IC_RESULT (ic))->defs,
-                                         OP_SYMBOL (IC_RESULT (ic))->uses);
-                 IC_RESULT (ic)->isaddr = 1;
-               }
-             else
-               IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
-                                          OP_SYMBOL (IC_RESULT (ic))->defs,
-                                         OP_SYMBOL (IC_RESULT (ic))->uses);
-           }
-
-         if (IC_RIGHT (ic) &&
-             IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
-             isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
-           {
-             werrorfl (ic->filename, ic->lineno,
-                       W_LOCAL_NOINIT,
-                       OP_SYMBOL (IC_RIGHT (ic))->name);
-             OP_REQV (IC_RIGHT (ic)) = NULL;
-             OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
-           }
-         
-         if (IC_RIGHT (ic) &&
-             IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
-             OP_REQV (IC_RIGHT (ic)))
-           {
-             IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
-                                           OP_SYMBOL (IC_RIGHT (ic))->defs,
-                                          OP_SYMBOL (IC_RIGHT (ic))->uses);
-             IC_RIGHT (ic)->isaddr = 0;
-           }
-
-         if (IC_LEFT (ic) &&
-             IS_TRUE_SYMOP (IC_LEFT (ic)) &&
-             isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
-           {
-             werrorfl (ic->filename, ic->lineno,
-                       W_LOCAL_NOINIT,
-                       OP_SYMBOL (IC_LEFT (ic))->name);
-             OP_REQV (IC_LEFT (ic)) = NULL;
-             OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
-           }
-            
-         if (IC_LEFT (ic) &&
-             IS_TRUE_SYMOP (IC_LEFT (ic)) &&
-             OP_REQV (IC_LEFT (ic)))
-           {
-             IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
-                                            OP_SYMBOL (IC_LEFT (ic))->defs,
-                                            OP_SYMBOL (IC_LEFT (ic))->uses);
-             IC_LEFT (ic)->isaddr = 0;
-           }
-       }
+                {
+                  werrorfl (ic->filename, ic->lineno,
+                          W_LOCAL_NOINIT,
+                          OP_SYMBOL (IC_JTCOND (ic))->name);
+                  OP_REQV (IC_JTCOND (ic)) = NULL;
+                  OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
+                }
+
+              if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
+                  OP_REQV (IC_JTCOND (ic)))
+                IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
+                                           OP_SYMBOL (IC_JTCOND (ic))->defs,
+                                          OP_SYMBOL (IC_JTCOND (ic))->uses);
+              continue;
+            }
+
+          if (ic->op == RECEIVE)
+            {
+              if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
+                OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
+            }
+
+          /* general case */
+          if (IC_RESULT (ic) &&
+              IS_TRUE_SYMOP (IC_RESULT (ic)) &&
+              OP_REQV (IC_RESULT (ic)))
+            {
+              if (POINTER_SET (ic))
+                {
+                  IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
+                                           OP_SYMBOL (IC_RESULT (ic))->defs,
+                                          OP_SYMBOL (IC_RESULT (ic))->uses);
+                  IC_RESULT (ic)->isaddr = 1;
+                }
+              else
+                IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)),
+                                           OP_SYMBOL (IC_RESULT (ic))->defs,
+                                          OP_SYMBOL (IC_RESULT (ic))->uses);
+            }
+
+          if (IC_RIGHT (ic) &&
+              IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
+              isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
+            {
+              werrorfl (ic->filename, ic->lineno,
+                        W_LOCAL_NOINIT,
+                        OP_SYMBOL (IC_RIGHT (ic))->name);
+              OP_REQV (IC_RIGHT (ic)) = NULL;
+              OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
+            }
+
+          if (IC_RIGHT (ic) &&
+              IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
+              OP_REQV (IC_RIGHT (ic)))
+            {
+              IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)),
+                                            OP_SYMBOL (IC_RIGHT (ic))->defs,
+                                           OP_SYMBOL (IC_RIGHT (ic))->uses);
+              IC_RIGHT (ic)->isaddr = 0;
+            }
+
+          if (IC_LEFT (ic) &&
+              IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+              isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
+            {
+              werrorfl (ic->filename, ic->lineno,
+                        W_LOCAL_NOINIT,
+                        OP_SYMBOL (IC_LEFT (ic))->name);
+              OP_REQV (IC_LEFT (ic)) = NULL;
+              OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
+            }
+
+          if (IC_LEFT (ic) &&
+              IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+              OP_REQV (IC_LEFT (ic)))
+            {
+              IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)),
+                                             OP_SYMBOL (IC_LEFT (ic))->defs,
+                                             OP_SYMBOL (IC_LEFT (ic))->uses);
+              IC_LEFT (ic)->isaddr = 0;
+            }
+        }
     }
 }
 
     }
 }
 
@@ -789,47 +1107,47 @@ findReqv (symbol * prereqv, eBBlock ** ebbs, int count)
 {
   int i;
   iCode * ic;
 {
   int i;
   iCode * ic;
-  
+
   /* for all blocks do */
   for (i=0; i<count; i++)
     {
       /* for all instructions in the block do */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
   /* for all blocks do */
   for (i=0; i<count; i++)
     {
       /* for all instructions in the block do */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       {
-         if (ic->op == IFX)
-           {
-             if (IS_ITEMP (IC_COND (ic))
-                 && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv)
-               return IC_COND (ic);
-           }
-         else if (ic->op == JUMPTABLE)
-           {
-             if (IS_ITEMP (IC_JTCOND (ic))
-                 && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv)
-               return IC_JTCOND (ic);
-           }
-         else
-           {
-             if (IS_ITEMP (IC_LEFT (ic))
-                 && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
-               return IC_LEFT (ic);
-             if (IS_ITEMP (IC_RIGHT (ic))
-                 && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
-               return IC_RIGHT (ic);
-             if (IS_ITEMP (IC_RESULT (ic))
-                 && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
-               return IC_RESULT (ic);
-           }
-       }
+        {
+          if (ic->op == IFX)
+            {
+              if (IS_ITEMP (IC_COND (ic))
+                  && OP_SYMBOL (IC_COND (ic))->prereqv == prereqv)
+                return IC_COND (ic);
+            }
+          else if (ic->op == JUMPTABLE)
+            {
+              if (IS_ITEMP (IC_JTCOND (ic))
+                  && OP_SYMBOL (IC_JTCOND (ic))->prereqv == prereqv)
+                return IC_JTCOND (ic);
+            }
+          else
+            {
+              if (IS_ITEMP (IC_LEFT (ic))
+                  && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
+                return IC_LEFT (ic);
+              if (IS_ITEMP (IC_RIGHT (ic))
+                  && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
+                return IC_RIGHT (ic);
+              if (IS_ITEMP (IC_RESULT (ic))
+                  && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
+                return IC_RESULT (ic);
+            }
+        }
     }
     }
-  
+
   return NULL;
 }
 
 /*-----------------------------------------------------------------*/
 /* killDeadCode - eliminates dead assignments                      */
 /*-----------------------------------------------------------------*/
   return NULL;
 }
 
 /*-----------------------------------------------------------------*/
 /* killDeadCode - eliminates dead assignments                      */
 /*-----------------------------------------------------------------*/
-int 
+int
 killDeadCode (ebbIndex * ebbi)
 {
   eBBlock ** ebbs = ebbi->dfOrder;
 killDeadCode (ebbIndex * ebbi)
 {
   eBBlock ** ebbs = ebbi->dfOrder;
@@ -858,187 +1176,182 @@ killDeadCode (ebbIndex * ebbi)
       change = 0;
       /* for all blocks do */
       for (i = 0; i < count; i++)
       change = 0;
       /* for all blocks do */
       for (i = 0; i < count; i++)
-       {
-         iCode *ic;
-
-         /* for all instructions in the block do */
-         for (ic = ebbs[i]->sch; ic; ic = ic->next)
-           {
-             int kill, j;
-             kill = 0;
-
-             if (SKIP_IC (ic) ||
-                 ic->op == IFX ||
-                 ic->op == RETURN ||
+        {
+          iCode *ic;
+
+          /* for all instructions in the block do */
+          for (ic = ebbs[i]->sch; ic; ic = ic->next)
+            {
+              int kill, j;
+              kill = 0;
+
+              if (SKIP_IC (ic) ||
+                  ic->op == IFX ||
+                  ic->op == RETURN ||
                   ic->op == DUMMY_READ_VOLATILE ||
                   ic->op == CRITICAL ||
                   ic->op == ENDCRITICAL)
                   ic->op == DUMMY_READ_VOLATILE ||
                   ic->op == CRITICAL ||
                   ic->op == ENDCRITICAL)
-               continue;
+                continue;
 
 
-             /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
-             /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are  */
-             /* valid. */
+              /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
+              /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are  */
+              /* valid. */
 
 
-             /* if the result is volatile then continue */
-             if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
-               continue;
+              /* if the result is volatile then continue */
+              if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
+                continue;
+
+              /* if the result is a temp & isaddr then skip */
+              if (IC_RESULT (ic) && POINTER_SET (ic))
+                continue;
 
 
-             /* if the result is a temp & isaddr then skip */
-             if (IC_RESULT (ic) && POINTER_SET (ic))
-               continue;
-              
               if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
               if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
-                 && !SPIL_LOC (IC_RESULT (ic)))
+                  && !SPIL_LOC (IC_RESULT (ic)))
+                continue;
+
+              /* if the result is used in the remainder of the */
+              /* block then skip */
+              if (usedInRemaining (IC_RESULT (ic), ic->next))
                 continue;
 
                 continue;
 
-             /* if the result is used in the remainder of the */
-             /* block then skip */
-             if (usedInRemaining (IC_RESULT (ic), ic->next))
-               continue;
-
-             /* does this definition reach the end of the block 
-                or the usage is zero then we can kill */
-             if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
-               kill = 1;       /* if not we can kill it */
-             else
-               {
-                 /* if this is a global variable or function parameter */
-                 /* we cannot kill anyway             */
-                 if (isOperandGlobal (IC_RESULT (ic)) ||
-                     (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
-                      !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
-                   continue;
-
-                 /* if we are sure there are no usages */
-                 if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
-                   {
-                     kill = 1;
-                     goto kill;
-                   }
-
-                 /* reset visited flag */
-                 for (j = 0; j < count; ebbs[j++]->visited = 0);
-
-                 /* find out if this definition is alive */
-                 if (applyToSet (ebbs[i]->succList,
-                                 isDefAlive,
-                                 ic))
-                   continue;
-
-                 kill = 1;
+              /* does this definition reach the end of the block
+                 or the usage is zero then we can kill */
+              if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
+                kill = 1;       /* if not we can kill it */
+              else
+                {
+                  /* if this is a global variable or function parameter */
+                  /* we cannot kill anyway             */
+                  if (isOperandGlobal (IC_RESULT (ic)) ||
+                      (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
+                       !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
+                    continue;
+
+                  /* if we are sure there are no usages */
+                  if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
+                    {
+                      kill = 1;
+                      goto kill;
+                    }
+
+                  /* reset visited flag */
+                  for (j = 0; j < count; ebbs[j++]->visited = 0);
+
+                  /* find out if this definition is alive */
+                  if (applyToSet (ebbs[i]->succList,
+                                  isDefAlive,
+                                  ic))
+                    continue;
+
+                  kill = 1;
+                }
+
+            kill:
+              /* kill this one if required */
+              if (kill)
+                {
+                  bool volLeft = IS_SYMOP (IC_LEFT (ic))
+                                 && isOperandVolatile (IC_LEFT (ic), FALSE);
+                  bool volRight = IS_SYMOP (IC_RIGHT (ic))
+                                  && isOperandVolatile (IC_RIGHT (ic), FALSE);
+
+                  /* a dead address-of operation should die, even if volatile */
+                  if (ic->op == ADDRESS_OF)
+                    volLeft = FALSE;
+
+                  if (ic->next && ic->seqPoint == ic->next->seqPoint
+                      && (ic->next->op == '+' || ic->next->op == '-'))
+                    {
+                      if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
+                          || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
+                        volLeft = FALSE;
+                      if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
+                          || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
+                        volRight = FALSE;
+                    }
+
+                  if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
+                    {
+                      if (SPIL_LOC (IC_RESULT (ic)))
+                        {
+                          IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
+                          SPIL_LOC (IC_RESULT (ic)) = NULL;
+                        }
+                      continue;
+                    }
+
+                  change = 1;
+                  gchange++;
+
+                  /* now delete from defUseSet */
+                  deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
+                  bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
+
+                  /* and defset of the block */
+                  bitVectUnSetBit (ebbs[i]->defSet, ic->key);
+
+                  /* If this is the last of a register equivalent, */
+                  /* look for a successor register equivalent. */
+                  bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+                  if (IS_ITEMP (IC_RESULT (ic))
+                      && OP_SYMBOL (IC_RESULT (ic))->isreqv
+                      && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
+                    {
+                      symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
+                      symbol * prereqv = resultsym->prereqv;
+
+                      if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
+                        {
+                          operand * newreqv;
+
+                          IC_RESULT (ic) = NULL;
+                          newreqv = findReqv (prereqv, ebbs, count);
+                          if (newreqv)
+                            {
+                              prereqv->reqv = newreqv;
+                            }
+                        }
+                    }
+
+                  /* delete the result */
+                  IC_RESULT (ic) = NULL;
+
+                  if (volLeft || volRight)
+                    {
+                      /* something is volatile, so keep the iCode */
+                      /* and change the operator instead */
+                      ic->op = DUMMY_READ_VOLATILE;
+
+                      /* keep only the volatile operands */
+                      if (!volLeft)
+                        IC_LEFT (ic) = NULL;
+                      if (!volRight)
+                        IC_RIGHT (ic) = NULL;
+                    }
+                  else
+                    {
+                      /* nothing is volatile, eliminate the iCode */
+                      remiCodeFromeBBlock (ebbs[i], ic);
+
+                      /* for the left & right remove the usage */
+                      if (IS_SYMOP (IC_LEFT (ic)))
+                        bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+
+                      if (IS_SYMOP (IC_RIGHT (ic)))
+                        bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+                    }
                 }
 
                 }
 
-           kill:
-             /* kill this one if required */
-             if (kill)
-               {
-                 bool volLeft = IS_SYMOP (IC_LEFT (ic))
-                                && isOperandVolatile (IC_LEFT (ic), FALSE);
-                 bool volRight = IS_SYMOP (IC_RIGHT (ic)) 
-                                 && isOperandVolatile (IC_RIGHT (ic), FALSE);
-
-                 /* a dead address-of operation should die, even if volatile */
-                 if (ic->op == ADDRESS_OF)
-                   volLeft = FALSE;
-              
-                 //if (ic->op == CAST && isOperandVolatile (IC_LEFT (ic), FALSE))
-                 //  {
-                 //    volRight = IS_SYMOP (IC_RIGHT (ic));
-                 //  }
-
-                 if (ic->next && ic->seqPoint == ic->next->seqPoint
-                     && (ic->next->op == '+' || ic->next->op == '-'))
-                   {
-                     if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
-                         || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
-                       volLeft = FALSE;
-                     if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
-                         || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
-                       volRight = FALSE;
-                   }
-                 
-                 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
-                   {
-                     if (SPIL_LOC (IC_RESULT (ic)))
-                       {
-                         IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
-                         SPIL_LOC (IC_RESULT (ic)) = NULL;
-                       }
-                     continue;
-                   }
-                                 
-                 change = 1;
-                 gchange++;
-                 
-                 /* now delete from defUseSet */
-                 deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
-                 bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
-
-                 /* and defset of the block */
-                 bitVectUnSetBit (ebbs[i]->defSet, ic->key);
-
-                 /* If this is the last of a register equivalent, */
-                 /* look for a successor register equivalent. */
-                 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
-                 if (IS_ITEMP (IC_RESULT (ic))
-                     && OP_SYMBOL (IC_RESULT (ic))->isreqv
-                     && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
-                   {
-                     symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
-                     symbol * prereqv = resultsym->prereqv;
-                     
-                     if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
-                       {
-                         operand * newreqv;
-
-                         IC_RESULT (ic) = NULL;
-                         newreqv = findReqv (prereqv, ebbs, count);
-                         if (newreqv)
-                           {
-                             prereqv->reqv = newreqv;
-                           }
-                       }
-                   }
-
-                 /* delete the result */
-                 IC_RESULT (ic) = NULL;
-                 
-                 if (volLeft || volRight)
-                   {
-                     /* something is volatile, so keep the iCode */
-                     /* and change the operator instead */
-                     ic->op = DUMMY_READ_VOLATILE;
-
-                     /* keep only the volatile operands */      
-                     if (!volLeft)
-                       IC_LEFT (ic) = NULL;
-                     if (!volRight)
-                       IC_RIGHT (ic) = NULL;
-                   }
-                 else
-                   {
-                     /* nothing is volatile, eliminate the iCode */
-                     remiCodeFromeBBlock (ebbs[i], ic);
-
-                     /* for the left & right remove the usage */
-                     if (IS_SYMOP (IC_LEFT (ic)))
-                       bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
-
-                     if (IS_SYMOP (IC_RIGHT (ic)))
-                       bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
-                   }
-               }
-
-           }                   /* end of all instructions */
-
-         if (!ebbs[i]->sch && !ebbs[i]->noPath)
-           disconBBlock (ebbs[i], ebbi);
-
-       }                       /* end of for all blocks */
+            }                   /* end of all instructions */
+
+          if (!ebbs[i]->sch && !ebbs[i]->noPath)
+            disconBBlock (ebbs[i], ebbi);
+
+        }                       /* end of for all blocks */
 
       if (!change)
 
       if (!change)
-       break;
-    }                          /* end of while(1) */
+        break;
+    }                           /* end of while(1) */
 
   return gchange;
 }
 
   return gchange;
 }
@@ -1046,7 +1359,7 @@ killDeadCode (ebbIndex * ebbi)
 /*-----------------------------------------------------------------*/
 /* printCyclomatic - prints the cyclomatic information             */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* printCyclomatic - prints the cyclomatic information             */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 printCyclomatic (eBBlock ** ebbs, int count)
 {
   int nEdges = elementsInSet (graphEdges);
 printCyclomatic (eBBlock ** ebbs, int count)
 {
   int nEdges = elementsInSet (graphEdges);
@@ -1063,7 +1376,7 @@ printCyclomatic (eBBlock ** ebbs, int count)
 /* discardDeadParamReceives - remove any RECEIVE opcodes which     */
 /* refer to dead variables.                                        */
 /*-----------------------------------------------------------------*/
 /* discardDeadParamReceives - remove any RECEIVE opcodes which     */
 /* refer to dead variables.                                        */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 discardDeadParamReceives (eBBlock ** ebbs, int count)
 {
   int i;
 discardDeadParamReceives (eBBlock ** ebbs, int count)
 {
   int i;
@@ -1073,22 +1386,22 @@ discardDeadParamReceives (eBBlock ** ebbs, int count)
   for (i = 0; i < count; i++)
     {
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
   for (i = 0; i < count; i++)
     {
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       {
-         if (ic->op == RECEIVE)
-           {
-             if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
-                 && !OP_SYMBOL (IC_RESULT (ic))->used)
-               {
+        {
+          if (ic->op == RECEIVE)
+            {
+              if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
+                  && !OP_SYMBOL (IC_RESULT (ic))->used)
+                {
 #if 0
 #if 0
-                 fprintf (stderr, "discarding dead receive for %s\n",
-                          OP_SYMBOL (IC_RESULT (ic))->name);
+                  fprintf (stderr, "discarding dead receive for %s\n",
+                           OP_SYMBOL (IC_RESULT (ic))->name);
 #endif
 #endif
-                 dummyIcode.next = ic->next;
-                 remiCodeFromeBBlock (ebbs[i], ic);
-                 ic = &dummyIcode;
-               }
-           }
-       }
+                  dummyIcode.next = ic->next;
+                  remiCodeFromeBBlock (ebbs[i], ic);
+                  ic = &dummyIcode;
+                }
+            }
+        }
     }
 }
 
     }
 }
 
@@ -1099,7 +1412,7 @@ discardDeadParamReceives (eBBlock ** ebbs, int count)
 /* char and long are the same, the cast can be safely performed in */
 /* a single step.                                                  */
 /*-----------------------------------------------------------------*/
 /* char and long are the same, the cast can be safely performed in */
 /* a single step.                                                  */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 optimizeCastCast (eBBlock ** ebbs, int count)
 {
   int i;
 optimizeCastCast (eBBlock ** ebbs, int count)
 {
   int i;
@@ -1113,52 +1426,52 @@ optimizeCastCast (eBBlock ** ebbs, int count)
   for (i = 0; i < count; i++)
     {
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
   for (i = 0; i < count; i++)
     {
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       {
-         
-         if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
-           {
-             type1 = operandType (IC_RIGHT (ic));
-             type2 = operandType (IC_RESULT (ic));
-
-             /* Look only for a cast from an integer type to an */
-             /* integer type that has no loss of bits */
-             if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
-               continue;
-             if (getSize (type2) < getSize (type1))
-               continue;
-             
-             /* There must be only one use of this first result */
-             if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
-               continue;
-             
-             /* This use must be a second cast */
-             uic = hTabItemWithKey (iCodehTab,
-                       bitVectFirstBit (OP_USES (IC_RESULT (ic))));
-             if (!uic || uic->op != CAST)
-               continue;
-  
-             /* It must be a cast to another integer type that */
-             /* has no loss of bits */
-             type3 = operandType (IC_RESULT (uic));
-             if (!IS_INTEGRAL (type3))
-                continue;
-             if (getSize (type3) < getSize (type2))
-                continue;
-             
-             /* The signedness between the first and last types */
-             /* must match */
-             if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
-                continue;
-
-             /* Change the first cast to a simple assignment and */
-             /* let the second cast do all the work */
-             ic->op = '=';
-             IC_LEFT (ic) = NULL;
-             sym = OP_SYMBOL (IC_RESULT (ic));
-             sym->type = copyLinkChain (type1);
-             sym->etype = getSpec (sym->type);
-           }
-       }
+        {
+
+          if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
+            {
+              type1 = operandType (IC_RIGHT (ic));
+              type2 = operandType (IC_RESULT (ic));
+
+              /* Look only for a cast from an integer type to an */
+              /* integer type that has no loss of bits */
+              if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
+                continue;
+              if (getSize (type2) < getSize (type1))
+                continue;
+
+              /* There must be only one use of this first result */
+              if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
+                continue;
+
+              /* This use must be a second cast */
+              uic = hTabItemWithKey (iCodehTab,
+                        bitVectFirstBit (OP_USES (IC_RESULT (ic))));
+              if (!uic || uic->op != CAST)
+                continue;
+
+              /* It must be a cast to another integer type that */
+              /* has no loss of bits */
+              type3 = operandType (IC_RESULT (uic));
+              if (!IS_INTEGRAL (type3))
+                 continue;
+              if (getSize (type3) < getSize (type2))
+                 continue;
+
+              /* The signedness between the first and last types */
+              /* must match */
+              if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
+                 continue;
+
+              /* Change the first cast to a simple assignment and */
+              /* let the second cast do all the work */
+              ic->op = '=';
+              IC_LEFT (ic) = NULL;
+              sym = OP_SYMBOL (IC_RESULT (ic));
+              sym->type = copyLinkChain (type1);
+              sym->etype = getSpec (sym->type);
+            }
+        }
     }
 }
 
     }
 }
 
@@ -1170,9 +1483,6 @@ eBBlock **
 eBBlockFromiCode (iCode * ic)
 {
   ebbIndex *ebbi = NULL;
 eBBlockFromiCode (iCode * ic)
 {
   ebbIndex *ebbi = NULL;
-  //eBBlock **ebbs = NULL;
-  //int count = 0;
-  //int saveCount = 0;
   int change = 1;
   int lchange = 0;
   int kchange = 0;
   int change = 1;
   int lchange = 0;
   int kchange = 0;
@@ -1182,23 +1492,22 @@ eBBlockFromiCode (iCode * ic)
   if (!ic)
     return NULL;
 
   if (!ic)
     return NULL;
 
-  //count = 0;
   eBBNum = 0;
 
   eBBNum = 0;
 
-  /* optimize the chain for labels & gotos 
+  /* optimize the chain for labels & gotos
      this will eliminate redundant labels and
      will change jump to jumps by jumps */
   ic = iCodeLabelOptimize (ic);
 
   /* break it down into basic blocks */
   ebbi = iCodeBreakDown (ic);
      this will eliminate redundant labels and
      will change jump to jumps by jumps */
   ic = iCodeLabelOptimize (ic);
 
   /* break it down into basic blocks */
   ebbi = iCodeBreakDown (ic);
-  
+
   /* hash the iCode keys so that we can quickly index */
   /* them in the rest of the optimization steps */
   setToNull ((void *) &iCodehTab);
   iCodehTab = newHashTable (iCodeKey);
   hashiCodeKeys (ebbi->bbOrder, ebbi->count);
   /* hash the iCode keys so that we can quickly index */
   /* them in the rest of the optimization steps */
   setToNull ((void *) &iCodehTab);
   iCodehTab = newHashTable (iCodeKey);
   hashiCodeKeys (ebbi->bbOrder, ebbi->count);
-  
+
   /* compute the control flow */
   computeControlFlow (ebbi);
 
   /* compute the control flow */
   computeControlFlow (ebbi);
 
@@ -1220,7 +1529,7 @@ eBBlockFromiCode (iCode * ic)
     dumpEbbsToFileExt (DUMP_RAW1, ebbi);
 
   optimizeCastCast (ebbi->bbOrder, ebbi->count);
     dumpEbbsToFileExt (DUMP_RAW1, ebbi);
 
   optimizeCastCast (ebbi->bbOrder, ebbi->count);
-    
+
   /* do common subexpression elimination for each block */
   change = cseAllBlocks (ebbi, FALSE);
 
   /* do common subexpression elimination for each block */
   change = cseAllBlocks (ebbi, FALSE);
 
@@ -1240,7 +1549,7 @@ eBBlockFromiCode (iCode * ic)
     {
       change += cseAllBlocks (ebbi, FALSE);
       if (options.dump_gcse)
     {
       change += cseAllBlocks (ebbi, FALSE);
       if (options.dump_gcse)
-       dumpEbbsToFileExt (DUMP_GCSE, ebbi);
+        dumpEbbsToFileExt (DUMP_GCSE, ebbi);
     }
   else
     {
     }
   else
     {
@@ -1258,7 +1567,7 @@ eBBlockFromiCode (iCode * ic)
   if (options.dump_loop)
     dumpEbbsToFileExt (DUMP_LOOP, ebbi);
 
   if (options.dump_loop)
     dumpEbbsToFileExt (DUMP_LOOP, ebbi);
 
-  /* recompute the data flow and apply global cse again 
+  /* recompute the data flow and apply global cse again
      if loops optimizations or dead code caused a change:
      loops will brings out of the loop which then may be
      available for use in the later blocks: dead code
      if loops optimizations or dead code caused a change:
      loops will brings out of the loop which then may be
      available for use in the later blocks: dead code
@@ -1270,7 +1579,7 @@ eBBlockFromiCode (iCode * ic)
       computeDataFlow (ebbi);
       change += cseAllBlocks (ebbi, FALSE);
       if (options.dump_loop)
       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
 
       /* if loop optimizations caused a change then do
          dead code elimination once more : this will
@@ -1279,7 +1588,7 @@ eBBlockFromiCode (iCode * ic)
       killDeadCode (ebbi);
 
       if (options.dump_loop)
       killDeadCode (ebbi);
 
       if (options.dump_loop)
-       dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
+        dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
 
     }
 
 
     }
 
@@ -1292,16 +1601,16 @@ eBBlockFromiCode (iCode * ic)
       // the user is on his own with naked functions...
       if (!IS_VOID(currFunc->etype)
        && !FUNC_ISNAKED(currFunc->type)) {
       // the user is on his own with naked functions...
       if (!IS_VOID(currFunc->etype)
        && !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); 
-            bp; 
-            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);
-         }
-       }
+        eBBlock *bp;
+        // make sure all predecessors of the last block end in a return
+        for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
+             bp;
+             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);
+          }
+        }
       }
     }
   }
       }
     }
   }
@@ -1311,13 +1620,13 @@ eBBlockFromiCode (iCode * ic)
     printCyclomatic (ebbi->bbOrder, ebbi->count);
 
   /* convert operations with support routines
     printCyclomatic (ebbi->bbOrder, ebbi->count);
 
   /* convert operations with support routines
-     written in C to function calls : Iam doing
+     written in C to function calls : I am doing
      this at this point since I want all the
      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 */
   convertToFcall (ebbi->bbOrder, ebbi->count);
 
   /* compute the live ranges */
-  computeLiveRanges (ebbi->bbOrder, ebbi->count);
+  computeLiveRanges (ebbi->bbOrder, ebbi->count, TRUE);
 
   if (options.dump_range)
     dumpEbbsToFileExt (DUMP_RANGE, ebbi);
 
   if (options.dump_range)
     dumpEbbsToFileExt (DUMP_RANGE, ebbi);
@@ -1332,7 +1641,7 @@ eBBlockFromiCode (iCode * ic)
 
   /* throw away blocks */
   setToNull ((void *) &graphEdges);
 
   /* throw away blocks */
   setToNull ((void *) &graphEdges);
-  
+
   return NULL;
 }
 
   return NULL;
 }