* fixed GCC 4.4.0 mingw compilation:
[fw/sdcc] / src / mcs51 / ralloc.c
index b95be782224a6ec05d214b47a8bbfc69c395a530..589da661e9a0e78395cd4cbcc8cdd888bdfacbc8 100644 (file)
@@ -8,19 +8,19 @@
    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 "common.h"
 -------------------------------------------------------------------------*/
 
 #include "common.h"
@@ -48,35 +48,47 @@ static struct
     bitVect *totRegAssigned;    /* final set of LRs that got into registers */
     short blockSpil;
     int slocNum;
     bitVect *totRegAssigned;    /* final set of LRs that got into registers */
     short blockSpil;
     int slocNum;
-    bitVect *funcrUsed;                /* registers used in a function */
+    bitVect *funcrUsed;         /* registers used in a function */
     int stackExtend;
     int dataExtend;
     int stackExtend;
     int dataExtend;
+    bitVect *allBitregs;        /* all bit registers */
   }
 _G;
 
 /* Shared with gen.c */
   }
 _G;
 
 /* Shared with gen.c */
-int mcs51_ptrRegReq;           /* one byte pointer register required */
+int mcs51_ptrRegReq;            /* one byte pointer register required */
 
 /* 8051 registers */
 regs regs8051[] =
 {
 
 /* 8051 registers */
 regs regs8051[] =
 {
-
-  {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1},
-  {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1},
-  {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1},
-  {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1},
-  {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1},
-  {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1},
-  {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1},
-  {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1},
-  {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1},
-  {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1},
+  {REG_GPR, R2_IDX,  REG_GPR, "r2",  "ar2", "0",    2, 1},
+  {REG_GPR, R3_IDX,  REG_GPR, "r3",  "ar3", "0",    3, 1},
+  {REG_GPR, R4_IDX,  REG_GPR, "r4",  "ar4", "0",    4, 1},
+  {REG_GPR, R5_IDX,  REG_GPR, "r5",  "ar5", "0",    5, 1},
+  {REG_GPR, R6_IDX,  REG_GPR, "r6",  "ar6", "0",    6, 1},
+  {REG_GPR, R7_IDX,  REG_GPR, "r7",  "ar7", "0",    7, 1},
+  {REG_PTR, R0_IDX,  REG_PTR, "r0",  "ar0", "0",    0, 1},
+  {REG_PTR, R1_IDX,  REG_PTR, "r1",  "ar1", "0",    1, 1},
+  {REG_BIT, B0_IDX,  REG_BIT, "b0",  "b0",  "bits", 0, 1},
+  {REG_BIT, B1_IDX,  REG_BIT, "b1",  "b1",  "bits", 1, 1},
+  {REG_BIT, B2_IDX,  REG_BIT, "b2",  "b2",  "bits", 2, 1},
+  {REG_BIT, B3_IDX,  REG_BIT, "b3",  "b3",  "bits", 3, 1},
+  {REG_BIT, B4_IDX,  REG_BIT, "b4",  "b4",  "bits", 4, 1},
+  {REG_BIT, B5_IDX,  REG_BIT, "b5",  "b5",  "bits", 5, 1},
+  {REG_BIT, B6_IDX,  REG_BIT, "b6",  "b6",  "bits", 6, 1},
+  {REG_BIT, B7_IDX,  REG_BIT, "b7",  "b7",  "bits", 7, 1},
+  {REG_GPR, X8_IDX,  REG_GPR, "x8",  "x8",  "xreg", 0, 1},
+  {REG_GPR, X9_IDX,  REG_GPR, "x9",  "x9",  "xreg", 1, 1},
   {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1},
   {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 1},
   {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 1},
   {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1},
   {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 1},
   {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 1},
-  {REG_CND, CND_IDX, REG_CND, "C", "C", "xreg", 0, 1},
+  {REG_CND, CND_IDX, REG_CND, "C",   "psw", "0xd0", 0, 1},
+  {0,       DPL_IDX, 0,       "dpl", "dpl", "0x82", 0, 0},
+  {0,       DPH_IDX, 0,       "dph", "dph", "0x83", 0, 0},
+  {0,       B_IDX,   0,       "b",   "b",   "0xf0", 0, 0},
+  {0,       A_IDX,   0,       "a",   "acc", "0xe0", 0, 0},
 };
 };
-int mcs51_nRegs = 13;
+int mcs51_nRegs = 16;
 static void spillThis (symbol *);
 static void freeAllRegs ();
 
 static void spillThis (symbol *);
 static void freeAllRegs ();
 
@@ -90,47 +102,59 @@ allocReg (short type)
 
   for (i = 0; i < mcs51_nRegs; i++)
     {
 
   for (i = 0; i < mcs51_nRegs; i++)
     {
-
       /* if type is given as 0 then any
          free register will do */
       /* if type is given as 0 then any
          free register will do */
-      if (!type &&
-         regs8051[i].isFree)
-       {
-         regs8051[i].isFree = 0;
-         if (currFunc)
-           currFunc->regsUsed =
-             bitVectSetBit (currFunc->regsUsed, i);
-         return &regs8051[i];
-       }
+      if (!type && regs8051[i].isFree)
+        {
+          regs8051[i].isFree = 0;
+          if (currFunc)
+            currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i);
+          return &regs8051[i];
+        }
       /* other wise look for specific type
          of register */
       /* other wise look for specific type
          of register */
-      if (regs8051[i].isFree &&
-         regs8051[i].type == type)
-       {
-         regs8051[i].isFree = 0;
-         if (currFunc)
-           currFunc->regsUsed =
-             bitVectSetBit (currFunc->regsUsed, i);
-         return &regs8051[i];
-       }
+      if (regs8051[i].isFree && regs8051[i].type == type)
+        {
+          regs8051[i].isFree = 0;
+          if (currFunc)
+            currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i);
+          return &regs8051[i];
+        }
     }
   return NULL;
 }
 
 /*-----------------------------------------------------------------*/
     }
   return NULL;
 }
 
 /*-----------------------------------------------------------------*/
-/* mcs51_regWithIdx - returns pointer to register wit index number       */
+/* allocThisReg - allocates a particular register (if free)        */
+/*-----------------------------------------------------------------*/
+static regs *
+allocThisReg (regs * reg)
+{
+  if (!reg->isFree)
+    return NULL;
+
+  reg->isFree = 0;
+  if (currFunc)
+    currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
+
+  return reg;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* mcs51_regWithIdx - returns pointer to register with index number*/
 /*-----------------------------------------------------------------*/
 regs *
 mcs51_regWithIdx (int idx)
 {
   int i;
 
 /*-----------------------------------------------------------------*/
 regs *
 mcs51_regWithIdx (int idx)
 {
   int i;
 
-  for (i = 0; i < mcs51_nRegs; i++)
+  for (i = 0; i < sizeof(regs8051)/sizeof(regs); i++)
     if (regs8051[i].rIdx == idx)
       return &regs8051[i];
 
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
     if (regs8051[i].rIdx == idx)
       return &regs8051[i];
 
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-         "regWithIdx not found");
+          "regWithIdx not found");
   exit (1);
 }
 
   exit (1);
 }
 
@@ -143,7 +167,7 @@ freeReg (regs * reg)
   if (!reg)
     {
       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
   if (!reg)
     {
       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-             "freeReg - Freeing NULL register");
+              "freeReg - Freeing NULL register");
       exit (1);
     }
 
       exit (1);
     }
 
@@ -176,7 +200,7 @@ nfreeRegsType (int type)
   if (type == REG_PTR)
     {
       if ((nfr = nFreeRegs (type)) == 0)
   if (type == REG_PTR)
     {
       if ((nfr = nFreeRegs (type)) == 0)
-       return nFreeRegs (REG_GPR);
+        return nFreeRegs (REG_GPR);
     }
 
   return nFreeRegs (type);
     }
 
   return nFreeRegs (type);
@@ -199,22 +223,30 @@ computeSpillable (iCode * ic)
 {
   bitVect *spillable;
 
 {
   bitVect *spillable;
 
-  /* spillable live ranges are those that are live at this 
+  /* spillable live ranges are those that are live at this
      point . the following categories need to be subtracted
      point . the following categories need to be subtracted
-     from this set. 
+     from this set.
      a) - those that are already spilt
      b) - if being used by this one
      c) - defined by this one */
 
   spillable = bitVectCopy (ic->rlive);
   spillable =
      a) - those that are already spilt
      b) - if being used by this one
      c) - defined by this one */
 
   spillable = bitVectCopy (ic->rlive);
   spillable =
-    bitVectCplAnd (spillable, _G.spiltSet);    /* those already spilt */
+    bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
   spillable =
   spillable =
-    bitVectCplAnd (spillable, ic->uses);       /* used in this one */
+    bitVectCplAnd (spillable, ic->uses);        /* used in this one */
   bitVectUnSetBit (spillable, ic->defKey);
   spillable = bitVectIntersect (spillable, _G.regAssigned);
   return spillable;
   bitVectUnSetBit (spillable, ic->defKey);
   spillable = bitVectIntersect (spillable, _G.regAssigned);
   return spillable;
+}
 
 
+/*-----------------------------------------------------------------*/
+/* bitType - will return 1 if the symbol has type REG_BIT          */
+/*-----------------------------------------------------------------*/
+static int
+bitType (symbol * sym, eBBlock * ebp, iCode * ic)
+{
+  return (sym->regType == REG_BIT ? 1 : 0);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -236,7 +268,7 @@ hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* directSpilLoc - will return 1 if the splilocation is in direct  */
+/* directSpilLoc - will return 1 if the spillocation is in direct  */
 /*-----------------------------------------------------------------*/
 static int
 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
 /*-----------------------------------------------------------------*/
 static int
 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
@@ -274,7 +306,7 @@ static int
 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
 {
   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
 {
   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
-         allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
+          allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -291,7 +323,7 @@ allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
 /*-----------------------------------------------------------------*/
 static set *
 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
 /*-----------------------------------------------------------------*/
 static set *
 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
-               eBBlock * ebp, iCode * ic)
+                eBBlock * ebp, iCode * ic)
 {
   set *rset = NULL;
   int i;
 {
   set *rset = NULL;
   int i;
@@ -303,19 +335,19 @@ liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
     {
       symbol *sym;
       if (!bitVectBitValue (lrs, i))
     {
       symbol *sym;
       if (!bitVectBitValue (lrs, i))
-       continue;
+        continue;
 
 
-      /* if we don't find it in the live range 
+      /* if we don't find it in the live range
          hash table we are in serious trouble */
       if (!(sym = hTabItemWithKey (liveRanges, i)))
          hash table we are in serious trouble */
       if (!(sym = hTabItemWithKey (liveRanges, i)))
-       {
-         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-                 "liveRangesWith could not find liveRange");
-         exit (1);
-       }
+        {
+          werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                  "liveRangesWith could not find liveRange");
+          exit (1);
+        }
 
       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
 
       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
-       addSetHead (&rset, sym);
+        addSetHead (&rset, sym);
     }
 
   return rset;
     }
 
   return rset;
@@ -337,20 +369,18 @@ leastUsedLR (set * sset)
 
   for (; lsym; lsym = setNextItem (sset))
     {
 
   for (; lsym; lsym = setNextItem (sset))
     {
-
       /* if usage is the same then prefer
       /* if usage is the same then prefer
-         the spill the smaller of the two */
+         to spill the smaller of the two */
       if (lsym->used == sym->used)
       if (lsym->used == sym->used)
-       if (getSize (lsym->type) < getSize (sym->type))
-         sym = lsym;
+        if (getSize (lsym->type) < getSize (sym->type))
+          sym = lsym;
 
       /* if less usage */
       if (lsym->used < sym->used)
 
       /* if less usage */
       if (lsym->used < sym->used)
-       sym = lsym;
-
+        sym = lsym;
     }
 
     }
 
-  setToNull ((void **) &sset);
+  setToNull ((void *) &sset);
   sym->blockSpil = 0;
   return sym;
 }
   sym->blockSpil = 0;
   return sym;
 }
@@ -363,13 +393,11 @@ noOverLap (set * itmpStack, symbol * fsym)
 {
   symbol *sym;
 
 {
   symbol *sym;
 
-
   for (sym = setFirstItem (itmpStack); sym;
        sym = setNextItem (itmpStack))
     {
   for (sym = setFirstItem (itmpStack); sym;
        sym = setNextItem (itmpStack))
     {
-       if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
+        if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
     }
     }
-
   return 1;
 }
 
   return 1;
 }
 
@@ -412,8 +440,7 @@ spillLRWithPtrReg (symbol * forSym)
   regs *r0, *r1;
   int k;
 
   regs *r0, *r1;
   int k;
 
-  if (!_G.regAssigned ||
-      bitVectIsZero (_G.regAssigned))
+  if (!_G.regAssigned || bitVectIsZero (_G.regAssigned))
     return;
 
   r0 = mcs51_regWithIdx (R0_IDX);
     return;
 
   r0 = mcs51_regWithIdx (R0_IDX);
@@ -426,24 +453,23 @@ spillLRWithPtrReg (symbol * forSym)
       int j;
 
       /* if no registers assigned to it or spilt */
       int j;
 
       /* if no registers assigned to it or spilt */
-      /* if it does not overlap with this then 
-         not need to spill it */
+      /* if it does not overlap this then
+         no need to spill it */
 
       if (lrsym->isspilt || !lrsym->nRegs ||
 
       if (lrsym->isspilt || !lrsym->nRegs ||
-         (lrsym->liveTo < forSym->liveFrom))
-       continue;
+          (lrsym->liveTo < forSym->liveFrom))
+        continue;
 
       /* go thru the registers : if it is either
 
       /* go thru the registers : if it is either
-         r0 or r1 then spil it */
+         r0 or r1 then spill it */
       for (j = 0; j < lrsym->nRegs; j++)
       for (j = 0; j < lrsym->nRegs; j++)
-       if (lrsym->regs[j] == r0 ||
-           lrsym->regs[j] == r1)
-         {
-           spillThis (lrsym);
-           break;
-         }
+        if (lrsym->regs[j] == r0 ||
+            lrsym->regs[j] == r1)
+          {
+            spillThis (lrsym);
+            break;
+          }
     }
     }
-
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -457,7 +483,7 @@ createStackSpil (symbol * sym)
 
   char slocBuffer[30];
 
 
   char slocBuffer[30];
 
-  /* first go try and find a free one that is already 
+  /* first go try and find a free one that is already
      existing on the stack */
   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
     {
      existing on the stack */
   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
     {
@@ -473,10 +499,11 @@ createStackSpil (symbol * sym)
      we need to allocate this on the stack : this is really a
      hack!! but cannot think of anything better at this time */
 
      we need to allocate this on the stack : this is really a
      hack!! but cannot think of anything better at this time */
 
-  if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
+  if (SNPRINTF (slocBuffer, sizeof(slocBuffer),
+                "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
     {
       fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
     {
       fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
-              __FILE__, __LINE__);
+               __FILE__, __LINE__);
       exit (1);
     }
 
       exit (1);
     }
 
@@ -485,13 +512,20 @@ createStackSpil (symbol * sym)
   /* set the type to the spilling symbol */
   sloc->type = copyLinkChain (sym->type);
   sloc->etype = getSpec (sloc->type);
   /* set the type to the spilling symbol */
   sloc->type = copyLinkChain (sym->type);
   sloc->etype = getSpec (sloc->type);
-  SPEC_SCLS (sloc->etype) = S_DATA;
+  if (!IS_BIT (sloc->etype))
+    {
+      SPEC_SCLS (sloc->etype) = S_DATA;
+    }
+  else if (SPEC_SCLS (sloc->etype) == S_SBIT)
+    {
+      SPEC_SCLS (sloc->etype) = S_BIT;
+    }
   SPEC_EXTR (sloc->etype) = 0;
   SPEC_STAT (sloc->etype) = 0;
   SPEC_VOLATILE(sloc->etype) = 0;
   SPEC_ABSA(sloc->etype) = 0;
 
   SPEC_EXTR (sloc->etype) = 0;
   SPEC_STAT (sloc->etype) = 0;
   SPEC_VOLATILE(sloc->etype) = 0;
   SPEC_ABSA(sloc->etype) = 0;
 
-  /* we don't allow it to be allocated`
+  /* we don't allow it to be allocated
      onto the external stack since : so we
      temporarily turn it off ; we also
      turn off memory model to prevent
      onto the external stack since : so we
      temporarily turn it off ; we also
      turn off memory model to prevent
@@ -509,7 +543,7 @@ createStackSpil (symbol * sym)
   options.useXstack = useXstack;
   options.model = model;
 /*     options.noOverlay = noOverlay; */
   options.useXstack = useXstack;
   options.model = model;
 /*     options.noOverlay = noOverlay; */
-  sloc->isref = 1;             /* to prevent compiler warning */
+  sloc->isref = 1;              /* to prevent compiler warning */
 
   /* if it is on the stack then update the stack */
   if (IN_STACK (sloc->etype))
 
   /* if it is on the stack then update the stack */
   if (IN_STACK (sloc->etype))
@@ -525,7 +559,7 @@ createStackSpil (symbol * sym)
   sym->usl.spillLoc = sloc;
   sym->stackSpil = 1;
 
   sym->usl.spillLoc = sloc;
   sym->stackSpil = 1;
 
-  /* add it to the set of itempStack set 
+  /* add it to the set of itempStack set
      of the spill location */
   addSetHead (&sloc->usl.itmpStack, sym);
   return sym;
      of the spill location */
   addSetHead (&sloc->usl.itmpStack, sym);
   return sym;
@@ -533,6 +567,7 @@ createStackSpil (symbol * sym)
 
 /*-----------------------------------------------------------------*/
 /* isSpiltOnStack - returns true if the spil location is on stack  */
 
 /*-----------------------------------------------------------------*/
 /* isSpiltOnStack - returns true if the spil location is on stack  */
+/*                  or otherwise needs a pointer register          */
 /*-----------------------------------------------------------------*/
 static bool
 isSpiltOnStack (symbol * sym)
 /*-----------------------------------------------------------------*/
 static bool
 isSpiltOnStack (symbol * sym)
@@ -551,6 +586,9 @@ isSpiltOnStack (symbol * sym)
   if (!sym->usl.spillLoc)
     return FALSE;
 
   if (!sym->usl.spillLoc)
     return FALSE;
 
+  if (sym->usl.spillLoc->onStack || sym->usl.spillLoc->iaccess)
+    return TRUE;
+
   etype = getSpec (sym->usl.spillLoc->type);
   if (IN_STACK (etype))
     return TRUE;
   etype = getSpec (sym->usl.spillLoc->type);
   if (IN_STACK (etype))
     return TRUE;
@@ -571,7 +609,6 @@ spillThis (symbol * sym)
   if (!(sym->remat || sym->usl.spillLoc))
     createStackSpil (sym);
 
   if (!(sym->remat || sym->usl.spillLoc))
     createStackSpil (sym);
 
-
   /* mark it has spilt & put it in the spilt set */
   sym->isspilt = sym->spillA = 1;
   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
   /* mark it has spilt & put it in the spilt set */
   sym->isspilt = sym->spillA = 1;
   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
@@ -580,20 +617,21 @@ spillThis (symbol * sym)
   bitVectUnSetBit (_G.totRegAssigned, sym->key);
 
   for (i = 0; i < sym->nRegs; i++)
   bitVectUnSetBit (_G.totRegAssigned, sym->key);
 
   for (i = 0; i < sym->nRegs; i++)
+    {
+      if (sym->regs[i])
+        {
+          freeReg (sym->regs[i]);
+          sym->regs[i] = NULL;
+        }
+    }
 
 
-    if (sym->regs[i])
-      {
-       freeReg (sym->regs[i]);
-       sym->regs[i] = NULL;
-      }
-
-  /* if spilt on stack then free up r0 & r1 
+  /* if spilt on stack then free up r0 & r1
      if they could have been assigned to some
      LIVE ranges */
   if (!mcs51_ptrRegReq && isSpiltOnStack (sym))
     {
      if they could have been assigned to some
      LIVE ranges */
   if (!mcs51_ptrRegReq && isSpiltOnStack (sym))
     {
-      mcs51_ptrRegReq++;
       spillLRWithPtrReg (sym);
       spillLRWithPtrReg (sym);
+      mcs51_ptrRegReq++;
     }
 
   if (sym->usl.spillLoc && !sym->remat)
     }
 
   if (sym->usl.spillLoc && !sym->remat)
@@ -614,10 +652,20 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* get the spillable live ranges */
   lrcs = computeSpillable (ic);
 
   /* get the spillable live ranges */
   lrcs = computeSpillable (ic);
 
-  /* get all live ranges that are rematerizable */
-  if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
+  /* remove incompatible registers */
+  if ((forSym->regType == REG_PTR) || (forSym->regType == REG_GPR))
     {
     {
+      selectS = liveRangesWith (lrcs, bitType, ebp, ic);
+      
+      for (sym = setFirstItem (selectS); sym; sym = setNextItem (selectS))
+        {
+          bitVectUnSetBit (lrcs, sym->key);
+        }
+    }
 
 
+  /* get all live ranges that are rematerializable */
+  if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
+    {
       /* return the least used of these */
       return leastUsedLR (selectS);
     }
       /* return the least used of these */
       return leastUsedLR (selectS);
     }
@@ -626,9 +674,10 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
     {
       sym = leastUsedLR (selectS);
   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
     {
       sym = leastUsedLR (selectS);
-      strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
-                          sym->usl.spillLoc->rname :
-                          sym->usl.spillLoc->name));
+      strncpyz (sym->rname,
+                sym->usl.spillLoc->rname[0] ?
+                   sym->usl.spillLoc->rname : sym->usl.spillLoc->name,
+                sizeof(sym->rname));
       sym->spildir = 1;
       /* mark it as allocation required */
       sym->usl.spillLoc->allocreq++;
       sym->spildir = 1;
       /* mark it as allocation required */
       sym->usl.spillLoc->allocreq++;
@@ -638,42 +687,42 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* if the symbol is local to the block then */
   if (forSym->liveTo < ebp->lSeq)
     {
   /* if the symbol is local to the block then */
   if (forSym->liveTo < ebp->lSeq)
     {
-
       /* check if there are any live ranges allocated
          to registers that are not used in this block */
       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
       /* check if there are any live ranges allocated
          to registers that are not used in this block */
       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
-       {
-         sym = leastUsedLR (selectS);
-         /* if this is not rematerializable */
-         if (!sym->remat)
-           {
-             _G.blockSpil++;
-             sym->blockSpil = 1;
-           }
-         return sym;
-       }
-
-      /* check if there are any live ranges that not
-         used in the remainder of the block */
-      if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
-       {
-         sym = leastUsedLR (selectS);
-         if (sym != forSym)
-           {
-             if (!sym->remat)
-               {
-                 sym->remainSpil = 1;
-                 _G.blockSpil++;
-               }
-             return sym;
-           }
-       }
+        {
+          sym = leastUsedLR (selectS);
+          /* if this is not rematerializable */
+          if (!sym->remat)
+            {
+              _G.blockSpil++;
+              sym->blockSpil = 1;
+            }
+          return sym;
+        }
+
+      /* check if there are any live ranges that are
+         not used in the remainder of the block */
+      if (!_G.blockSpil &&
+          !isiCodeInFunctionCall (ic) &&
+          (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
+        {
+          sym = leastUsedLR (selectS);
+          if (sym != forSym)
+            {
+              if (!sym->remat)
+                {
+                  sym->remainSpil = 1;
+                  _G.blockSpil++;
+                }
+              return sym;
+            }
+        }
     }
 
   /* find live ranges with spillocation && not used as pointers */
   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
     {
     }
 
   /* find live ranges with spillocation && not used as pointers */
   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
     {
-
       sym = leastUsedLR (selectS);
       /* mark this as allocation required */
       sym->usl.spillLoc->allocreq++;
       sym = leastUsedLR (selectS);
       /* mark this as allocation required */
       sym->usl.spillLoc->allocreq++;
@@ -683,18 +732,16 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* find live ranges with spillocation */
   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
     {
   /* find live ranges with spillocation */
   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
     {
-
       sym = leastUsedLR (selectS);
       sym->usl.spillLoc->allocreq++;
       return sym;
     }
 
   /* couldn't find then we need to create a spil
       sym = leastUsedLR (selectS);
       sym->usl.spillLoc->allocreq++;
       return sym;
     }
 
   /* couldn't find then we need to create a spil
-     location on the stack , for which one? the least
-     used ofcourse */
+     location on the stack, for which one?
+     the least used ofcourse */
   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
     {
   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
     {
-
       /* return a created spil location */
       sym = createStackSpil (leastUsedLR (selectS));
       sym->usl.spillLoc->allocreq++;
       /* return a created spil location */
       sym = createStackSpil (leastUsedLR (selectS));
       sym->usl.spillLoc->allocreq++;
@@ -705,7 +752,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
      this one : happens very rarely but it does happen */
   spillThis (forSym);
   return forSym;
      this one : happens very rarely but it does happen */
   spillThis (forSym);
   return forSym;
-
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -734,22 +780,22 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
     if (ssym->regs[i])
       freeReg (ssym->regs[i]);
 
     if (ssym->regs[i])
       freeReg (ssym->regs[i]);
 
-  /* if spilt on stack then free up r0 & r1 
+  /* if spilt on stack then free up r0 & r1
      if they could have been assigned to as gprs */
   if (!mcs51_ptrRegReq && isSpiltOnStack (ssym))
     {
      if they could have been assigned to as gprs */
   if (!mcs51_ptrRegReq && isSpiltOnStack (ssym))
     {
-      mcs51_ptrRegReq++;
       spillLRWithPtrReg (ssym);
       spillLRWithPtrReg (ssym);
+      mcs51_ptrRegReq++;
     }
 
     }
 
-  /* if this was a block level spil then insert push & pop 
+  /* if this was a block level spil then insert push & pop
      at the start & end of block respectively */
   if (ssym->blockSpil)
     {
       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
       /* add push to the start of the block */
       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
      at the start & end of block respectively */
   if (ssym->blockSpil)
     {
       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
       /* add push to the start of the block */
       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
-                                   ebp->sch->next : ebp->sch));
+                                    ebp->sch->next : ebp->sch));
       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
       /* add pop to the end of the block */
       addiCodeToeBBlock (ebp, nic, NULL);
       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
       /* add pop to the end of the block */
       addiCodeToeBBlock (ebp, nic, NULL);
@@ -760,7 +806,6 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
      a pop at the end of the block */
   if (ssym->remainSpil)
     {
      a pop at the end of the block */
   if (ssym->remainSpil)
     {
-
       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
       /* add push just before this instruction */
       addiCodeToeBBlock (ebp, nic, ic);
       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
       /* add push just before this instruction */
       addiCodeToeBBlock (ebp, nic, ic);
@@ -783,6 +828,7 @@ static regs *
 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
 tryAgain:
   /* try for a ptr type */
 
 tryAgain:
   /* try for a ptr type */
@@ -797,7 +843,12 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
-  /* this looks like an infinite loop but 
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+
+  /* this looks like an infinite loop but
      in really selectSpil will abort  */
   goto tryAgain;
 }
      in really selectSpil will abort  */
   goto tryAgain;
 }
@@ -809,6 +860,7 @@ static regs *
 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
 tryAgain:
   /* try for gpr type */
 
 tryAgain:
   /* try for gpr type */
@@ -823,13 +875,33 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
-  /* this looks like an infinite loop but 
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+
+  /* this looks like an infinite loop but
      in really selectSpil will abort  */
   goto tryAgain;
 }
 
 /*-----------------------------------------------------------------*/
      in really selectSpil will abort  */
   goto tryAgain;
 }
 
 /*-----------------------------------------------------------------*/
-/* getRegPtrNoSpil - get it cannot split                           */
+/* getRegBit - will try for Bit if not spill this                  */
+/*-----------------------------------------------------------------*/
+static regs *getRegBit (symbol * sym)
+{
+  regs *reg;
+
+  /* try for a bit type */
+  if ((reg = allocReg (REG_BIT)))
+    return reg;
+
+  spillThis (sym);
+  return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* getRegPtrNoSpil - get it cannot be spilt                        */
 /*-----------------------------------------------------------------*/
 static regs *getRegPtrNoSpil()
 {
 /*-----------------------------------------------------------------*/
 static regs *getRegPtrNoSpil()
 {
@@ -850,11 +922,10 @@ static regs *getRegPtrNoSpil()
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* getRegGprNoSpil - get it cannot split                           */
+/* getRegGprNoSpil - get it cannot be spilt                        */
 /*-----------------------------------------------------------------*/
 static regs *getRegGprNoSpil()
 {
 /*-----------------------------------------------------------------*/
 static regs *getRegGprNoSpil()
 {
-
   regs *reg;
   if ((reg = allocReg (REG_GPR)))
     return reg;
   regs *reg;
   if ((reg = allocReg (REG_GPR)))
     return reg;
@@ -869,6 +940,27 @@ static regs *getRegGprNoSpil()
   return 0;
 }
 
   return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* getRegBitNoSpil - get it cannot be spilt                        */
+/*-----------------------------------------------------------------*/
+static regs *getRegBitNoSpil()
+{
+  regs *reg;
+
+  /* try for a ptr type */
+  if ((reg = allocReg (REG_BIT)))
+    return reg;
+
+  /* try for gpr type */
+  if ((reg = allocReg (REG_GPR)))
+    return reg;
+
+  assert(0);
+
+  /* just to make the compiler happy */
+  return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* symHasReg - symbol has a given register                         */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* symHasReg - symbol has a given register                         */
 /*-----------------------------------------------------------------*/
@@ -884,6 +976,29 @@ symHasReg (symbol * sym, regs * reg)
   return FALSE;
 }
 
   return FALSE;
 }
 
+/*-----------------------------------------------------------------*/
+/* updateRegUsage -  update the registers in use at the start of   */
+/*                   this icode                                    */
+/*-----------------------------------------------------------------*/
+static void
+updateRegUsage (iCode * ic)
+{
+  int reg;
+
+  for (reg=0; reg<mcs51_nRegs; reg++)
+    {
+      if (regs8051[reg].isFree)
+        {
+          ic->riu &= ~(1<<regs8051[reg].offset);
+        }
+      else
+        {
+          ic->riu |= (1<<regs8051[reg].offset);
+          BitBankUsed |= (reg >= 8);
+        }
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* deassignLRs - check the live to and if they have registers & are */
 /*               not spilt then free up the registers              */
 /*-----------------------------------------------------------------*/
 /* deassignLRs - check the live to and if they have registers & are */
 /*               not spilt then free up the registers              */
@@ -898,92 +1013,91 @@ deassignLRs (iCode * ic, eBBlock * ebp)
   for (sym = hTabFirstItem (liveRanges, &k); sym;
        sym = hTabNextItem (liveRanges, &k))
     {
   for (sym = hTabFirstItem (liveRanges, &k); sym;
        sym = hTabNextItem (liveRanges, &k))
     {
-
       symbol *psym = NULL;
       /* if it does not end here */
       if (sym->liveTo > ic->seq)
       symbol *psym = NULL;
       /* if it does not end here */
       if (sym->liveTo > ic->seq)
-       continue;
+        continue;
 
 
-      /* if it was spilt on stack then we can 
+      /* if it was spilt on stack then we can
          mark the stack spil location as free */
       if (sym->isspilt)
          mark the stack spil location as free */
       if (sym->isspilt)
-       {
-         if (sym->stackSpil)
-           {
-             sym->usl.spillLoc->isFree = 1;
-             sym->stackSpil = 0;
-           }
-         continue;
-       }
+        {
+          if (sym->stackSpil)
+            {
+              sym->usl.spillLoc->isFree = 1;
+              sym->stackSpil = 0;
+            }
+          continue;
+        }
 
       if (!bitVectBitValue (_G.regAssigned, sym->key))
 
       if (!bitVectBitValue (_G.regAssigned, sym->key))
-       continue;
+        continue;
 
       /* special case check if this is an IFX &
 
       /* special case check if this is an IFX &
-         the privious one was a pop and the 
+         the privious one was a pop and the
          previous one was not spilt then keep track
          of the symbol */
       if (ic->op == IFX && ic->prev &&
          previous one was not spilt then keep track
          of the symbol */
       if (ic->op == IFX && ic->prev &&
-         ic->prev->op == IPOP &&
-         !ic->prev->parmPush &&
-         !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
-       psym = OP_SYMBOL (IC_LEFT (ic->prev));
+          ic->prev->op == IPOP &&
+          !ic->prev->parmPush &&
+          !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
+        psym = OP_SYMBOL (IC_LEFT (ic->prev));
 
       if (sym->nRegs)
 
       if (sym->nRegs)
-       {
-         int i = 0;
-
-         bitVectUnSetBit (_G.regAssigned, sym->key);
-
-         /* if the result of this one needs registers
-            and does not have it then assign it right
-            away */
-         if (IC_RESULT (ic) &&
-             !(SKIP_IC2 (ic) ||        /* not a special icode */
-               ic->op == JUMPTABLE ||
-               ic->op == IFX ||
-               ic->op == IPUSH ||
-               ic->op == IPOP ||
-               ic->op == RETURN ||
-               POINTER_SET (ic)) &&
-             (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
-             result->liveTo > ic->seq &&       /* and will live beyond this */
-             result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
-             result->regType == sym->regType &&        /* same register types */
-             result->nRegs &&  /* which needs registers */
-             !result->isspilt &&       /* and does not already have them */
-             !result->remat &&
-             !bitVectBitValue (_G.regAssigned, result->key) &&
-         /* the number of free regs + number of regs in this LR
-            can accomodate the what result Needs */
-             ((nfreeRegsType (result->regType) +
-               sym->nRegs) >= result->nRegs)
-           )
-           {
-
-             for (i = 0; i < result->nRegs; i++)
-               if (i < sym->nRegs)
-                 result->regs[i] = sym->regs[i];
-               else
-                 result->regs[i] = getRegGpr (ic, ebp, result);
-
-             _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
-             _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
-
-           }
-
-         /* free the remaining */
-         for (; i < sym->nRegs; i++)
-           {
-             if (psym)
-               {
-                 if (!symHasReg (psym, sym->regs[i]))
-                   freeReg (sym->regs[i]);
-               }
-             else
-               freeReg (sym->regs[i]);
-           }
-       }
+        {
+          int i = 0;
+
+          bitVectUnSetBit (_G.regAssigned, sym->key);
+
+          /* if the result of this one needs registers
+             and does not have it then assign it right
+             away */
+          if (IC_RESULT (ic) &&
+              !(SKIP_IC2 (ic) ||        /* not a special icode */
+                ic->op == JUMPTABLE ||
+                ic->op == IFX ||
+                ic->op == IPUSH ||
+                ic->op == IPOP ||
+                ic->op == RETURN ||
+                POINTER_SET (ic)) &&
+              (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
+              result->liveTo > ic->seq &&       /* and will live beyond this */
+              result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
+              result->liveFrom == ic->seq &&    /* does not start before here */
+              result->regType == sym->regType &&        /* same register types */
+              result->nRegs &&  /* which needs registers */
+              !result->isspilt &&       /* and does not already have them */
+              !result->remat &&
+              !bitVectBitValue (_G.regAssigned, result->key) &&
+          /* the number of free regs + number of regs in this LR
+             can accomodate the what result Needs */
+              ((nfreeRegsType (result->regType) +
+                sym->nRegs) >= result->nRegs)
+             )
+            {
+              for (i = 0; i < result->nRegs; i++)
+                if (i < sym->nRegs)
+                  result->regs[i] = sym->regs[i];
+                else
+                  result->regs[i] = getRegGpr (ic, ebp, result);
+
+              _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
+              _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
+
+            }
+
+          /* free the remaining */
+          for (; i < sym->nRegs; i++)
+            {
+              if (psym)
+                {
+                  if (!symHasReg (psym, sym->regs[i]))
+                    freeReg (sym->regs[i]);
+                }
+              else
+                freeReg (sym->regs[i]);
+            }
+        }
     }
 }
 
     }
 }
 
@@ -1016,31 +1130,36 @@ reassignLR (operand * op)
 static int
 willCauseSpill (int nr, int rt)
 {
 static int
 willCauseSpill (int nr, int rt)
 {
-  /* first check if there are any avlb registers
-     of te type required */
+  /* first check if there are any available registers
+     of the type required */
   if (rt == REG_PTR)
     {
   if (rt == REG_PTR)
     {
-      /* special case for pointer type 
-         if pointer type not avlb then 
+      /* special case for pointer type
+         if pointer type not avlb then
          check for type gpr */
       if (nFreeRegs (rt) >= nr)
          check for type gpr */
       if (nFreeRegs (rt) >= nr)
-       return 0;
+        return 0;
       if (nFreeRegs (REG_GPR) >= nr)
       if (nFreeRegs (REG_GPR) >= nr)
-       return 0;
+        return 0;
+    }
+  else if (rt == REG_BIT)
+    {
+      if (nFreeRegs (rt) >= nr)
+        return 0;
     }
   else
     {
       if (mcs51_ptrRegReq)
     }
   else
     {
       if (mcs51_ptrRegReq)
-       {
-         if (nFreeRegs (rt) >= nr)
-           return 0;
-       }
+        {
+          if (nFreeRegs (rt) >= nr)
+            return 0;
+        }
       else
       else
-       {
-         if (nFreeRegs (REG_PTR) +
-             nFreeRegs (REG_GPR) >= nr)
-           return 0;
-       }
+        {
+          if (nFreeRegs (REG_PTR) +
+              nFreeRegs (REG_GPR) >= nr)
+            return 0;
+        }
     }
 
   /* it will cause a spil */
     }
 
   /* it will cause a spil */
@@ -1068,13 +1187,13 @@ again:
   for (i = 0; i < count; i++)
     {
       for (j = 0; j < count; j++)
   for (i = 0; i < count; i++)
     {
       for (j = 0; j < count; j++)
-       {
-         if (result->regs[i] == opsym->regs[j] && i != j)
-           {
-             shared = 1;
-             goto xchgPositions;
-           }
-       }
+        {
+          if (result->regs[i] == opsym->regs[j] && i != j)
+            {
+              shared = 1;
+              goto xchgPositions;
+            }
+        }
     }
 xchgPositions:
   if (shared)
     }
 xchgPositions:
   if (shared)
@@ -1088,153 +1207,300 @@ xchgPositions:
   return change;
 }
 
   return change;
 }
 
+/*------------------------------------------------------------------*/
+/* verifyRegsAssigned - make sure an iTemp is properly initialized; */
+/* it should either have registers or have beed spilled. Otherwise, */
+/* there was an uninitialized variable, so just spill this to get   */
+/* the operand in a valid state.                                    */
+/*------------------------------------------------------------------*/
+static void
+verifyRegsAssigned (operand *op, iCode * ic)
+{
+  symbol * sym;
+
+  if (!op) return;
+  if (!IS_ITEMP (op)) return;
+
+  sym = OP_SYMBOL (op);
+  if (sym->isspilt) return;
+  if (!sym->nRegs) return;
+  if (sym->regs[0]) return;
+
+  werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
+            sym->prereqv ? sym->prereqv->name : sym->name);
+  spillThis (sym);
+}
+
+
 /*-----------------------------------------------------------------*/
 /* serialRegAssign - serially allocate registers to the variables  */
 /*-----------------------------------------------------------------*/
 static void
 serialRegAssign (eBBlock ** ebbs, int count)
 {
 /*-----------------------------------------------------------------*/
 /* serialRegAssign - serially allocate registers to the variables  */
 /*-----------------------------------------------------------------*/
 static void
 serialRegAssign (eBBlock ** ebbs, int count)
 {
-    int i;
-
-    /* for all blocks */
-    for (i = 0; i < count; i++) {
-
-       iCode *ic;
-
-       if (ebbs[i]->noPath &&
-           (ebbs[i]->entryLabel != entryLabel &&
-            ebbs[i]->entryLabel != returnLabel))
-           continue;
-
-       /* of all instructions do */
-       for (ic = ebbs[i]->sch; ic; ic = ic->next) {
-
-           /* if this is an ipop that means some live
-              range will have to be assigned again */
-           if (ic->op == IPOP)
-               reassignLR (IC_LEFT (ic));
-
-           /* if result is present && is a true symbol */
-           if (IC_RESULT (ic) && ic->op != IFX &&
-               IS_TRUE_SYMOP (IC_RESULT (ic)))
-               OP_SYMBOL (IC_RESULT (ic))->allocreq++;
-
-           /* take away registers from live
-              ranges that end at this instruction */
-           deassignLRs (ic, ebbs[i]);
-
-           /* some don't need registers */
-           if (SKIP_IC2 (ic) ||
-               ic->op == JUMPTABLE ||
-               ic->op == IFX ||
-               ic->op == IPUSH ||
-               ic->op == IPOP ||
-               (IC_RESULT (ic) && POINTER_SET (ic)))
-               continue;
-
-           /* now we need to allocate registers
-              only for the result */
-           if (IC_RESULT (ic)) {
-               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
-               bitVect *spillable;
-               int willCS;
-               int j;
-               int ptrRegSet = 0;
-
-               /* if it does not need or is spilt 
-                  or is already assigned to registers
-                  or will not live beyond this instructions */
-               if (!sym->nRegs ||
-                   sym->isspilt ||
-                   bitVectBitValue (_G.regAssigned, sym->key) ||
-                   sym->liveTo <= ic->seq)
-                   continue;
-
-               /* if some liverange has been spilt at the block level
-                  and this one live beyond this block then spil this
-                  to be safe */
-               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
-                   spillThis (sym);
-                   continue;
-               }
-               /* if trying to allocate this will cause
-                  a spill and there is nothing to spill 
-                  or this one is rematerializable then
-                  spill this one */
-               willCS = willCauseSpill (sym->nRegs, sym->regType);
-               spillable = computeSpillable (ic);
-               if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
-                   spillThis (sym);
-                   continue;                 
-               }
-
-               /* if it has a spillocation & is used less than
-                  all other live ranges then spill this */
-               if (willCS) {
-                   if (sym->usl.spillLoc) {
-                       symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
-                                                                        allLRs, ebbs[i], ic));
-                       if (leastUsed && leastUsed->used > sym->used) {
-                           spillThis (sym);
-                           continue;
-                       }
-                   } else {
-                       /* if none of the liveRanges have a spillLocation then better
-                          to spill this one than anything else already assigned to registers */
-                       if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
-                           /* if this is local to this block then we might find a block spil */
-                           if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
-                               spillThis (sym);
-                               continue;
-                           }
-                       }
-                   }
-               }
-               /* if we need ptr regs for the right side
-                  then mark it */
-               if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
-                   && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
-                   mcs51_ptrRegReq++;
-                   ptrRegSet = 1;
-               }
-               /* else we assign registers to it */
-               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
-               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
-
-               for (j = 0; j < sym->nRegs; j++) {
-                   if (sym->regType == REG_PTR)
-                       sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
-                   else
-                       sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
-
-                   /* if the allocation failed which means
-                      this was spilt then break */
-                   if (!sym->regs[j]) {
-                     break;
-                   }
-               }
-
-               /* if it shares registers with operands make sure
-                  that they are in the same position */
-               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
-                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
-                   positionRegs (OP_SYMBOL (IC_RESULT (ic)),
-                                 OP_SYMBOL (IC_LEFT (ic)));
-               }
-               /* do the same for the right operand */
-               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
-                   OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
-                   positionRegs (OP_SYMBOL (IC_RESULT (ic)),
-                                 OP_SYMBOL (IC_RIGHT (ic)));
-               }
-
-               if (ptrRegSet) {
-                   mcs51_ptrRegReq--;
-                   ptrRegSet = 0;
-               }
-
-           }
-       }
+  int i;
+
+  /* for all blocks */
+  for (i = 0; i < count; i++)
+    {
+      iCode *ic;
+
+      if (ebbs[i]->noPath &&
+          (ebbs[i]->entryLabel != entryLabel &&
+           ebbs[i]->entryLabel != returnLabel))
+        continue;
+
+      /* for all instructions do */
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+        {
+          updateRegUsage(ic);
+
+          /* if this is an ipop that means some live
+             range will have to be assigned again */
+          if (ic->op == IPOP)
+              reassignLR (IC_LEFT (ic));
+
+          /* if result is present && is a true symbol */
+          if (IC_RESULT (ic) && ic->op != IFX &&
+              IS_TRUE_SYMOP (IC_RESULT (ic)))
+            {
+              OP_SYMBOL (IC_RESULT (ic))->allocreq++;
+            }
+
+          /* take away registers from live
+             ranges that end at this instruction */
+          deassignLRs (ic, ebbs[i]);
+
+          /* some don't need registers */
+          if (SKIP_IC2 (ic) ||
+              ic->op == JUMPTABLE ||
+              ic->op == IFX ||
+              ic->op == IPUSH ||
+              ic->op == IPOP ||
+              (IC_RESULT (ic) && POINTER_SET (ic)))
+            {
+              continue;
+            }
+
+          /* now we need to allocate registers
+             only for the result */
+          if (IC_RESULT (ic))
+            {
+              symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+              bitVect *spillable;
+              int willCS;
+              int j;
+              int ptrRegSet = 0;
+
+              /* Make sure any spill location is definitely allocated */
+              if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+                  !sym->usl.spillLoc->allocreq)
+                {
+                  sym->usl.spillLoc->allocreq++;
+                }
+                  
+              /* if it does not need or is spilt
+                 or is already assigned to registers
+                 or will not live beyond this instructions */
+              if (!sym->nRegs ||
+                  sym->isspilt ||
+                  bitVectBitValue (_G.regAssigned, sym->key) ||
+                  sym->liveTo <= ic->seq)
+                {
+                  continue;
+                }
+
+              /* do not try to spil bit registers as it won't work */
+              if (sym->regType != REG_BIT)
+                {
+                  /* if some liverange has been spilt at the block level
+                     and this one live beyond this block then spil this
+                     to be safe */
+                  if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
+                    {
+                      spillThis (sym);
+                      continue;
+                    }
+
+                  willCS = willCauseSpill (sym->nRegs, sym->regType);
+                  /* if this is a bit variable then don't use precious registers
+                     along with expensive bit-to-char conversions but just spill
+                     it */
+                  if (willCS && SPEC_NOUN(sym->etype) == V_BIT)
+                    {
+                      spillThis (sym);
+                      continue;
+                    }
+
+                  /* if trying to allocate this will cause
+                     a spill and there is nothing to spill
+                     or this one is rematerializable then
+                     spill this one */
+                  spillable = computeSpillable (ic);
+                  if (sym->remat || (willCS && bitVectIsZero (spillable)))
+                    {
+                      spillThis (sym);
+                      continue;
+                    }
+
+                  /* If the live range preceeds the point of definition
+                     then ideally we must take into account registers that
+                     have been allocated after sym->liveFrom but freed
+                     before ic->seq. This is complicated, so spill this
+                     symbol instead and let fillGaps handle the allocation. */
+                  if (sym->liveFrom < ic->seq)
+                    {
+                      spillThis (sym);
+                      continue;
+                    }
+
+                  /* if it has a spillocation & is used less than
+                     all other live ranges then spill this */
+                  if (willCS)
+                    {
+                      if (sym->usl.spillLoc)
+                        {
+                          symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
+                                                                           allLRs, ebbs[i], ic));
+                          if (leastUsed && leastUsed->used > sym->used)
+                            {
+                              spillThis (sym);
+                              continue;
+                            }
+                        }
+                      else
+                        {
+                          /* if none of the liveRanges have a spillLocation then better
+                             to spill this one than anything else already assigned to registers */
+                          if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic))
+                            {
+                              /* if this is local to this block then we might find a block spil */
+                              if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq))
+                                {
+                                  spillThis (sym);
+                                  continue;
+                                }
+                            }
+                        }
+                    }
+                }
+              /* if we need ptr regs for the right side
+                 then mark it */
+              if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
+                  && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE)
+                {
+                  mcs51_ptrRegReq++;
+                  ptrRegSet = 1;
+                }
+              if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))
+                  && SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata)
+                {
+                  mcs51_ptrRegReq++;
+                  ptrRegSet = 1;
+                }
+              if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))
+                  && SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata)
+                {
+                  mcs51_ptrRegReq++;
+                  ptrRegSet = 1;
+                }
+
+              /* else we assign registers to it */
+              _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+              _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
+
+              for (j = 0; j < sym->nRegs; j++)
+                {
+                  sym->regs[j] = NULL;
+                  if (sym->regType == REG_PTR)
+                      sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
+                  else if (sym->regType == REG_BIT)
+                      sym->regs[j] = getRegBit (sym);
+                  else
+                    {
+                      if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic)))
+                        {
+                          symbol * right = OP_SYMBOL (IC_RIGHT (ic));
+
+                          if (right->regs[j] && (right->regType != REG_BIT))
+                              sym->regs[j] = allocThisReg (right->regs[j]);
+                        }
+                      if (!sym->regs[j])
+                          sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+                    }
+
+                  /* if the allocation failed which means
+                     this was spilt then break */
+                  if (!sym->regs[j])
+                    {
+                      int i;
+                      for (i=0; i < sym->nRegs ; i++ )
+                          sym->regs[i] = NULL;
+                      break;
+                    }
+                }
+
+              if (!POINTER_SET(ic) && !POINTER_GET(ic))
+                {
+                  /* if it shares registers with operands make sure
+                     that they are in the same position */
+                  if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+                      OP_SYMBOL (IC_LEFT (ic))->nRegs)
+                    {
+                      positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+                                    OP_SYMBOL (IC_LEFT (ic)));
+                    }
+                  /* do the same for the right operand */
+                  if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+                      OP_SYMBOL (IC_RIGHT (ic))->nRegs)
+                    {
+                      positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+                                    OP_SYMBOL (IC_RIGHT (ic)));
+                    }
+                }
+
+              if (ptrRegSet)
+                {
+                  mcs51_ptrRegReq--;
+                  ptrRegSet = 0;
+                }
+            }
+        }
+    }
+
+  /* Check for and fix any problems with uninitialized operands */
+  for (i = 0; i < count; i++)
+    {
+      iCode *ic;
+
+      if (ebbs[i]->noPath &&
+          (ebbs[i]->entryLabel != entryLabel &&
+           ebbs[i]->entryLabel != returnLabel))
+        {
+          continue;
+        }
+
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+        {
+          if (SKIP_IC2 (ic))
+            continue;
+
+          if (ic->op == IFX)
+            {
+              verifyRegsAssigned (IC_COND (ic), ic);
+              continue;
+            }
+
+          if (ic->op == JUMPTABLE)
+            {
+              verifyRegsAssigned (IC_JTCOND (ic), ic);
+              continue;
+            }
+
+          verifyRegsAssigned (IC_RESULT (ic), ic);
+          verifyRegsAssigned (IC_LEFT (ic), ic);
+          verifyRegsAssigned (IC_RIGHT (ic), ic);
+        }
     }
 }
 
     }
 }
 
@@ -1243,109 +1509,228 @@ serialRegAssign (eBBlock ** ebbs, int count)
 /*-----------------------------------------------------------------*/
 static void fillGaps()
 {
 /*-----------------------------------------------------------------*/
 static void fillGaps()
 {
-    symbol *sym =NULL;
-    int key =0;    
-    
-    if (getenv("DISABLE_FILL_GAPS")) return;
-    
-    /* look for livernages that was spilt by the allocator */
-    for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
-        sym = hTabNextItem(liveRanges,&key)) {
-
-       int i;
-       int pdone = 0;
-
-       if (!sym->spillA || !sym->clashes || sym->remat) continue ;
-
-       /* find the liveRanges this one clashes with, that are
-          still assigned to registers & mark the registers as used*/
-       for ( i = 0 ; i < sym->clashes->size ; i ++) {
-           int k;
-           symbol *clr;
-
-           if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
-               bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
-               continue ;
-
-               clr = hTabItemWithKey(liveRanges,i);
-           assert(clr);
-        
-           /* mark these registers as used */
-           for (k = 0 ; k < clr->nRegs ; k++ ) 
-               useReg(clr->regs[k]);
-       }
-
-       if (willCauseSpill(sym->nRegs,sym->regType)) {
-           /* NOPE :( clear all registers & and continue */
-           freeAllRegs();
-           continue ;
-       }
-
-       /* THERE IS HOPE !!!! */
-       for (i=0; i < sym->nRegs ; i++ ) {
-           if (sym->regType == REG_PTR)
-               sym->regs[i] = getRegPtrNoSpil ();
-           else
-               sym->regs[i] = getRegGprNoSpil ();                
-       }
-
-       /* for all its definitions check if the registers
-          allocated needs positioning NOTE: we can position
-          only ONCE if more than One positioning required 
-          then give up */
-       sym->isspilt = 0;
-       for (i = 0 ; i < sym->defs->size ; i++ ) {
-           if (bitVectBitValue(sym->defs,i)) {
-               iCode *ic;
-               if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
-               if (SKIP_IC(ic)) continue;
-               assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
-               /* if left is assigned to registers */
-               if (IS_SYMOP(IC_LEFT(ic)) && 
-                   bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
-                   pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
-               }
-               if (IS_SYMOP(IC_RIGHT(ic)) && 
-                   bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
-                   pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
-               }
-               if (pdone > 1) break;
-           }
-       }
-       for (i = 0 ; i < sym->uses->size ; i++ ) {
-           if (bitVectBitValue(sym->uses,i)) {
-               iCode *ic;
-               if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
-               if (SKIP_IC(ic)) continue;
-               if (!IS_ASSIGN_ICODE(ic)) continue ;
-
-               /* if result is assigned to registers */
-               if (IS_SYMOP(IC_RESULT(ic)) && 
-                   bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
-                   pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
-               }
-               if (pdone > 1) break;
-           }
-       }
-       /* had to position more than once GIVE UP */
-       if (pdone > 1) {
-           /* UNDO all the changes we made to try this */
-           sym->isspilt = 1;
-           for (i=0; i < sym->nRegs ; i++ ) {
-                   sym->regs[i] = NULL;
-           }
-           freeAllRegs();
-           D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
-           continue ;      
-       }
-       D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
-       _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
-       sym->isspilt = sym->spillA = 0 ;
-       sym->usl.spillLoc->allocreq--;
-       freeAllRegs();
+  symbol *sym =NULL;
+  int key =0;
+  int pass;
+  iCode *ic = NULL;
+
+  if (getenv("DISABLE_FILL_GAPS"))
+    return;
+
+  /* look for liveranges that were spilt by the allocator */
+  for (sym = hTabFirstItem(liveRanges, &key) ; sym ;
+       sym = hTabNextItem(liveRanges, &key))
+    {
+      int i;
+      int pdone = 0;
+
+      if (!sym->spillA || !sym->clashes || sym->remat)
+        continue;
+
+      /* if spilt in direct space the original rname is lost */
+      if (sym->usl.spillLoc && (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
+        continue;
+
+      /* find the liveRanges this one clashes with, that are
+         still assigned to registers & mark the registers as used*/
+      for ( i = 0 ; i < sym->clashes->size ; i ++)
+        {
+          int k;
+          symbol *clr;
+
+          if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
+              bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
+            continue ;
+
+          clr = hTabItemWithKey(liveRanges, i);
+          assert(clr);
+
+          /* mark these registers as used */
+          for (k = 0 ; k < clr->nRegs ; k++ )
+            useReg(clr->regs[k]);
+        }
+
+      if (willCauseSpill(sym->nRegs, sym->regType))
+        {
+          /* NOPE :( clear all registers & and continue */
+          freeAllRegs();
+          continue ;
+        }
+
+      ic = NULL;
+      for (i = 0 ; i < sym->defs->size ; i++ )
+        {
+          if (bitVectBitValue(sym->defs, i))
+            {
+              if (!(ic = hTabItemWithKey(iCodehTab, i)))
+                continue;
+              if (ic->op == CAST)
+                break;
+            }
+        }
+
+      D(printf("Attempting fillGaps on %s: [", sym->name));
+      /* THERE IS HOPE !!!! */
+      for (i=0; i < sym->nRegs ; i++ )
+        {
+          if (sym->regType == REG_PTR)
+            sym->regs[i] = getRegPtrNoSpil ();
+          else if (sym->regType == REG_BIT)
+            sym->regs[i] = getRegBitNoSpil ();
+          else
+            {
+              sym->regs[i] = NULL;
+              if (ic && ic->op == CAST && IS_SYMOP (IC_RIGHT (ic)))
+                {
+                  symbol * right = OP_SYMBOL (IC_RIGHT (ic));
+
+                  if (right->regs[i])
+                    sym->regs[i] = allocThisReg (right->regs[i]);
+                }
+              if (!sym->regs[i])
+                sym->regs[i] = getRegGprNoSpil ();
+            }
+          D(printf("%s ", sym->regs[i]->name));
+        }
+      D(printf("]\n"));
+
+      /* For all its definitions check if the registers
+         allocated needs positioning NOTE: we can position
+         only ONCE if more than One positioning required
+         then give up.
+         We may need to perform the checks twice; once to
+         position the registers as needed, the second to
+         verify any register repositioning is still
+         compatible.
+        */
+      sym->isspilt = 0;
+      for (pass=0; pass<2; pass++)
+        {
+          D(printf(" checking definitions\n"));
+          for (i = 0 ; i < sym->defs->size ; i++ )
+            {
+              if (bitVectBitValue(sym->defs,i))
+                {
+                  if (!(ic = hTabItemWithKey(iCodehTab,i))) 
+                    continue;
+                  D(printf("  ic->seq = %d\n", ic->seq));
+                  if (SKIP_IC(ic))
+                    continue;
+                  assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+                  /* if left is assigned to registers */
+                  if (IS_SYMOP(IC_LEFT(ic)))
+                    {
+                      D(printf("   left = "));
+                      D(printOperand(IC_LEFT(ic),NULL));
+                    }
+                  if (IS_SYMOP(IC_LEFT(ic)) &&
+                      bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key))
+                    {
+                      pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
+                    }
+                  if (IS_SYMOP(IC_RIGHT(ic)))
+                    {
+                      D(printf("   right = "));
+                      D(printOperand(IC_RIGHT(ic),NULL));
+                    }
+                  if (IS_SYMOP(IC_RIGHT(ic)) &&
+                      bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key))
+                    {
+                      pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+                    }
+                  D(printf("   pdone = %d\n", pdone));
+                  if (pdone > 1) 
+                    break;
+                }
+            }
+          D(printf(" checking uses\n"));
+          for (i = 0 ; i < sym->uses->size ; i++ )
+            {
+              if (bitVectBitValue(sym->uses,i))
+                {
+                  iCode *ic;
+                  if (!(ic = hTabItemWithKey(iCodehTab, i)))
+                    continue;
+                  D(printf("  ic->seq = %d\n", ic->seq));
+                  if (SKIP_IC(ic)) 
+                    continue;
+                  if (POINTER_SET(ic) || POINTER_GET(ic))
+                    continue;
+
+                  /* if result is assigned to registers */
+                  if (IS_SYMOP (IC_RESULT (ic)))
+                    {
+                      D(printf("   result = "));
+                      D(printOperand(IC_RESULT (ic), NULL));
+                    }
+                  if (IS_SYMOP (IC_RESULT (ic)) &&
+                      bitVectBitValue(_G.totRegAssigned, OP_SYMBOL (IC_RESULT (ic))->key))
+                    {
+                      pdone += (positionRegs(sym, OP_SYMBOL (IC_RESULT (ic)))>0);
+                    }
+                  D(printf("   pdone = %d\n", pdone));
+                  if (pdone > 1) 
+                    break;
+                }
+            }
+          if (pdone == 0)
+            break; /* second pass only if regs repositioned */
+          if (pdone > 1) 
+            break;
+        }
+      D(printf(" sym->regs = ["));
+      for (i=0; i < sym->nRegs ; i++ )
+        D(printf("%s ", sym->regs[i]->name));
+      D(printf("]\n"));
+      /* had to position more than once GIVE UP */
+      if (pdone > 1)
+        {
+          /* UNDO all the changes we made to try this */
+          sym->isspilt = 1;
+          for (i=0; i < sym->nRegs ; i++ )
+            {
+              sym->regs[i] = NULL;
+            }
+          freeAllRegs();
+          D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
+          continue ;
+        }
+      D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
+
+      _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
+      sym->isspilt = sym->spillA = 0 ;
+      sym->usl.spillLoc->allocreq--;
+      freeAllRegs();
     }
 }
 
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* findAllBitregs :- returns bit vector of all bit registers       */
+/*-----------------------------------------------------------------*/
+static bitVect *
+findAllBitregs (void)
+{
+  bitVect *rmask = newBitVect (mcs51_nRegs);
+  int j;
+
+  for (j = 0; j < mcs51_nRegs; j++)
+    {
+      if (regs8051[j].type == REG_BIT)
+        rmask = bitVectSetBit (rmask, regs8051[j].rIdx);
+    }
+
+  return rmask;
+}
+
+/*-----------------------------------------------------------------*/
+/* mcs51_allBitregs :- returns bit vector of all bit registers     */
+/*-----------------------------------------------------------------*/
+bitVect *
+mcs51_allBitregs (void)
+{
+  return _G.allBitregs;
+}
+
 /*-----------------------------------------------------------------*/
 /* rUmaskForOp :- returns register mask for an operand             */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* rUmaskForOp :- returns register mask for an operand             */
 /*-----------------------------------------------------------------*/
@@ -1371,8 +1756,8 @@ mcs51_rUmaskForOp (operand * op)
 
   for (j = 0; j < sym->nRegs; j++)
     {
 
   for (j = 0; j < sym->nRegs; j++)
     {
-      rumask = bitVectSetBit (rumask,
-                             sym->regs[j]->rIdx);
+      if (sym->regs[j]) /* EEP - debug */
+        rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx);
     }
 
   return rumask;
     }
 
   return rumask;
@@ -1389,33 +1774,26 @@ regsUsedIniCode (iCode * ic)
   /* do the special cases first */
   if (ic->op == IFX)
     {
   /* do the special cases first */
   if (ic->op == IFX)
     {
-      rmask = bitVectUnion (rmask,
-                           mcs51_rUmaskForOp (IC_COND (ic)));
+      rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_COND (ic)));
       goto ret;
     }
 
   /* for the jumptable */
   if (ic->op == JUMPTABLE)
     {
       goto ret;
     }
 
   /* for the jumptable */
   if (ic->op == JUMPTABLE)
     {
-      rmask = bitVectUnion (rmask,
-                           mcs51_rUmaskForOp (IC_JTCOND (ic)));
-
+      rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_JTCOND (ic)));
       goto ret;
     }
 
   /* of all other cases */
   if (IC_LEFT (ic))
       goto ret;
     }
 
   /* of all other cases */
   if (IC_LEFT (ic))
-    rmask = bitVectUnion (rmask,
-                         mcs51_rUmaskForOp (IC_LEFT (ic)));
-
+    rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_LEFT (ic)));
 
   if (IC_RIGHT (ic))
 
   if (IC_RIGHT (ic))
-    rmask = bitVectUnion (rmask,
-                         mcs51_rUmaskForOp (IC_RIGHT (ic)));
+    rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_RIGHT (ic)));
 
   if (IC_RESULT (ic))
 
   if (IC_RESULT (ic))
-    rmask = bitVectUnion (rmask,
-                         mcs51_rUmaskForOp (IC_RESULT (ic)));
+    rmask = bitVectUnion (rmask, mcs51_rUmaskForOp (IC_RESULT (ic)));
 
 ret:
   return rmask;
 
 ret:
   return rmask;
@@ -1435,59 +1813,57 @@ createRegMask (eBBlock ** ebbs, int count)
       iCode *ic;
 
       if (ebbs[i]->noPath &&
       iCode *ic;
 
       if (ebbs[i]->noPath &&
-         (ebbs[i]->entryLabel != entryLabel &&
-          ebbs[i]->entryLabel != returnLabel))
-       continue;
+          (ebbs[i]->entryLabel != entryLabel &&
+           ebbs[i]->entryLabel != returnLabel))
+        continue;
 
       /* for all instructions */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
 
       /* for all instructions */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       {
-
-         int j;
-
-         if (SKIP_IC2 (ic) || !ic->rlive)
-           continue;
-
-         /* first mark the registers used in this
-            instruction */
-         ic->rUsed = regsUsedIniCode (ic);
-         _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
-
-         /* now create the register mask for those 
-            registers that are in use : this is a
-            super set of ic->rUsed */
-         ic->rMask = newBitVect (mcs51_nRegs + 1);
-
-         /* for all live Ranges alive at this point */
-         for (j = 1; j < ic->rlive->size; j++)
-           {
-             symbol *sym;
-             int k;
-
-             /* if not alive then continue */
-             if (!bitVectBitValue (ic->rlive, j))
-               continue;
-
-             /* find the live range we are interested in */
-             if (!(sym = hTabItemWithKey (liveRanges, j)))
-               {
-                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-                         "createRegMask cannot find live range");
-                 fprintf(stderr, "\tmissing live range: key=%d\n", j);
-                 exit (0);
-               }
-
-             /* if no register assigned to it */
-             if (!sym->nRegs || sym->isspilt)
-               continue;
-
-             /* for all the registers allocated to it */
-             for (k = 0; k < sym->nRegs; k++)
-               if (sym->regs[k])
-                 ic->rMask =
-                   bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
-           }
-       }
+        {
+          int j;
+
+          if (SKIP_IC2 (ic) || !ic->rlive)
+            continue;
+
+          /* first mark the registers used in this
+             instruction */
+          ic->rUsed = regsUsedIniCode (ic);
+          _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
+
+          /* now create the register mask for those
+             registers that are in use : this is a
+             super set of ic->rUsed */
+          ic->rMask = newBitVect (mcs51_nRegs + 1);
+
+          /* for all live Ranges alive at this point */
+          for (j = 1; j < ic->rlive->size; j++)
+            {
+              symbol *sym;
+              int k;
+
+              /* if not alive then continue */
+              if (!bitVectBitValue (ic->rlive, j))
+                continue;
+
+              /* find the live range we are interested in */
+              if (!(sym = hTabItemWithKey (liveRanges, j)))
+                {
+                  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                          "createRegMask cannot find live range");
+                  fprintf(stderr, "\tmissing live range: key=%d\n", j);
+                  exit (0);
+                }
+
+              /* if no register assigned to it */
+              if (!sym->nRegs || sym->isspilt)
+                continue;
+
+              /* for all the registers allocated to it */
+              for (k = 0; k < sym->nRegs; k++)
+                if (sym->regs[k])
+                  ic->rMask = bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
+            }
+        }
     }
 }
 
     }
 }
 
@@ -1497,32 +1873,49 @@ createRegMask (eBBlock ** ebbs, int count)
 static char *
 rematStr (symbol * sym)
 {
 static char *
 rematStr (symbol * sym)
 {
-  char *s = buffer;
   iCode *ic = sym->rematiCode;
   iCode *ic = sym->rematiCode;
+  int offset = 0;
 
   while (1)
     {
 
   while (1)
     {
-
-      /* if plus or minus print the right hand side */
-      if (ic->op == '+' || ic->op == '-')
-       {
-         sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
-                  ic->op);
-         s += strlen (s);
-         ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
-         continue;
-       }
+      /* if plus adjust offset to right hand side */
+      if (ic->op == '+')
+        {
+          offset += (int) operandLitValue (IC_RIGHT (ic));
+          ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+          continue;
+        }
+
+      /* if minus adjust offset to right hand side */
+      if (ic->op == '-')
+        {
+          offset -= (int) operandLitValue (IC_RIGHT (ic));
+          ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+          continue;
+        }
 
       /* cast then continue */
 
       /* cast then continue */
-      if (IS_CAST_ICODE(ic)) {
-         ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
-         continue;
-      }
+      if (IS_CAST_ICODE(ic))
+        {
+          ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+          continue;
+        }
       /* we reached the end */
       /* we reached the end */
-      sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
       break;
     }
 
       break;
     }
 
+  if (offset)
+    {
+      SNPRINTF (buffer, sizeof(buffer),
+                "(%s %c 0x%04x)",
+                OP_SYMBOL (IC_LEFT (ic))->rname,
+                offset >= 0 ? '+' : '-',
+                abs (offset) & 0xffff);
+    }
+  else
+    {
+      strncpyz (buffer, OP_SYMBOL (IC_LEFT (ic))->rname, sizeof(buffer));
+    }
   return buffer;
 }
 
   return buffer;
 }
 
@@ -1540,98 +1933,72 @@ regTypeNum (eBBlock *ebbs)
   for (sym = hTabFirstItem (liveRanges, &k); sym;
        sym = hTabNextItem (liveRanges, &k))
     {
   for (sym = hTabFirstItem (liveRanges, &k); sym;
        sym = hTabNextItem (liveRanges, &k))
     {
-
       /* if used zero times then no registers needed */
       if ((sym->liveTo - sym->liveFrom) == 0)
       /* if used zero times then no registers needed */
       if ((sym->liveTo - sym->liveFrom) == 0)
-       continue;
-
+        continue;
 
       /* if the live range is a temporary */
       if (sym->isitmp)
 
       /* if the live range is a temporary */
       if (sym->isitmp)
-       {
-
-         /* if the type is marked as a conditional */
-         if (sym->regType == REG_CND)
-           continue;
-
-         /* if used in return only then we don't 
-            need registers */
-         if (sym->ruonly || sym->accuse)
-           {
-             if (IS_AGGREGATE (sym->type) || sym->isptr)
-               sym->type = aggrToPtr (sym->type, FALSE);
-             continue;
-           }
-
-         /* if the symbol has only one definition &
-            that definition is a get_pointer */
-         if (bitVectnBitsOn (sym->defs) == 1 &&
-             (ic = hTabItemWithKey (iCodehTab,
-                                    bitVectFirstBit (sym->defs))) &&
-             POINTER_GET (ic) &&
-             !sym->noSpilLoc &&
-             !IS_BITVAR (sym->etype))
-           {
-
-
-             /* and that pointer is remat in data space */
-             if (OP_SYMBOL (IC_LEFT (ic))->remat &&
-                 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
-                 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
-               {
-                 /* create a psuedo symbol & force a spil */
-                 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
-                 psym->type = sym->type;
-                 psym->etype = sym->etype;
-                 strcpy (psym->rname, psym->name);
-                 sym->isspilt = 1;
-                 sym->usl.spillLoc = psym;
-#if 0 // an alternative fix for bug #480076
-                 /* now this is a useless assignment to itself */
-                 remiCodeFromeBBlock (ebbs, ic);
-#else
-                 /* now this really is an assignment to itself, make it so;
-                    it will be optimized out later */
-                 ic->op='=';
-                 IC_RIGHT(ic)=IC_RESULT(ic);
-                 IC_LEFT(ic)=NULL;
-#endif
-                 continue;
-               }
-
-             /* if in data space or idata space then try to
-                allocate pointer register */
-
-           }
-
-         /* if not then we require registers */
-         sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
-                       getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
-                       getSize (sym->type));
-
-         if (sym->nRegs > 4)
-           {
-             fprintf (stderr, "allocated more than 4 or 0 registers for type ");
-             printTypeChain (sym->type, stderr);
-             fprintf (stderr, "\n");
-           }
-
-         /* determine the type of register required */
-         if (sym->nRegs == 1 &&
-             IS_PTR (sym->type) &&
-             sym->uptr)
-           sym->regType = REG_PTR;
-         else
-           sym->regType = REG_GPR;
-
-       }
+        {
+          /* if the type is marked as a conditional */
+          if (sym->regType == REG_CND)
+            continue;
+
+          /* if used in return only then we don't
+             need registers */
+          if (sym->ruonly || sym->accuse)
+            {
+              if (IS_AGGREGATE (sym->type) || sym->isptr)
+                sym->type = aggrToPtr (sym->type, FALSE);
+              else if (IS_BIT(sym->type))
+                sym->regType = REG_CND;
+              continue;
+            }
+
+          /* if the symbol has only one definition &
+             that definition is a get_pointer */
+          if (bitVectnBitsOn (sym->defs) == 1 &&
+              (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs))) &&
+              POINTER_GET (ic) &&
+              !IS_BITVAR (sym->etype) &&
+              (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
+            {
+              if (ptrPseudoSymSafe (sym, ic))
+                {
+                  ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
+                  continue;
+                }
+
+              /* if in data space or idata space then try to
+                 allocate pointer register */
+            }
+
+          /* if not then we require registers */
+          sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
+                        getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
+                        getSize (sym->type));
+
+          if (sym->nRegs > 4)
+            {
+              fprintf (stderr, "allocated more than 4 or 0 registers for type ");
+              printTypeChain (sym->type, stderr);
+              fprintf (stderr, "\n");
+            }
+
+          /* determine the type of register required */
+          if (sym->nRegs == 1 && IS_PTR (sym->type) && sym->uptr)
+            sym->regType = REG_PTR;
+          else if (IS_BIT(sym->type))
+            sym->regType = REG_BIT;
+          else
+            sym->regType = REG_GPR;
+        }
       else
       else
-       /* for the first run we don't provide */
-       /* registers for true symbols we will */
-       /* see how things go                  */
-       sym->nRegs = 0;
+        /* for the first run we don't provide */
+        /* registers for true symbols we will */
+        /* see how things go                  */
+        sym->nRegs = 0;
     }
     }
-
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1672,53 +2039,70 @@ farSpacePackable (iCode * ic)
     {
       /* if the definition is a call then no */
       if ((dic->op == CALL || dic->op == PCALL) &&
     {
       /* if the definition is a call then no */
       if ((dic->op == CALL || dic->op == PCALL) &&
-         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
-       {
-         return NULL;
-       }
+          IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+        {
+          return NULL;
+        }
 
       /* if shift by unknown amount then not */
       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
 
       /* if shift by unknown amount then not */
       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
-         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
-       return NULL;
+          IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+        return NULL;
 
       /* if pointer get and size > 1 */
       if (POINTER_GET (dic) &&
 
       /* if pointer get and size > 1 */
       if (POINTER_GET (dic) &&
-         getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
-       return NULL;
+          getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
+        return NULL;
 
       if (POINTER_SET (dic) &&
 
       if (POINTER_SET (dic) &&
-         getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
-       return NULL;
-
-      /* if any three is a true symbol in far space */
-      if (IC_RESULT (dic) &&
-         IS_TRUE_SYMOP (IC_RESULT (dic)) &&
-         isOperandInFarSpace (IC_RESULT (dic)))
-       return NULL;
-
-      if (IC_RIGHT (dic) &&
-         IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
-         isOperandInFarSpace (IC_RIGHT (dic)) &&
-         !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
-       return NULL;
-
-      if (IC_LEFT (dic) &&
-         IS_TRUE_SYMOP (IC_LEFT (dic)) &&
-         isOperandInFarSpace (IC_LEFT (dic)) &&
-         !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
-       return NULL;
+          getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
+        return NULL;
+
+      if (dic->op == IFX)
+        {
+          if (IC_COND (dic) &&
+              IS_TRUE_SYMOP (IC_COND (dic)) &&
+              isOperandInFarSpace (IC_COND (dic)))
+            return NULL;
+        }
+      else if (dic->op == JUMPTABLE)
+        {
+          if (IC_JTCOND (dic) &&
+              IS_TRUE_SYMOP (IC_JTCOND (dic)) &&
+              isOperandInFarSpace (IC_JTCOND (dic)))
+            return NULL;
+        }
+      else
+        {
+          /* if any tree is a true symbol in far space */
+          if (IC_RESULT (dic) &&
+              IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+              isOperandInFarSpace (IC_RESULT (dic)))
+            return NULL;
+
+          if (IC_RIGHT (dic) &&
+              IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+              isOperandInFarSpace (IC_RIGHT (dic)) &&
+              !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+            return NULL;
+
+          if (IC_LEFT (dic) &&
+              IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+              isOperandInFarSpace (IC_LEFT (dic)) &&
+              !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+            return NULL;
+        }
 
       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
 
       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
-       {
-         if ((dic->op == LEFT_OP ||
-              dic->op == RIGHT_OP ||
-              dic->op == '-') &&
-             IS_OP_LITERAL (IC_RIGHT (dic)))
-           return NULL;
-         else
-           return dic;
-       }
+        {
+          if ((dic->op == LEFT_OP ||
+               dic->op == RIGHT_OP ||
+               dic->op == '-') &&
+              IS_OP_LITERAL (IC_RIGHT (dic)))
+            return NULL;
+          else
+            return dic;
+        }
     }
 
   return NULL;
     }
 
   return NULL;
@@ -1731,132 +2115,172 @@ static int
 packRegsForAssign (iCode * ic, eBBlock * ebp)
 {
   iCode *dic, *sic;
 packRegsForAssign (iCode * ic, eBBlock * ebp)
 {
   iCode *dic, *sic;
-  //sym_link *etype = operandType (IC_RIGHT (ic));
 
   if (!IS_ITEMP (IC_RIGHT (ic)) ||
       OP_SYMBOL (IC_RIGHT (ic))->isind ||
 
   if (!IS_ITEMP (IC_RIGHT (ic)) ||
       OP_SYMBOL (IC_RIGHT (ic))->isind ||
-      OP_LIVETO (IC_RIGHT (ic)) > ic->seq
-      /* why? || IS_BITFIELD (etype) */ )
+      OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
     {
       return 0;
     }
 
   /* if the true symbol is defined in far space or on stack
      then we should not since this will increase register pressure */
     {
       return 0;
     }
 
   /* if the true symbol is defined in far space or on stack
      then we should not since this will increase register pressure */
-  if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
-    return 0;
-  }
+  if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic))
+    {
+      return 0;
+    }
 
 
-  /* find the definition of iTempNN scanning backwards if we find a 
-     a use of the true symbol in before we find the definition then 
+  /* find the definition of iTempNN scanning backwards if we find a
+     a use of the true symbol in before we find the definition then
      we cannot */
   for (dic = ic->prev; dic; dic = dic->prev)
     {
      we cannot */
   for (dic = ic->prev; dic; dic = dic->prev)
     {
-      /* if there is a function call then don't pack it */
+      int crossedCall = 0;
+
+      /* We can pack across a function call only if it's a local */
+      /* variable or our parameter. Never pack global variables */
+      /* or parameters to a function we call. */
       if ((dic->op == CALL || dic->op == PCALL))
       if ((dic->op == CALL || dic->op == PCALL))
-       {
-         dic = NULL;
-         break;
-       }
+        {
+          if (!OP_SYMBOL (IC_RESULT (ic))->ismyparm
+              && !OP_SYMBOL (IC_RESULT (ic))->islocal)
+            {
+              crossedCall = 1;
+            }
+        }
+
+      /* Don't move an assignment out of a critical block */
+      if (dic->op == CRITICAL)
+        {
+          dic = NULL;
+          break;
+        }
 
       if (SKIP_IC2 (dic))
 
       if (SKIP_IC2 (dic))
-       continue;
-
-      if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
-         IS_OP_VOLATILE (IC_RESULT (dic)))
-       {
-         dic = NULL;
-         break;
-       }
-
-      if (IS_SYMOP (IC_RESULT (dic)) &&
-         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
-       {
-         if (POINTER_SET (dic))
-           dic = NULL;
-
-         break;
-       }
-
-      if (IS_SYMOP (IC_RIGHT (dic)) &&
-         (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
-          IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
-       {
-         dic = NULL;
-         break;
-       }
-
-      if (IS_SYMOP (IC_LEFT (dic)) &&
-         (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
-          IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
-       {
-         dic = NULL;
-         break;
-       }
-
-      if (POINTER_SET (dic) &&
-         IC_RESULT (dic)->key == IC_RESULT (ic)->key)
-       {
-         dic = NULL;
-         break;
-       }
+        continue;
+
+      if (dic->op == IFX)
+        {
+          if (IS_SYMOP (IC_COND (dic)) &&
+              (IC_COND (dic)->key == IC_RESULT (ic)->key ||
+               IC_COND (dic)->key == IC_RIGHT (ic)->key))
+            {
+              dic = NULL;
+              break;
+            }
+        }
+      else
+        {
+          if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+              IS_OP_VOLATILE (IC_RESULT (dic)))
+            {
+              dic = NULL;
+              break;
+            }
+
+          if (IS_SYMOP (IC_RESULT (dic)) &&
+              IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+            {
+              if (POINTER_SET (dic))
+                dic = NULL;
+
+              break;
+            }
+
+          if (IS_SYMOP (IC_RIGHT (dic)) &&
+              (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+               IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+            {
+              dic = NULL;
+              break;
+            }
+
+          if (IS_SYMOP (IC_LEFT (dic)) &&
+              (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+               IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+            {
+              dic = NULL;
+              break;
+            }
+
+          if (IS_SYMOP (IC_RESULT (dic)) &&
+              IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+            {
+              dic = NULL;
+              break;
+            }
+
+          if (crossedCall)
+            {
+              dic = NULL;
+              break;
+            }
+        }
     }
 
   if (!dic)
     }
 
   if (!dic)
-    return 0;                  /* did not find */
+    return 0;                   /* did not find */
 
   /* if assignment then check that right is not a bit */
 
   /* if assignment then check that right is not a bit */
-  if (ASSIGNMENT (dic) && !POINTER_SET (dic))
+  if (ASSIGNMENT (ic) && !POINTER_SET (ic))
     {
     {
-      sym_link *etype = operandType (IC_RIGHT (dic));
+      sym_link *etype = operandType (IC_RESULT (dic));
       if (IS_BITFIELD (etype))
       if (IS_BITFIELD (etype))
-       return 0;
+        {
+          /* if result is a bit too then it's ok */
+          etype = operandType (IC_RESULT (ic));
+          if (!IS_BITFIELD (etype))
+            {
+              return 0;
+            }
+        }
     }
     }
+
   /* if the result is on stack or iaccess then it must be
      the same atleast one of the operands */
   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
       OP_SYMBOL (IC_RESULT (ic))->iaccess)
     {
   /* if the result is on stack or iaccess then it must be
      the same atleast one of the operands */
   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
       OP_SYMBOL (IC_RESULT (ic))->iaccess)
     {
-
       /* the operation has only one symbol
          operator then we can pack */
       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
       /* the operation has only one symbol
          operator then we can pack */
       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
-         (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
-       goto pack;
+          (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
+        goto pack;
 
       if (!((IC_LEFT (dic) &&
 
       if (!((IC_LEFT (dic) &&
-            IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
-           (IC_RIGHT (dic) &&
-            IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
-       return 0;
+             IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
+            (IC_RIGHT (dic) &&
+             IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
+        return 0;
     }
 pack:
   /* found the definition */
   /* replace the result with the result of */
   /* this assignment and remove this assignment */
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
     }
 pack:
   /* found the definition */
   /* replace the result with the result of */
   /* this assignment and remove this assignment */
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
-  IC_RESULT (dic) = IC_RESULT (ic);
+  ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
 
   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
     {
       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
     }
 
   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
     {
       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
     }
-  /* delete from liverange table also 
+  // TODO: and the otherway around?
+
+  /* delete from liverange table also
      delete from all the points inbetween and the new
      one */
   for (sic = dic; sic != ic; sic = sic->next)
     {
       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
       if (IS_ITEMP (IC_RESULT (dic)))
      delete from all the points inbetween and the new
      one */
   for (sic = dic; sic != ic; sic = sic->next)
     {
       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
       if (IS_ITEMP (IC_RESULT (dic)))
-       bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
+        bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
     }
 
   remiCodeFromeBBlock (ebp, ic);
     }
 
   remiCodeFromeBBlock (ebp, ic);
-  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+  bitVectUnSetBit(OP_DEFS (IC_RESULT (ic)), ic->key);
   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-  OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+  OP_DEFS(IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
   return 1;
   return 1;
-
 }
 
 /*------------------------------------------------------------------*/
 }
 
 /*------------------------------------------------------------------*/
@@ -1875,28 +2299,40 @@ findAssignToSym (operand * op, iCode * ic)
      and eliminate the use of iTempAA, freeing up its register for
      other uses.
   */
      and eliminate the use of iTempAA, freeing up its register for
      other uses.
   */
-     
 
   for (dic = ic->prev; dic; dic = dic->prev)
     {
 
   for (dic = ic->prev; dic; dic = dic->prev)
     {
-
       /* if definition by assignment */
       if (dic->op == '=' &&
       /* if definition by assignment */
       if (dic->op == '=' &&
-         !POINTER_SET (dic) &&
-         IC_RESULT (dic)->key == op->key
+          !POINTER_SET (dic) &&
+          IC_RESULT (dic)->key == op->key
 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
-       )
-       break;  /* found where this temp was defined */
+        )
+        break;  /* found where this temp was defined */
 
       /* if we find an usage then we cannot delete it */
 
       /* if we find an usage then we cannot delete it */
-      if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
-       return NULL;
 
 
-      if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
-       return NULL;
+      if (dic->op == IFX)
+        {
+          if (IC_COND (dic) && IC_COND (dic)->key == op->key)
+            return NULL;
+        }
+      else if (dic->op == JUMPTABLE)
+        {
+          if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
+            return NULL;
+        }
+      else
+        {
+          if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
+            return NULL;
+
+          if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
+            return NULL;
 
 
-      if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
-       return NULL;
+          if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
+            return NULL;
+        }
     }
 
   if (!dic)
     }
 
   if (!dic)
@@ -1904,11 +2340,11 @@ findAssignToSym (operand * op, iCode * ic)
 
   /* we are interested only if defined in far space */
   /* or in stack space in case of + & - */
 
   /* we are interested only if defined in far space */
   /* or in stack space in case of + & - */
-  
+
   /* if assigned to a non-symbol then don't repack regs */
   if (!IS_SYMOP (IC_RIGHT (dic)))
     return NULL;
   /* if assigned to a non-symbol then don't repack regs */
   if (!IS_SYMOP (IC_RIGHT (dic)))
     return NULL;
-  
+
   /* if the symbol is volatile then we should not */
   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
     return NULL;
   /* if the symbol is volatile then we should not */
   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
     return NULL;
@@ -1919,20 +2355,19 @@ findAssignToSym (operand * op, iCode * ic)
   /* if the symbol is in far space then we should not */
   if (isOperandInFarSpace (IC_RIGHT (dic)))
     return NULL;
   /* if the symbol is in far space then we should not */
   if (isOperandInFarSpace (IC_RIGHT (dic)))
     return NULL;
-  
+
   /* for + & - operations make sure that
      if it is on the stack it is the same
      as one of the three operands */
   if ((ic->op == '+' || ic->op == '-') &&
       OP_SYMBOL (IC_RIGHT (dic))->onStack)
     {
   /* for + & - operations make sure that
      if it is on the stack it is the same
      as one of the three operands */
   if ((ic->op == '+' || ic->op == '-') &&
       OP_SYMBOL (IC_RIGHT (dic))->onStack)
     {
-      
       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
-         IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
-         IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
-       return NULL;
+          IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
+          IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
+        return NULL;
     }
     }
-  
+
   /* now make sure that the right side of dic
      is not defined between ic & dic */
   if (dic)
   /* now make sure that the right side of dic
      is not defined between ic & dic */
   if (dic)
@@ -1940,9 +2375,9 @@ findAssignToSym (operand * op, iCode * ic)
       iCode *sic = dic->next;
 
       for (; sic != ic; sic = sic->next)
       iCode *sic = dic->next;
 
       for (; sic != ic; sic = sic->next)
-       if (IC_RESULT (sic) &&
-           IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
-         return NULL;
+        if (IC_RESULT (sic) &&
+            IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
+          return NULL;
     }
 
   return dic;
     }
 
   return dic;
@@ -1975,6 +2410,7 @@ reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
   /* update the sym of the used operand */
   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
   op->key = OP_SYMBOL(op)->key;
   /* update the sym of the used operand */
   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
   op->key = OP_SYMBOL(op)->key;
+  OP_SYMBOL(op)->accuse = 0;
 
   /* update the sym's liverange */
   if ( OP_LIVETO(op) < ic->seq )
 
   /* update the sym's liverange */
   if ( OP_LIVETO(op) < ic->seq )
@@ -1985,7 +2421,7 @@ reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
 }
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
 }
-  
+
 
 /*-----------------------------------------------------------------*/
 /* packRegsForSupport :- reduce some registers for support calls   */
 
 /*-----------------------------------------------------------------*/
 /* packRegsForSupport :- reduce some registers for support calls   */
@@ -1994,7 +2430,7 @@ static int
 packRegsForSupport (iCode * ic, eBBlock * ebp)
 {
   iCode *dic;
 packRegsForSupport (iCode * ic, eBBlock * ebp)
 {
   iCode *dic;
-  
+
   /* for the left & right operand :- look to see if the
      left was assigned a true symbol in far space in that
      case replace them */
   /* for the left & right operand :- look to see if the
      left was assigned a true symbol in far space in that
      case replace them */
@@ -2005,11 +2441,11 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
       dic = findAssignToSym (IC_LEFT (ic), ic);
 
       if (dic)
       dic = findAssignToSym (IC_LEFT (ic), ic);
 
       if (dic)
-       {
-         /* found it we need to remove it from the block */
-         reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
-         return 1;
-       }
+        {
+          /* found it we need to remove it from the block */
+          reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
+          return 1;
+        }
     }
 
   /* do the same for the right operand */
     }
 
   /* do the same for the right operand */
@@ -2019,28 +2455,26 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
 
       if (dic)
       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
 
       if (dic)
-       {
-         /* if this is a subtraction & the result
-            is a true symbol in far space then don't pack */
-         if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
-           {
-             sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
-             if (IN_FARSPACE (SPEC_OCLS (etype)))
-               return 0;
-           }
-         /* found it we need to remove it from the
-            block */
-         reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
-         
-         return 1;
-       }
+        {
+          /* if this is a subtraction & the result
+             is a true symbol in far space then don't pack */
+          if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
+            {
+              sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
+              if (IN_FARSPACE (SPEC_OCLS (etype)))
+                return 0;
+            }
+          /* found it we need to remove it from the
+             block */
+          reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
+
+          return 1;
+        }
     }
 
   return 0;
 }
 
     }
 
   return 0;
 }
 
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
 
 /*-----------------------------------------------------------------*/
 /* packRegsForOneuse : - will reduce some registers for single Use */
 
 /*-----------------------------------------------------------------*/
 /* packRegsForOneuse : - will reduce some registers for single Use */
@@ -2048,11 +2482,14 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
 static iCode *
 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 {
 static iCode *
 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 {
-  bitVect *uses;
   iCode *dic, *sic;
 
   /* if returning a literal then do nothing */
   iCode *dic, *sic;
 
   /* if returning a literal then do nothing */
-  if (!IS_SYMOP (op))
+  if (!IS_ITEMP (op))
+    return NULL;
+
+  /* if rematerializable or already return use then do nothing */
+  if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
     return NULL;
 
   /* only upto 2 bytes since we cannot predict
     return NULL;
 
   /* only upto 2 bytes since we cannot predict
@@ -2065,132 +2502,146 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
       !POINTER_SET (ic) &&
       !POINTER_GET (ic))
     return NULL;
       !POINTER_SET (ic) &&
       !POINTER_GET (ic))
     return NULL;
-  
+
   if (ic->op == SEND && ic->argreg != 1) return NULL;
 
   if (ic->op == SEND && ic->argreg != 1) return NULL;
 
-  /* this routine will mark the a symbol as used in one 
-     instruction use only && if the defintion is local 
+  /* this routine will mark the symbol as used in one
+     instruction use only && if the definition is local
      (ie. within the basic block) && has only one definition &&
      (ie. within the basic block) && has only one definition &&
-     that definiion is either a return value from a 
+     that definition is either a return value from a
      function or does not contain any variables in
      far space */
      function or does not contain any variables in
      far space */
-  uses = bitVectCopy (OP_USES (op));
-  bitVectUnSetBit (uses, ic->key);     /* take away this iCode */
-  if (!bitVectIsZero (uses))   /* has other uses */
+  if (bitVectnBitsOn (OP_USES (op)) > 1)
     return NULL;
 
     return NULL;
 
-  /* if it has only one defintion */
+  /* if it has only one definition */
   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
-    return NULL;               /* has more than one definition */
+    return NULL;                /* has more than one definition */
 
   /* get that definition */
 
   /* get that definition */
-  if (!(dic =
-       hTabItemWithKey (iCodehTab,
-                        bitVectFirstBit (OP_DEFS (op)))))
+  if (!(dic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (op)))))
     return NULL;
 
   /* if that only usage is a cast */
     return NULL;
 
   /* if that only usage is a cast */
-  if (dic->op == CAST) {
-    /* to a bigger type */
-    if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
-       getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
-      /* than we can not, since we cannot predict the usage of b & acc */
-      return NULL;
+  if (dic->op == CAST)
+    {
+      /* to a bigger type */
+      if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
+          getSize(OP_SYM_TYPE(IC_RIGHT(dic))))
+        {
+          /* then we can not, since we cannot predict the usage of b & acc */
+          return NULL;
+        }
     }
     }
-  }
 
   /* found the definition now check if it is local */
   if (dic->seq < ebp->fSeq ||
       dic->seq > ebp->lSeq)
 
   /* found the definition now check if it is local */
   if (dic->seq < ebp->fSeq ||
       dic->seq > ebp->lSeq)
-    return NULL;               /* non-local */
+    return NULL;                /* non-local */
 
   /* now check if it is the return from
      a function call */
   if (dic->op == CALL || dic->op == PCALL)
     {
       if (ic->op != SEND && ic->op != RETURN &&
 
   /* now check if it is the return from
      a function call */
   if (dic->op == CALL || dic->op == PCALL)
     {
       if (ic->op != SEND && ic->op != RETURN &&
-         !POINTER_SET(ic) && !POINTER_GET(ic))
-       {
-         OP_SYMBOL (op)->ruonly = 1;
-         return dic;
-       }
-      dic = dic->next;
+          !POINTER_SET(ic) && !POINTER_GET(ic))
+        {
+          OP_SYMBOL (op)->ruonly = 1;
+          return dic;
+        }
     }
     }
+  else
+    {
+      /* otherwise check that the definition does
+         not contain any symbols in far space */
+      if (isOperandInFarSpace (IC_LEFT (dic)) ||
+          isOperandInFarSpace (IC_RIGHT (dic)) ||
+          IS_OP_RUONLY (IC_LEFT (ic)) ||
+          IS_OP_RUONLY (IC_RIGHT (ic)))
+        {
+          return NULL;
+        }
 
 
+      /* if pointer set then make sure the pointer
+         is one byte */
+      if (POINTER_SET (dic) &&
+          !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
+        return NULL;
 
 
-  /* otherwise check that the definition does
-     not contain any symbols in far space */
-  if (isOperandInFarSpace (IC_LEFT (dic)) ||
-      isOperandInFarSpace (IC_RIGHT (dic)) ||
-      IS_OP_RUONLY (IC_LEFT (ic)) ||
-      IS_OP_RUONLY (IC_RIGHT (ic)))
-    {
-      return NULL;
+      if (POINTER_GET (dic) &&
+          !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
+        return NULL;
     }
 
     }
 
-  /* if pointer set then make sure the pointer
-     is one byte */
-  if (POINTER_SET (dic) &&
-      !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
-    return NULL;
-
-  if (POINTER_GET (dic) &&
-      !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
-    return NULL;
+  /* Make sure no overlapping liverange is already assigned to DPTR */
+  if (OP_SYMBOL(op)->clashes)
+    {
+      symbol *sym;
+      int i;
+
+      for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ )
+        {
+          if (bitVectBitValue(OP_SYMBOL(op)->clashes,i))
+            {
+              sym = hTabItemWithKey(liveRanges,i);
+              if (sym->ruonly)
+                return NULL ;
+            }
+        }
+    }
 
   sic = dic;
 
 
   sic = dic;
 
-  /* also make sure the intervenening instructions
-     don't have any thing in far space */
+  /* also make sure the intervening instructions
+     don't have anything in far space */
   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
     {
   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
     {
-
       /* if there is an intervening function call then no */
       if (dic->op == CALL || dic->op == PCALL)
       /* if there is an intervening function call then no */
       if (dic->op == CALL || dic->op == PCALL)
-       return NULL;
+        return NULL;
       /* if pointer set then make sure the pointer
          is one byte */
       if (POINTER_SET (dic) &&
       /* if pointer set then make sure the pointer
          is one byte */
       if (POINTER_SET (dic) &&
-         !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
-       return NULL;
+          !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
+        return NULL;
 
       if (POINTER_GET (dic) &&
 
       if (POINTER_GET (dic) &&
-         !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
-       return NULL;
+          !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
+        return NULL;
 
       /* if address of & the result is remat the okay */
       if (dic->op == ADDRESS_OF &&
 
       /* if address of & the result is remat the okay */
       if (dic->op == ADDRESS_OF &&
-         OP_SYMBOL (IC_RESULT (dic))->remat)
-       continue;
+          OP_SYMBOL (IC_RESULT (dic))->remat)
+        continue;
 
       /* if operand has size of three or more & this
          operation is a '*','/' or '%' then 'b' may
          cause a problem */
       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
 
       /* if operand has size of three or more & this
          operation is a '*','/' or '%' then 'b' may
          cause a problem */
       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
-         getSize (operandType (op)) >= 3)
-       return NULL;
+          getSize (operandType (op)) >= 3)
+        return NULL;
 
       /* if left or right or result is in far space */
       if (isOperandInFarSpace (IC_LEFT (dic)) ||
 
       /* if left or right or result is in far space */
       if (isOperandInFarSpace (IC_LEFT (dic)) ||
-         isOperandInFarSpace (IC_RIGHT (dic)) ||
-         isOperandInFarSpace (IC_RESULT (dic)) ||
-         IS_OP_RUONLY (IC_LEFT (dic)) ||
-         IS_OP_RUONLY (IC_RIGHT (dic)) ||
-         IS_OP_RUONLY (IC_RESULT (dic)))
-       {
-         return NULL;
-       }
+          isOperandInFarSpace (IC_RIGHT (dic)) ||
+          isOperandInFarSpace (IC_RESULT (dic)) ||
+          IS_OP_RUONLY (IC_LEFT (dic)) ||
+          IS_OP_RUONLY (IC_RIGHT (dic)) ||
+          IS_OP_RUONLY (IC_RESULT (dic)))
+        {
+          return NULL;
+        }
       /* if left or right or result is on stack */
       if (isOperandOnStack(IC_LEFT(dic)) ||
       /* if left or right or result is on stack */
       if (isOperandOnStack(IC_LEFT(dic)) ||
-         isOperandOnStack(IC_RIGHT(dic)) ||
-         isOperandOnStack(IC_RESULT(dic))) {
-       return NULL;
-      }
+          isOperandOnStack(IC_RIGHT(dic)) ||
+          isOperandOnStack(IC_RESULT(dic)))
+        {
+          return NULL;
+        }
     }
 
   OP_SYMBOL (op)->ruonly = 1;
   return sic;
     }
 
   OP_SYMBOL (op)->ruonly = 1;
   return sic;
-
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -2203,7 +2654,7 @@ isBitwiseOptimizable (iCode * ic)
   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
 
   /* bitwise operations are considered optimizable
   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
 
   /* bitwise operations are considered optimizable
-     under the following conditions (Jean-Louis VERN) 
+     under the following conditions (Jean-Louis VERN)
 
      x & lit
      bit & bit
 
      x & lit
      bit & bit
@@ -2239,7 +2690,7 @@ bool isCommutativeOp(unsigned int op)
 /* operandUsesAcc - determines whether the code generated for this */
 /*                  operand will have to use the accumulator       */
 /*-----------------------------------------------------------------*/
 /* operandUsesAcc - determines whether the code generated for this */
 /*                  operand will have to use the accumulator       */
 /*-----------------------------------------------------------------*/
-bool operandUsesAcc(operand *op)
+bool operandUsesAcc(operand *op, bool allowBitspace)
 {
   if (!op)
     return FALSE;
 {
   if (!op)
     return FALSE;
@@ -2252,27 +2703,27 @@ bool operandUsesAcc(operand *op)
       return TRUE;  /* duh! */
 
     if (IN_STACK(sym->etype) || sym->onStack ||
       return TRUE;  /* duh! */
 
     if (IN_STACK(sym->etype) || sym->onStack ||
-       (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
+        (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
       return TRUE;  /* acc is used to calc stack offset */
 
     if (IS_ITEMP(op))
       {
       return TRUE;  /* acc is used to calc stack offset */
 
     if (IS_ITEMP(op))
       {
-       if (SPIL_LOC(op)) {
-         sym = SPIL_LOC(op);  /* if spilled, look at spill location */
-       } else {
-         return FALSE;  /* more checks? */
-       }
+        if (SPIL_LOC(op)) {
+          sym = SPIL_LOC(op);  /* if spilled, look at spill location */
+        } else {
+          return FALSE;  /* more checks? */
+        }
       }
 
     symspace = SPEC_OCLS(sym->etype);
 
     if (sym->iaccess && symspace->paged)
       return TRUE;  /* must fetch paged indirect sym via accumulator */
       }
 
     symspace = SPEC_OCLS(sym->etype);
 
     if (sym->iaccess && symspace->paged)
       return TRUE;  /* must fetch paged indirect sym via accumulator */
-    
-    if (IN_BITSPACE(symspace))
+
+    if (!allowBitspace && IN_BITSPACE(symspace))
       return TRUE;  /* fetching bit vars uses the accumulator */
       return TRUE;  /* fetching bit vars uses the accumulator */
-    
-    if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
+
+    if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace))
       return TRUE;  /* fetched via accumulator and dptr */
   }
 
       return TRUE;  /* fetched via accumulator and dptr */
   }
 
@@ -2288,20 +2739,19 @@ packRegsForAccUse (iCode * ic)
   iCode *uic;
 
   /* if this is an aggregate, e.g. a one byte char array */
   iCode *uic;
 
   /* if this is an aggregate, e.g. a one byte char array */
-  if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
+  if (IS_AGGREGATE(operandType(IC_RESULT(ic))))
     return;
     return;
-  }
 
   /* if we are calling a reentrant function that has stack parameters */
   if (ic->op == CALL &&
 
   /* if we are calling a reentrant function that has stack parameters */
   if (ic->op == CALL &&
-       IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
-       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
-      return;
+      IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
+      FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
+    return;
 
   if (ic->op == PCALL &&
 
   if (ic->op == PCALL &&
-       IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
-       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
-      return;
+      IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
+      FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
+    return;
 
   /* if + or - then it has to be one byte result */
   if ((ic->op == '+' || ic->op == '-')
 
   /* if + or - then it has to be one byte result */
   if ((ic->op == '+' || ic->op == '-')
@@ -2323,7 +2773,6 @@ packRegsForAccUse (iCode * ic)
       getSize (operandType (IC_RESULT (ic))) > 1)
     return;
 
       getSize (operandType (IC_RESULT (ic))) > 1)
     return;
 
-
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
     return;
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
     return;
@@ -2334,7 +2783,7 @@ packRegsForAccUse (iCode * ic)
 
   /* and the usage immediately follows this iCode */
   if (!(uic = hTabItemWithKey (iCodehTab,
 
   /* and the usage immediately follows this iCode */
   if (!(uic = hTabItemWithKey (iCodehTab,
-                              bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+                               bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
     return;
 
   if (ic->next != uic)
     return;
 
   if (ic->next != uic)
@@ -2351,7 +2800,7 @@ packRegsForAccUse (iCode * ic)
       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
     return;
 
       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
     return;
 
-  /* if the usage is not is an assignment
+  /* if the usage is not an assignment
      or an arithmetic / bitwise / shift operation then not */
   if (uic->op != '=' &&
       !IS_ARITHMETIC_OP (uic) &&
      or an arithmetic / bitwise / shift operation then not */
   if (uic->op != '=' &&
       !IS_ARITHMETIC_OP (uic) &&
@@ -2360,7 +2809,7 @@ packRegsForAccUse (iCode * ic)
       uic->op != RIGHT_OP)
     return;
 
       uic->op != RIGHT_OP)
     return;
 
-  /* if used in ^ operation then make sure right is not a 
+  /* if used in ^ operation then make sure right is not a
      literal (WIML: Why is this?) */
   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
     return;
      literal (WIML: Why is this?) */
   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
     return;
@@ -2393,10 +2842,10 @@ packRegsForAccUse (iCode * ic)
     goto accuse;
 
   /* if the other operand uses the accumulator then we cannot */
     goto accuse;
 
   /* if the other operand uses the accumulator then we cannot */
-  if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
-       operandUsesAcc(IC_RIGHT(uic))) ||
+  if ( (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
+        operandUsesAcc (IC_RIGHT (uic), IS_BIT (operandType (IC_LEFT (uic))))) ||
        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
-       operandUsesAcc(IC_LEFT(uic))) ) 
+        operandUsesAcc (IC_LEFT (uic), IS_BIT (operandType (IC_RIGHT (uic))))) )
     return;
 
   /* make sure this is on the left side if not commutative */
     return;
 
   /* make sure this is on the left side if not commutative */
@@ -2425,13 +2874,14 @@ accuse:
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* packForPush - hueristics to reduce iCode for pushing            */
+/* packForPush - heuristics to reduce iCode for pushing            */
 /*-----------------------------------------------------------------*/
 static void
 /*-----------------------------------------------------------------*/
 static void
-packForPush (iCode * ic, eBBlock * ebp)
+packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
 {
   iCode *dic, *lic;
   bitVect *dbv;
 {
   iCode *dic, *lic;
   bitVect *dbv;
+  struct eBBlock * ebp=ebpp[blockno];
 
   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
     return;
 
   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
     return;
@@ -2443,38 +2893,58 @@ packForPush (iCode * ic, eBBlock * ebp)
 
   /* find the definition */
   if (!(dic = hTabItemWithKey (iCodehTab,
 
   /* find the definition */
   if (!(dic = hTabItemWithKey (iCodehTab,
-                              bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
+                               bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
     return;
 
   if (dic->op != '=' || POINTER_SET (dic))
     return;
 
     return;
 
   if (dic->op != '=' || POINTER_SET (dic))
     return;
 
-  /* make sure the right side does not have any definitions
-     inbetween */
-  dbv = OP_DEFS(IC_RIGHT(dic));
-  for (lic = ic; lic && lic != dic ; lic = lic->prev) {
-    if (bitVectBitValue(dbv,lic->key)) 
-      return ;
-  }
-  /* make sure they have the same type */
-  {
-    sym_link *itype=operandType(IC_LEFT(ic));
-    sym_link *ditype=operandType(IC_RIGHT(dic));
+  if (dic->seq < ebp->fSeq) // Evelyn did this
+    {
+      int i;
+      for (i=0; i<blockno; i++)
+        {
+          if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq)
+            {
+              ebp=ebpp[i];
+              break;
+            }
+        }
+      wassert (i!=blockno); // no way to recover from here
+    }
+
+  if (IS_SYMOP(IC_RIGHT(dic)))
+    {
+      /* make sure the right side does not have any definitions
+         inbetween */
+      dbv = OP_DEFS(IC_RIGHT(dic));
+      for (lic = ic; lic && lic != dic ; lic = lic->prev)
+        {
+          if (bitVectBitValue(dbv,lic->key))
+            return ;
+        }
+      /* make sure they have the same type */
+      if (IS_SPEC(operandType(IC_LEFT(ic))))
+        {
+          sym_link *itype=operandType(IC_LEFT(ic));
+          sym_link *ditype=operandType(IC_RIGHT(dic));
+
+          if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
+              SPEC_LONG(itype)!=SPEC_LONG(ditype))
+            return;
+        }
+      /* extend the live range of replaced operand if needed */
+      if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq)
+        {
+          OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
+        }
+      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+    }
 
 
-    if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
-       SPEC_LONG(itype)!=SPEC_LONG(ditype))
-      return;
-  }
-  /* extend the live range of replaced operand if needed */
-  if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
-         OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
-  }
   /* we now we know that it has one & only one def & use
      and the that the definition is an assignment */
   /* we now we know that it has one & only one def & use
      and the that the definition is an assignment */
-  IC_LEFT (ic) = IC_RIGHT (dic);
-   
+  ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
   remiCodeFromeBBlock (ebp, dic);
   remiCodeFromeBBlock (ebp, dic);
-  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
 }
 
   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
 }
 
@@ -2483,261 +2953,323 @@ packForPush (iCode * ic, eBBlock * ebp)
 /*                   pressure                                      */
 /*-----------------------------------------------------------------*/
 static void
 /*                   pressure                                      */
 /*-----------------------------------------------------------------*/
 static void
-packRegisters (eBBlock * ebp)
+packRegisters (eBBlock ** ebpp, int blockno)
 {
   iCode *ic;
   int change = 0;
 {
   iCode *ic;
   int change = 0;
+  eBBlock *ebp=ebpp[blockno];
 
 
-  while (1)
+  do
     {
     {
-
       change = 0;
 
       /* look for assignments of the form */
       change = 0;
 
       /* look for assignments of the form */
-      /* iTempNN = TRueSym (someoperation) SomeOperand */
+      /* iTempNN = TrueSym (someoperation) SomeOperand */
       /*       ....                       */
       /* TrueSym := iTempNN:1             */
       for (ic = ebp->sch; ic; ic = ic->next)
       /*       ....                       */
       /* TrueSym := iTempNN:1             */
       for (ic = ebp->sch; ic; ic = ic->next)
-       {
-         /* find assignment of the form TrueSym := iTempNN:1 */
-         if (ic->op == '=' && !POINTER_SET (ic))
-           change += packRegsForAssign (ic, ebp);
-       }
-
-      if (!change)
-       break;
+        {
+          /* find assignment of the form TrueSym := iTempNN:1 */
+          if (ic->op == '=' && !POINTER_SET (ic))
+            change += packRegsForAssign (ic, ebp);
+        }
     }
     }
+  while (change);
 
   for (ic = ebp->sch; ic; ic = ic->next)
     {
 
   for (ic = ebp->sch; ic; ic = ic->next)
     {
-      /* if this is an itemp & result of an address of a true sym 
+      /* Fix for bug #979599:   */
+      /* P0 &= ~1;              */
+
+      /* Look for two subsequent iCodes with */
+      /*   iTemp := _c;         */
+      /*   _c = iTemp & op;     */
+      /* and replace them by    */
+      /*   iTemp := _c;         */
+      /*   _c = _c & op;        */
+      if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
+          ic->prev &&
+          ic->prev->op == '=' &&
+          IS_ITEMP (IC_LEFT (ic)) &&
+          IC_LEFT (ic) == IC_RESULT (ic->prev) &&
+          isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
+        {
+          iCode* ic_prev = ic->prev;
+          symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
+
+          ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
+          if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
+            {
+              bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
+              if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
+                  prev_result_sym->liveTo == ic->seq)
+                {
+                  prev_result_sym->liveTo = ic_prev->seq;
+                }
+            }
+          bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+
+          bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
+
+          if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
+            {
+              bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
+              bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
+              remiCodeFromeBBlock (ebp, ic_prev);
+              hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
+            }
+        }
+
+      /* if this is an itemp & result of an address of a true sym
          then mark this as rematerialisable   */
       if (ic->op == ADDRESS_OF &&
          then mark this as rematerialisable   */
       if (ic->op == ADDRESS_OF &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
-         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
-         !OP_SYMBOL (IC_LEFT (ic))->onStack)
-       {
-
-         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
-         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
-
-       }
+          IS_ITEMP (IC_RESULT (ic)) &&
+          IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+          !OP_SYMBOL (IC_LEFT (ic))->onStack)
+        {
+          OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+          OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+          OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+        }
 
       /* if straight assignment then carry remat flag if
          this is the only definition */
       if (ic->op == '=' &&
 
       /* if straight assignment then carry remat flag if
          this is the only definition */
       if (ic->op == '=' &&
-         !POINTER_SET (ic) &&
-         IS_SYMOP (IC_RIGHT (ic)) &&
-         OP_SYMBOL (IC_RIGHT (ic))->remat &&
-         !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
-         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
-       {
-
-         OP_SYMBOL (IC_RESULT (ic))->remat =
-           OP_SYMBOL (IC_RIGHT (ic))->remat;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
-           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
-       }
+          !POINTER_SET (ic) &&
+          IS_SYMOP (IC_RIGHT (ic)) &&
+          OP_SYMBOL (IC_RIGHT (ic))->remat &&
+          !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
+          !isOperandGlobal(IC_RESULT(ic)) &&          /* due to bug 1618050 */
+          bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+        {
+          OP_SYMBOL (IC_RESULT (ic))->remat =
+            OP_SYMBOL (IC_RIGHT (ic))->remat;
+          OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+            OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+        }
 
       /* if cast to a generic pointer & the pointer being
 
       /* if cast to a generic pointer & the pointer being
-        cast is remat, then we can remat this cast as well */
-      if (ic->op == CAST && 
-         IS_SYMOP(IC_RIGHT(ic)) &&
-         OP_SYMBOL(IC_RIGHT(ic))->remat ) {
-             sym_link *to_type = operandType(IC_LEFT(ic));
-             sym_link *from_type = operandType(IC_RIGHT(ic));
-             if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
-                     OP_SYMBOL (IC_RESULT (ic))->remat = 1;
-                     OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
-                     OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
-             }
-      }
-
-      /* if this is a +/- operation with a rematerizable 
+         cast is remat, then we can remat this cast as well */
+      if (ic->op == CAST &&
+          IS_SYMOP(IC_RIGHT(ic)) &&
+          OP_SYMBOL(IC_RIGHT(ic))->remat &&
+          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
+        {
+          sym_link *to_type = operandType(IC_LEFT(ic));
+          sym_link *from_type = operandType(IC_RIGHT(ic));
+          if (IS_GENPTR(to_type) && IS_PTR(from_type))
+            {
+              OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+              OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+              OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+            }
+        }
+
+      /* if this is a +/- operation with a rematerizable
          then mark this as rematerializable as well */
       if ((ic->op == '+' || ic->op == '-') &&
          then mark this as rematerializable as well */
       if ((ic->op == '+' || ic->op == '-') &&
-         (IS_SYMOP (IC_LEFT (ic)) &&
-          IS_ITEMP (IC_RESULT (ic)) &&
-          IS_OP_LITERAL (IC_RIGHT (ic))) &&
-          OP_SYMBOL (IC_LEFT (ic))->remat &&
-         (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
-          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
-       {
-         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
-         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
-       }
+          (IS_SYMOP (IC_LEFT (ic)) &&
+           IS_ITEMP (IC_RESULT (ic)) &&
+           IS_OP_LITERAL (IC_RIGHT (ic))) &&
+           OP_SYMBOL (IC_LEFT (ic))->remat &&
+          (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
+           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
+        {
+          OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+          OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+          OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+        }
 
       /* mark the pointer usages */
 
       /* mark the pointer usages */
-      if (POINTER_SET (ic))
-       OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
+      if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)))
+        OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
 
 
-      if (POINTER_GET (ic))
-       OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+      if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic)))
+        OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
 
       if (!SKIP_IC2 (ic))
 
       if (!SKIP_IC2 (ic))
-       {
-         /* if we are using a symbol on the stack
-            then we should say mcs51_ptrRegReq */
-         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
-           mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
-                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
-         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
-           mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
-                             OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
-         else
-           {
-             if (IS_SYMOP (IC_LEFT (ic)))
-               mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
-                               OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
-             if (IS_SYMOP (IC_RIGHT (ic)))
-               mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
-                              OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
-             if (IS_SYMOP (IC_RESULT (ic)))
-               mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
-                             OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
-           }
-       }
+        {
+          /* if we are using a symbol on the stack
+             then we should say mcs51_ptrRegReq */
+          if (options.useXstack && ic->parmPush
+              && (ic->op == IPUSH || ic->op == IPOP))
+            mcs51_ptrRegReq++;
+          if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
+            mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
+                                 OP_SYMBOL (IC_COND (ic))->iaccess ||
+                                 SPEC_OCLS(OP_SYMBOL (IC_COND (ic))->etype) == idata) ? 1 : 0);
+          else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
+            mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
+                              OP_SYMBOL (IC_JTCOND (ic))->iaccess ||
+                              SPEC_OCLS(OP_SYMBOL (IC_JTCOND (ic))->etype) == idata) ? 1 : 0);
+          else
+            {
+              if (IS_SYMOP (IC_LEFT (ic)))
+                mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
+                                OP_SYMBOL (IC_LEFT (ic))->iaccess ||
+                                SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) ? 1 : 0);
+              if (IS_SYMOP (IC_RIGHT (ic)))
+                mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
+                               OP_SYMBOL (IC_RIGHT (ic))->iaccess ||
+                               SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) ? 1 : 0);
+              if (IS_SYMOP (IC_RESULT (ic)))
+                mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
+                              OP_SYMBOL (IC_RESULT (ic))->iaccess ||
+                              SPEC_OCLS(OP_SYMBOL (IC_RESULT (ic))->etype) == idata) ? 1 : 0);
+              if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
+                  && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE)
+                mcs51_ptrRegReq ++;
+              if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic))
+                  && getSize (OP_SYMBOL (IC_RESULT (ic))->type) <= (unsigned int) PTRSIZE)
+                mcs51_ptrRegReq ++;
+            }
+        }
 
       /* if the condition of an if instruction
          is defined in the previous instruction and
 
       /* if the condition of an if instruction
          is defined in the previous instruction and
-        this is the only usage then
+         this is the only usage then
          mark the itemp as a conditional */
       if ((IS_CONDITIONAL (ic) ||
          mark the itemp as a conditional */
       if ((IS_CONDITIONAL (ic) ||
-          (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
-         ic->next && ic->next->op == IFX &&
-         bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
-         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
-         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
-       {
-         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
-         continue;
-       }
+           (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
+          ic->next && ic->next->op == IFX &&
+          bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
+          isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+          OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+        {
+          OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+          continue;
+        }
+
+      /* if the condition of an if instruction
+         is defined in the previous GET_POINTER instruction and
+         this is the only usage then
+         mark the itemp as accumulator use */
+      if ((POINTER_GET (ic) && getSize (operandType (IC_RESULT (ic))) <=1) &&
+          ic->next && ic->next->op == IFX &&
+          bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
+          isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+          OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+        {
+          OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
+          continue;
+        }
 
       /* reduce for support function calls */
       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
 
       /* reduce for support function calls */
       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
-       packRegsForSupport (ic, ebp);
+        packRegsForSupport (ic, ebp);
 
       /* some cases the redundant moves can
          can be eliminated for return statements */
       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
 
       /* some cases the redundant moves can
          can be eliminated for return statements */
       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
-         !isOperandInFarSpace (IC_LEFT (ic)) &&
-         options.model == MODEL_SMALL) {
-       if (0 && options.stackAuto) {
-         /* we should check here if acc will be clobbered for stack
-            offset calculations */
-       } else {
-         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-       }
+          !isOperandInFarSpace (IC_LEFT (ic)) &&
+          options.model == MODEL_SMALL) {
+        packRegsForOneuse (ic, IC_LEFT (ic), ebp);
       }
 
       /* if pointer set & left has a size more than
          one and right is not in far space */
       if (POINTER_SET (ic) &&
       }
 
       /* if pointer set & left has a size more than
          one and right is not in far space */
       if (POINTER_SET (ic) &&
-         !isOperandInFarSpace (IC_RIGHT (ic)) &&
-         !OP_SYMBOL (IC_RESULT (ic))->remat &&
-         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
-         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
-
-       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+          IS_SYMOP (IC_RESULT (ic)) &&
+          !isOperandInFarSpace (IC_RIGHT (ic)) &&
+          !OP_SYMBOL (IC_RESULT (ic))->remat &&
+          !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+          getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
+        packRegsForOneuse (ic, IC_RESULT (ic), ebp);
 
       /* if pointer get */
       if (POINTER_GET (ic) &&
 
       /* if pointer get */
       if (POINTER_GET (ic) &&
-         !isOperandInFarSpace (IC_RESULT (ic)) &&
-         !OP_SYMBOL (IC_LEFT (ic))->remat &&
-         !IS_OP_RUONLY (IC_RESULT (ic)) &&
-         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
-
-       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
-
-      /* if this is cast for intergral promotion then
-         check if only use of  the definition of the 
+          IS_SYMOP (IC_LEFT (ic)) &&
+          !isOperandInFarSpace (IC_RESULT (ic)) &&
+          !OP_SYMBOL (IC_LEFT (ic))->remat &&
+          !IS_OP_RUONLY (IC_RESULT (ic)) &&
+          getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
+        packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+      /* if this is a cast for intergral promotion then
+         check if it's the only use of the definition of the
          operand being casted/ if yes then replace
          operand being casted/ if yes then replace
-         the result of that arithmetic operation with 
+         the result of that arithmetic operation with
          this result and get rid of the cast */
       if (ic->op == CAST)
          this result and get rid of the cast */
       if (ic->op == CAST)
-       {
-         sym_link *fromType = operandType (IC_RIGHT (ic));
-         sym_link *toType = operandType (IC_LEFT (ic));
-
-         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
-             getSize (fromType) != getSize (toType) &&
-             SPEC_USIGN (fromType) == SPEC_USIGN (toType))
-           {
-
-             iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
-             if (dic)
-               {
-                 if (IS_ARITHMETIC_OP (dic))
-                   {                  
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
-                     IC_RESULT (dic) = IC_RESULT (ic);
-                     remiCodeFromeBBlock (ebp, ic);
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
-                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-                     ic = ic->prev;
-                   }
-                 else
-                   OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
-               }
-           }
-         else
-           {
-
-             /* if the type from and type to are the same
-                then if this is the only use then packit */
-             if (compareType (operandType (IC_RIGHT (ic)),
-                            operandType (IC_LEFT (ic))) == 1)
-               {
-                 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
-                 if (dic)
-                   {
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
-                     IC_RESULT (dic) = IC_RESULT (ic);
-                     remiCodeFromeBBlock (ebp, ic);
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
-                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-                     ic = ic->prev;
-                   }
-               }
-           }
-       }
-
-      /* pack for PUSH 
+        {
+          sym_link *fromType = operandType (IC_RIGHT (ic));
+          sym_link *toType = operandType (IC_LEFT (ic));
+
+          if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
+              getSize (fromType) != getSize (toType) &&
+              SPEC_USIGN (fromType) == SPEC_USIGN (toType))
+            {
+
+              iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+              if (dic)
+                {
+                  if (IS_ARITHMETIC_OP (dic))
+                    {
+                      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+                      ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
+                      remiCodeFromeBBlock (ebp, ic);
+                      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+                      hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+                      OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+                      ic = ic->prev;
+                    }
+                  else
+                    OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
+                }
+            }
+          else
+            {
+              /* if the type from and type to are the same
+                 then if this is the only use then packit */
+              if (compareType (operandType (IC_RIGHT (ic)),
+                             operandType (IC_LEFT (ic))) == 1)
+                {
+                  iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+                  if (dic)
+                    {
+                      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+                      ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
+                      remiCodeFromeBBlock (ebp, ic);
+                      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+                      hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+                      OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+                      ic = ic->prev;
+                    }
+                }
+            }
+        }
+
+      /* pack for PUSH
          iTempNN := (some variable in farspace) V1
          push iTempNN ;
          -------------
          push V1
        */
       if (ic->op == IPUSH)
          iTempNN := (some variable in farspace) V1
          push iTempNN ;
          -------------
          push V1
        */
       if (ic->op == IPUSH)
-       {
-         packForPush (ic, ebp);
-       }
-
+        {
+          packForPush (ic, ebpp, blockno);
+        }
 
       /* pack registers for accumulator use, when the
          result of an arithmetic or bit wise operation
          has only one use, that use is immediately following
 
       /* pack registers for accumulator use, when the
          result of an arithmetic or bit wise operation
          has only one use, that use is immediately following
-         the defintion and the using iCode has only one
+         the definition and the using iCode has only one
          operand or has two operands but one is literal &
          the result of that operation is not on stack then
          we can leave the result of this operation in acc:b
          combination */
       if ((IS_ARITHMETIC_OP (ic)
          operand or has two operands but one is literal &
          the result of that operation is not on stack then
          we can leave the result of this operation in acc:b
          combination */
       if ((IS_ARITHMETIC_OP (ic)
-          || IS_CONDITIONAL(ic)
-          || IS_BITWISE_OP (ic)
-          || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
-          || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
-         ) &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         getSize (operandType (IC_RESULT (ic))) <= 2)
-
-       packRegsForAccUse (ic);
+           || IS_CONDITIONAL(ic)
+           || IS_BITWISE_OP (ic)
+           || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
+           || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
+          ) &&
+          IS_ITEMP (IC_RESULT (ic)) &&
+          getSize (operandType (IC_RESULT (ic))) <= 2)
+        {
+          packRegsForAccUse (ic);
+        }
     }
 }
 
     }
 }
 
@@ -2745,25 +3277,41 @@ packRegisters (eBBlock * ebp)
 /* assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
 void
 /* assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
 void
-mcs51_assignRegisters (eBBlock ** ebbs, int count)
+mcs51_assignRegisters (ebbIndex * ebbi)
 {
 {
+  eBBlock ** ebbs = ebbi->bbOrder;
+  int count = ebbi->count;
   iCode *ic;
   int i;
 
   setToNull ((void *) &_G.funcrUsed);
   iCode *ic;
   int i;
 
   setToNull ((void *) &_G.funcrUsed);
+  setToNull ((void *) &_G.regAssigned);
   setToNull ((void *) &_G.totRegAssigned);
   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
   setToNull ((void *) &_G.totRegAssigned);
   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-  mcs51_nRegs = 8;
+  if ((currFunc && IFFUNC_ISREENT (currFunc->type)) || options.stackAuto)
+    {
+      mcs51_nRegs = 16;
+    }
+  else
+    {
+      mcs51_nRegs = 8;
+    }
+  _G.allBitregs = findAllBitregs ();
 
   /* change assignments this will remove some
      live ranges reducing some register pressure */
 
   /* change assignments this will remove some
      live ranges reducing some register pressure */
+
   for (i = 0; i < count; i++)
   for (i = 0; i < count; i++)
-    packRegisters (ebbs[i]);
+    packRegisters (ebbs, i);
+
+  /* liveranges probably changed by register packing
+     so we compute them again */
+  recomputeLiveRanges (ebbs, count);
 
   if (options.dump_pack)
 
   if (options.dump_pack)
-    dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+    dumpEbbsToFileExt (DUMP_PACK, ebbi);
 
 
-  /* first determine for each live range the number of 
+  /* first determine for each live range the number of
      registers & the type of registers required for each */
   regTypeNum (*ebbs);
 
      registers & the type of registers required for each */
   regTypeNum (*ebbs);
 
@@ -2771,6 +3319,8 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   serialRegAssign (ebbs, count);
 
   freeAllRegs ();
   serialRegAssign (ebbs, count);
 
   freeAllRegs ();
+  //setToNull ((void *) &_G.regAssigned);
+  //setToNull ((void *) &_G.totRegAssigned);
   fillGaps();
 
   /* if stack was extended then tell the user */
   fillGaps();
 
   /* if stack was extended then tell the user */
@@ -2793,11 +3343,21 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   createRegMask (ebbs, count);
 
   /* redo that offsets for stacked automatic variables */
   createRegMask (ebbs, count);
 
   /* redo that offsets for stacked automatic variables */
-  redoStackOffsets ();
+  if (currFunc) {
+    redoStackOffsets ();
+  }
+
+  /* make sure r0 & r1 are flagged as used if they might be used */
+  /* as pointers */
+  if (currFunc && mcs51_ptrRegReq)
+    {
+      currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R0_IDX);
+      currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R1_IDX);
+    }
 
   if (options.dump_rassgn)
     {
 
   if (options.dump_rassgn)
     {
-      dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+      dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
       dumpLiveRanges (DUMP_LRANGE, liveRanges);
     }
 
       dumpLiveRanges (DUMP_LRANGE, liveRanges);
     }
 
@@ -2812,8 +3372,8 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   /* free up any _G.stackSpil locations allocated */
   applyToSet (_G.stackSpil, deallocStackSpil);
   _G.slocNum = 0;
   /* free up any _G.stackSpil locations allocated */
   applyToSet (_G.stackSpil, deallocStackSpil);
   _G.slocNum = 0;
-  setToNull ((void **) &_G.stackSpil);
-  setToNull ((void **) &_G.spiltSet);
+  setToNull ((void *) &_G.stackSpil);
+  setToNull ((void *) &_G.spiltSet);
   /* mark all registers as free */
   freeAllRegs ();
 
   /* mark all registers as free */
   freeAllRegs ();