* support/regression/tests/bug-477927.c: Added.
[fw/sdcc] / src / mcs51 / ralloc.c
index 1c8d487bdc67407d1878341b82cd38d8aeb0ad70..a6a346418fd86a631f27437c31bf05ae3f83762b 100644 (file)
@@ -1182,10 +1182,15 @@ serialRegAssign (eBBlock ** ebbs, int count)
                    else
                        sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
 
-                   /* if the allocation falied which means
+                   /* if the allocation failed which means
                       this was spilt then break */
-                   if (!sym->regs[j])
-                       break;
+                   if (!sym->regs[j]) {
+                     if (j) {
+                       fprintf (stderr, "%d reg(s) lost in %s:%d\n",
+                                j, __FILE__,__LINE__);
+                     }
+                     break;
+                   }
                }
 
                /* if it shares registers with operands make sure
@@ -1432,6 +1437,7 @@ regTypeNum ()
              (ic = hTabItemWithKey (iCodehTab,
                                     bitVectFirstBit (sym->defs))) &&
              POINTER_GET (ic) &&
+             !sym->noSpilLoc &&
              !IS_BITVAR (sym->etype))
            {
 
@@ -1583,55 +1589,33 @@ static int
 packRegsForAssign (iCode * ic, eBBlock * ebp)
 {
   iCode *dic, *sic;
-  sym_link *etype = operandType (IC_RIGHT (ic));
+  //sym_link *etype = operandType (IC_RIGHT (ic));
 
   if (!IS_ITEMP (IC_RIGHT (ic)) ||
       OP_SYMBOL (IC_RIGHT (ic))->isind ||
-      OP_LIVETO (IC_RIGHT (ic)) > ic->seq ||
-      IS_BITFIELD (etype))
+      OP_LIVETO (IC_RIGHT (ic)) > ic->seq
+      /* why? || IS_BITFIELD (etype) */ )
     {
       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 0
-  if (isOperandInFarSpace (IC_RESULT (ic)))
-    {
-      if ((dic = farSpacePackable (ic)))
-       goto pack;
-      else
-       return 0;
-    }
-#else
   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
     return 0;
   }
-#endif
 
   /* 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)
     {
-#if 0 // jwk 20010410
-      /* if there is a function call and this is
-         a parameter & not my parameter then don't pack it */
-      if ((dic->op == CALL || dic->op == PCALL) &&
-         (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
-          !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
-       {
-         dic = NULL;
-         break;
-       }
-#else
       /* if there is a function call then don't pack it */
       if ((dic->op == CALL || dic->op == PCALL))
        {
          dic = NULL;
          break;
        }
-#endif
 
       if (SKIP_IC2 (dic))
        continue;
@@ -1754,9 +1738,9 @@ findAssignToSym (operand * op, iCode * ic)
          /* or in stack space in case of + & - */
 
          /* if assigned to a non-symbol then return
-            true */
+            FALSE */
          if (!IS_SYMOP (IC_RIGHT (dic)))
-           break;
+           return NULL;
 
          /* if the symbol is in far space then
             we should not */
@@ -1815,6 +1799,8 @@ static int
 packRegsForSupport (iCode * ic, eBBlock * ebp)
 {
   int change = 0;
+  iCode *dic, *sic;
+
   /* for the left & right operand :- look to see if the
      left was assigned a true symbol in far space in that
      case replace them */
@@ -1822,8 +1808,7 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
   if (IS_ITEMP (IC_LEFT (ic)) &&
       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
     {
-      iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
-      iCode *sic;
+      dic = findAssignToSym (IC_LEFT (ic), ic);
 
       if (!dic)
        goto right;
@@ -1833,9 +1818,8 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
       for (sic = dic; sic != ic; sic = sic->next)
        bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
 
-      IC_LEFT (ic)->operand.symOperand =
-       IC_RIGHT (dic)->operand.symOperand;
-      IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+      OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
+      IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
       remiCodeFromeBBlock (ebp, dic);
       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
       change++;
@@ -1896,13 +1880,15 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 
   /* only upto 2 bytes since we cannot predict
      the usage of b, & acc */
-  if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2) &&
-      ic->op != RETURN &&
+  if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
+    return NULL;
+
+  if (ic->op != RETURN &&
       ic->op != SEND &&
       !POINTER_SET (ic) &&
       !POINTER_GET (ic))
     return NULL;
-
+  
   /* this routine will mark the a symbol as used in one 
      instruction use only && if the defintion is local 
      (ie. within the basic block) && has only one definition &&
@@ -1924,6 +1910,16 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
                         bitVectFirstBit (OP_DEFS (op)))))
     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;
+    }
+  }
+
   /* found the definition now check if it is local */
   if (dic->seq < ebp->fSeq ||
       dic->seq > ebp->lSeq)
@@ -2151,6 +2147,10 @@ packRegsForAccUse (iCode * ic)
       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
     return;
 
+#if 0
+  // this is too dangerous and need further restrictions
+  // see bug #447547
+
   /* if one of them is a literal then we can */
   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
@@ -2158,6 +2158,7 @@ packRegsForAccUse (iCode * ic)
       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
       return;
     }
+#endif
 
   /* if the other one is not on stack then we can */
   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
@@ -2265,7 +2266,7 @@ packRegisters (eBBlock * ebp)
 
   for (ic = ebp->sch; ic; ic = ic->next)
     {
-      /* if this is an itemp & result of a address of a true sym 
+      /* if this is an itemp & result of an address of a true sym 
          then mark this as rematerialisable   */
       if (ic->op == ADDRESS_OF &&
          IS_ITEMP (IC_RESULT (ic)) &&
@@ -2340,20 +2341,6 @@ packRegisters (eBBlock * ebp)
            }
        }
 
-#if 0
-      /* if the condition of an if instruction
-         is defined in the previous instruction then
-         mark the itemp as a conditional */
-      if ((IS_CONDITIONAL (ic) ||
-          (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
-         ic->next && ic->next->op == IFX &&
-         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;
-       }
-#else
       /* if the condition of an if instruction
          is defined in the previous instruction and
         this is the only usage then
@@ -2368,7 +2355,6 @@ packRegisters (eBBlock * ebp)
          OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
          continue;
        }
-#endif
 
       /* reduce for support function calls */
       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
@@ -2479,6 +2465,7 @@ packRegisters (eBBlock * ebp)
          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 == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
@@ -2501,12 +2488,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
 
   setToNull ((void *) &_G.funcrUsed);
   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-  /* if not register extentions then reduce number
-     of registers */
-  if (options.regExtend)
-    mcs51_nRegs = 13;
-  else
-    mcs51_nRegs = 8;
+  mcs51_nRegs = 8;
 
   /* change assignments this will remove some
      live ranges reducing some register pressure */
@@ -2557,7 +2539,6 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   /* now get back the chain */
   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
 
-
   gen51Code (ic);
 
   /* free up any _G.stackSpil locations allocated */