* src/avr/ralloc.c (serialRegAssign),
[fw/sdcc] / src / hc08 / ralloc.c
index f70c369b36420e7232c2d8ee5d43ac937fa667e2..25c75138bf9ab286e144dae5ad27ef3e0e5b2d7e 100644 (file)
@@ -61,21 +61,23 @@ int hc08_ptrRegReq;         /* one byte pointer register required */
 regs regshc08[] =
 {
 
-  {REG_GPR, A_IDX, REG_GPR, "a", "a", "0", 1, NULL, 0, 1},
-  {REG_GPR, X_IDX, REG_GPR, "x", "x", "0", 2, NULL, 0, 1},
-  {REG_GPR, H_IDX, REG_GPR, "h", "h", "0", 4, NULL, 0, 1},
-  {REG_PTR, HX_IDX, REG_PTR, "hx", "hx", "0", 6, NULL, 0, 1},
-  {REG_GPR, XA_IDX, REG_GPR, "xa", "xa", "0", 3, NULL, 0, 1},
-
-  {REG_CND, CND_IDX, REG_CND, "C", "C", "xreg", 0, NULL, 0, 1},
+  {REG_GPR, A_IDX,   "a",  1, NULL, 0, 1},
+  {REG_GPR, X_IDX,   "x",  2, NULL, 0, 1},
+  {REG_GPR, H_IDX,   "h",  4, NULL, 0, 1},
+  {REG_PTR, HX_IDX,  "hx", 6, NULL, 0, 1},
+  {REG_GPR, XA_IDX,  "xa", 3, NULL, 0, 1},
+
+  {REG_CND, CND_IDX, "C",  0, NULL, 0, 1},
+  {0,       SP_IDX,  "sp", 0, NULL, 0, 1},
 };
-int hc08_nRegs = 6;
+int hc08_nRegs = 7;
 
 regs *hc08_reg_a;
 regs *hc08_reg_x;
 regs *hc08_reg_h;
 regs *hc08_reg_hx;
 regs *hc08_reg_xa;
+regs *hc08_reg_sp;
 
 static void spillThis (symbol *);
 static void freeAllRegs ();
@@ -434,7 +436,7 @@ leastUsedLR (set * sset)
 
     }
 
-  setToNull ((void **) &sset);
+  setToNull ((void *) &sset);
   sym->blockSpil = 0;
   return sym;
 }
@@ -1169,6 +1171,32 @@ xchgPositions:
   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  */
 /*-----------------------------------------------------------------*/
@@ -1261,6 +1289,16 @@ serialRegAssign (eBBlock ** ebbs, int count)
                    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) {
@@ -1329,6 +1367,40 @@ serialRegAssign (eBBlock ** ebbs, int count)
            }
        }
     }
+
+    /* 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);
+          }
+      }    
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -1596,7 +1668,6 @@ rematStr (symbol * sym)
   
   while (1)
     {
-
       /* if plus or minus print the right hand side */
       if (ic->op == '+' || ic->op == '-')
        {
@@ -1606,6 +1677,7 @@ rematStr (symbol * sym)
          ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
          continue;
        }
+
 /*      
       if (ic->op == '+')
         {
@@ -1626,7 +1698,10 @@ rematStr (symbol * sym)
          continue;
       }
       /* we reached the end */
-      sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+      if (ic->op == ADDRESS_OF)
+        sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+      else if (ic->op == '=')
+        sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
       break;
     }
 
@@ -1676,34 +1751,13 @@ regTypeNum (eBBlock *ebbs)
              (ic = hTabItemWithKey (iCodehTab,
                                     bitVectFirstBit (sym->defs))) &&
              POINTER_GET (ic) &&
-             !sym->noSpilLoc &&
-             !IS_BITVAR (sym->etype))
+             !IS_BITVAR (sym->etype) &&
+             (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
            {
 
-
-             /* and that pointer is remat in data space */
-             if (IS_SYMOP (IC_LEFT (ic)) &&
-                 OP_SYMBOL (IC_LEFT (ic))->remat &&
-                 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
-                 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
+             if (ptrPseudoSymSafe (sym, ic))
                {
-                 /* 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='=';
-                 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
-                 IC_LEFT(ic)=NULL;
-#endif
+                 ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
                  continue;
                }
 
@@ -1838,6 +1892,43 @@ farSpacePackable (iCode * ic)
 }
 #endif
 
+#if 0
+static void
+packRegsForLiteral (iCode * ic)
+{
+  int k;
+  iCode *uic;
+  
+  if (ic->op != '=')
+    return;
+  if (POINTER_SET (ic))
+    return;
+  if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
+    return;
+  if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
+    return;
+
+  for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
+    if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
+      {
+        uic = hTabItemWithKey (iCodehTab, k);
+        if (!uic) continue;
+        
+        if (uic->op != IFX && uic->op != JUMPTABLE)
+         {
+           if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
+             ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
+           if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
+             ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
+           if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
+             ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
+         }
+      }
+
+}
+#endif
+
+
 /*-----------------------------------------------------------------*/
 /* packRegsForAssign - register reduction for assignment           */
 /*-----------------------------------------------------------------*/
@@ -1987,6 +2078,7 @@ pack:
   return 1;
 }
 
+
 /*------------------------------------------------------------------*/
 /* findAssignToSym : scanning backwards looks for first assig found */
 /*------------------------------------------------------------------*/
@@ -2124,6 +2216,7 @@ static int
 packRegsForSupport (iCode * ic, eBBlock * ebp)
 {
   iCode *dic;
+  int changes = 0;
   
   /* for the left & right operand :- look to see if the
      left was assigned a true symbol in far space in that
@@ -2138,7 +2231,7 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
        {
          /* found it we need to remove it from the block */
          reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
-         return 1;
+         changes++;
        }
     }
 
@@ -2150,25 +2243,13 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
 
       if (dic)
        {
-         /* if this is a subtraction & the result
-            is a true symbol in far space then don't pack */
-#if 0
-         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;
-           }
-#endif
-         /* found it we need to remove it from the
-            block */
+         /* found it we need to remove it from the block */
          reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
-         
-         return 1;
+         changes++;
        }
     }
 
-  return 0;
+  return changes;
 }
 
 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
@@ -2502,7 +2583,10 @@ packRegsForAccUse (iCode * ic)
       !IS_BITWISE_OP (uic) &&
       (uic->op != LEFT_OP) &&
       (uic->op != RIGHT_OP) &&
-      (uic->op != GETHBIT))
+      (uic->op != GETHBIT) &&
+      (uic->op != RETURN) &&
+      (uic->op != '~') &&
+      (uic->op != '!'))
     return;
 
 #if 0
@@ -2682,10 +2766,12 @@ packRegisters (eBBlock ** ebpp, int blockno)
 
   for (ic = ebp->sch; ic; ic = ic->next)
     {
+      //packRegsForLiteral (ic);
+      
       /* 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)) &&
+         IS_ITEMP (IC_RESULT (ic)) && 
          IS_TRUE_SYMOP (IC_LEFT (ic)) &&
          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
          !OP_SYMBOL (IC_LEFT (ic))->onStack )
@@ -2696,7 +2782,20 @@ packRegisters (eBBlock ** ebpp, int blockno)
          OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
 
        }
+#if 1
+      if (ic->op == '=' &&
+          !POINTER_SET (ic) &&
+         IS_ITEMP (IC_RESULT (ic)) &&
+         IS_VALOP (IC_RIGHT (ic)) &&
+         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;
 
+       }
+#endif
       /* if straight assignment then carry remat flag if
          this is the only definition */
       if (ic->op == '=' &&
@@ -2793,7 +2892,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
        }
 
       /* reduce for support function calls */
-      if (ic->supportRtn || ic->op == '+' || ic->op == '-')
+      if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
        packRegsForSupport (ic, ebp);
 
       #if 0
@@ -2905,9 +3004,12 @@ packRegisters (eBBlock ** ebpp, int blockno)
           || IS_CONDITIONAL(ic)
           || IS_BITWISE_OP (ic)
           || ic->op == '='
+           || ic->op == '!'
+           || ic->op == '~'
           || ic->op == GETHBIT
           || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
           || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
+           || ic->op == RECEIVE
          ) &&
          IS_ITEMP (IC_RESULT (ic)) &&
          getSize (operandType (IC_RESULT (ic))) <= 1)
@@ -2930,18 +3032,24 @@ hc08_assignRegisters (eBBlock ** ebbs, int count)
   setToNull ((void *) &_G.regAssigned);
   setToNull ((void *) &_G.totRegAssigned);
   hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-  hc08_nRegs = 5;
+  hc08_nRegs = 7;
   hc08_reg_a = hc08_regWithIdx(A_IDX);
   hc08_reg_x = hc08_regWithIdx(X_IDX);
   hc08_reg_h = hc08_regWithIdx(H_IDX);
   hc08_reg_hx = hc08_regWithIdx(HX_IDX);
   hc08_reg_xa = hc08_regWithIdx(XA_IDX);
+  hc08_reg_sp = hc08_regWithIdx(SP_IDX);
+  hc08_nRegs = 5;
 
   /* change assignments this will remove some
      live ranges reducing some register pressure */
   for (i = 0; i < count; i++)
     packRegisters (ebbs, i);
 
+  /* liveranges probably changed by register packing
+     so we compute them again */
+  recomputeLiveRanges (ebbs, count);
+  
   if (options.dump_pack)
     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);