* device/include/pic16/pic18f*.h: add bit aliases in INTCONbits_t
[fw/sdcc] / src / mcs51 / ralloc.c
index 96a431ce920e3719844ae553bc0bd1bae91a8e4a..2a627aade38fade32b735d965faa979edbcdd4f7 100644 (file)
@@ -51,6 +51,7 @@ static struct
     bitVect *funcrUsed;         /* registers used in a function */
     int stackExtend;
     int dataExtend;
+    bitVect *allBitregs;        /* all bit registers */
   }
 _G;
 
@@ -69,6 +70,14 @@ regs regs8051[] =
   {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},
@@ -80,7 +89,7 @@ regs regs8051[] =
   {0,       B_IDX,   0,       "b",   "b",   "0xf0", 0, 0},
   {0,       A_IDX,   0,       "a",   "acc", "0xe0", 0, 0},
 };
-int mcs51_nRegs = 17;
+int mcs51_nRegs = 16;
 static void spillThis (symbol *);
 static void freeAllRegs ();
 
@@ -238,6 +247,15 @@ computeSpillable (iCode * ic)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* 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);
+}
+
 /*-----------------------------------------------------------------*/
 /* noSpilLoc - return true if a variable has no spil location      */
 /*-----------------------------------------------------------------*/
@@ -257,7 +275,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)
@@ -360,7 +378,7 @@ leastUsedLR (set * sset)
     {
 
       /* 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 (getSize (lsym->type) < getSize (sym->type))
           sym = lsym;
@@ -505,16 +523,20 @@ createStackSpil (symbol * sym)
   /* set the type to the spilling symbol */
   sloc->type = copyLinkChain (sym->type);
   sloc->etype = getSpec (sloc->type);
-  if (SPEC_SCLS (sloc->etype) != S_BIT)
+  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;
 
-  /* 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
@@ -556,6 +578,7 @@ createStackSpil (symbol * sym)
 
 /*-----------------------------------------------------------------*/
 /* isSpiltOnStack - returns true if the spil location is on stack  */
+/*                  or otherwise needs a pointer register          */
 /*-----------------------------------------------------------------*/
 static bool
 isSpiltOnStack (symbol * sym)
@@ -574,6 +597,9 @@ isSpiltOnStack (symbol * sym)
   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;
@@ -636,10 +662,20 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* 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);
     }
@@ -661,7 +697,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* 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)))
@@ -698,7 +733,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* 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++;
@@ -708,7 +742,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* find live ranges with spillocation */
   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
     {
-
       sym = leastUsedLR (selectS);
       sym->usl.spillLoc->allocreq++;
       return sym;
@@ -719,7 +752,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
      used ofcourse */
   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
     {
-
       /* return a created spil location */
       sym = createStackSpil (leastUsedLR (selectS));
       sym->usl.spillLoc->allocreq++;
@@ -865,6 +897,21 @@ tryAgain:
   goto tryAgain;
 }
 
+/*-----------------------------------------------------------------*/
+/* 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                        */
 /*-----------------------------------------------------------------*/
@@ -906,6 +953,27 @@ static regs *getRegGprNoSpil()
   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                         */
 /*-----------------------------------------------------------------*/
@@ -921,6 +989,29 @@ symHasReg (symbol * sym, regs * reg)
   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              */
@@ -1178,18 +1269,8 @@ serialRegAssign (eBBlock ** ebbs, int count)
       /* for all instructions do */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
         {
-#if 1
-            int reg;
-
-            // update the registers in use at the start of this icode
-            for (reg=0; reg<mcs51_nRegs; reg++) {
-              if (regs8051[reg].isFree) {
-                ic->riu &= ~(1<<regs8051[reg].offset);
-              } else {
-                ic->riu |= (1<<regs8051[reg].offset);
-              }
-            }
-#endif
+            updateRegUsage(ic);
+
             /* if this is an ipop that means some live
                range will have to be assigned again */
             if (ic->op == IPOP)
@@ -1246,10 +1327,11 @@ serialRegAssign (eBBlock ** ebbs, int count)
                     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 (SPEC_NOUN(sym->etype) == V_BIT) {
+                if (willCS && SPEC_NOUN(sym->etype) == V_BIT) {
                     spillThis (sym);
                     continue;
                 }
@@ -1258,7 +1340,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
                    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);
@@ -1323,13 +1404,15 @@ serialRegAssign (eBBlock ** ebbs, int count)
                     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])
+                            if (right->regs[j] && (right->regType != REG_BIT))
                               sym->regs[j] = allocThisReg (right->regs[j]);
                           }
                         if (!sym->regs[j])
@@ -1427,6 +1510,10 @@ static void fillGaps()
 
         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 ++) {
@@ -1468,6 +1555,8 @@ static void fillGaps()
         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;
@@ -1576,6 +1665,33 @@ static void fillGaps()
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* 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             */
 /*-----------------------------------------------------------------*/
@@ -1727,21 +1843,23 @@ createRegMask (eBBlock ** ebbs, int count)
 static char *
 rematStr (symbol * sym)
 {
-  char *s = buffer;
   iCode *ic = sym->rematiCode;
-
-  *s = 0;
+  int offset = 0;
 
   while (1)
     {
+      /* 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 plus or minus print the right hand side */
-      if (ic->op == '+' || ic->op == '-')
+      /* if minus adjust offset to right hand side */
+      if (ic->op == '-')
         {
-          SNPRINTF (s, sizeof(buffer) - strlen(buffer),
-                    "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
-                    ic->op);
-          s += strlen (s);
+          offset -= (int) operandLitValue (IC_RIGHT (ic));
           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
           continue;
         }
@@ -1752,11 +1870,21 @@ rematStr (symbol * sym)
           continue;
       }
       /* we reached the end */
-      SNPRINTF (s, sizeof(buffer) - strlen(buffer),
-                "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
       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;
 }
 
@@ -1794,6 +1922,8 @@ regTypeNum (eBBlock *ebbs)
             {
               if (IS_AGGREGATE (sym->type) || sym->isptr)
                 sym->type = aggrToPtr (sym->type, FALSE);
+              else if (IS_BIT(sym->type))
+                sym->regType = REG_CND;
               continue;
             }
 
@@ -1994,6 +2124,13 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
             }
         }
 
+      /* Don't move an assignment out of a critical block */
+      if (dic->op == CRITICAL)
+        {
+          dic = NULL;
+          break;
+        }
+
       if (SKIP_IC2 (dic))
         continue;
 
@@ -2074,20 +2211,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
             }
        }
     }
-#if 0
-  /* if assignment then check that right is not a bit */
-  if (ASSIGNMENT (dic) && !POINTER_SET (dic))
-    {
-      sym_link *etype = operandType (IC_RIGHT (dic));
-      if (IS_BITFIELD (etype))
-        {
-          /* if result is a bit too then it's ok */
-          etype = operandType (IC_RESULT (dic));
-          if (!IS_BITFIELD (etype))
-            return 0;
-        }
-    }
-#endif
+
   /* 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 ||
@@ -2330,8 +2454,6 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
   return 0;
 }
 
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
 
 /*-----------------------------------------------------------------*/
 /* packRegsForOneuse : - will reduce some registers for single Use */
@@ -2362,16 +2484,16 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 
   if (ic->op == SEND && ic->argreg != 1) return NULL;
 
-  /* this routine will mark the 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 &&
-     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 */
   if (bitVectnBitsOn (OP_USES (op)) > 1)
     return NULL;
 
-  /* if it has only one defintion */
+  /* if it has only one definition */
   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
     return NULL;                /* has more than one definition */
 
@@ -2409,25 +2531,25 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
     }
   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;
-    }
+      /* 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;
+      /* 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;
+      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 */
@@ -2449,11 +2571,10 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 
   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)
     {
-
       /* if there is an intervening function call then no */
       if (dic->op == CALL || dic->op == PCALL)
         return NULL;
@@ -2547,7 +2668,7 @@ bool isCommutativeOp(unsigned int op)
 /* 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;
@@ -2577,7 +2698,7 @@ bool operandUsesAcc(operand *op)
     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 */
 
     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace))
@@ -2631,7 +2752,6 @@ packRegsForAccUse (iCode * ic)
       getSize (operandType (IC_RESULT (ic))) > 1)
     return;
 
-
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
     return;
@@ -2659,7 +2779,7 @@ packRegsForAccUse (iCode * ic)
       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) &&
@@ -2701,10 +2821,10 @@ packRegsForAccUse (iCode * ic)
     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 &&
-        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 */
@@ -2895,6 +3015,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
           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 =
@@ -2936,11 +3057,10 @@ packRegisters (eBBlock ** ebpp, int blockno)
         }
 
       /* mark the pointer usages */
-      if (POINTER_SET (ic))
+      if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)))
         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
 
-      if (POINTER_GET (ic) &&
-          IS_SYMOP(IC_LEFT (ic)))
+      if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic)))
         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
 
       if (!SKIP_IC2 (ic))
@@ -3025,6 +3145,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
       /* if pointer set & left has a size more than
          one and right is not in far space */
       if (POINTER_SET (ic) &&
+          IS_SYMOP (IC_RESULT (ic)) &&
           !isOperandInFarSpace (IC_RIGHT (ic)) &&
           !OP_SYMBOL (IC_RESULT (ic))->remat &&
           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
@@ -3040,7 +3161,6 @@ packRegisters (eBBlock ** ebpp, int blockno)
           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
@@ -3075,7 +3195,6 @@ packRegisters (eBBlock ** ebpp, int blockno)
             }
           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)),
@@ -3111,7 +3230,7 @@ packRegisters (eBBlock ** ebpp, int 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
-         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
@@ -3144,7 +3263,16 @@ mcs51_assignRegisters (ebbIndex * ebbi)
   setToNull ((void *) &_G.regAssigned);
   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 */