* src/mcs51/gen.c (genFunction): optimize RECEIVE in reentrant
[fw/sdcc] / src / ds390 / ralloc.c
index 9cbdf64cc8e8ea9f272226fe2dc56e67758bf947..3743e964dcf776f0369cdb7aa3971d007aa844e4 100644 (file)
@@ -77,7 +77,13 @@ regs regs390[] =
   {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 0, 0},
   {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 0, 0},
   {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 0, 0},
-  {REG_CND, CND_IDX, REG_GPR, "C", "C", "xreg", 0, 0, 0},
+  {REG_CND, CND_IDX, REG_GPR, "C", "psw", "xreg", 0, 0, 0},
+  {0, DPL1_IDX, 0, "dpl1", "dpl1", "dpl1", 0, 0, 0},
+  {0, DPH1_IDX, 0, "dph1", "dph1", "dph1", 0, 0, 0},
+  {0, DPX1_IDX, 0, "dpx1", "dpx1", "dpx1", 0, 0, 0},
+  {0, DPS_IDX, 0, "dps", "dps", "dps", 0, 0, 0},
+  {0, A_IDX, 0, "a", "acc", "acc", 0, 0, 0},
+  {0, AP_IDX, 0, "ap", "ap", "ap", 0, 0, 0},
 };
 int ds390_nRegs = 13;
 static void spillThis (symbol *);
@@ -130,7 +136,7 @@ ds390_regWithIdx (int idx)
 {
   int i;
 
-  for (i = 0; i < ds390_nRegs; i++)
+  for (i = 0; i < sizeof(regs390)/sizeof(regs); i++)
     if (regs390[i].rIdx == idx)
       return &regs390[i];
 
@@ -802,6 +808,7 @@ static regs *
 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
 tryAgain:
   /* try for a ptr type */
@@ -816,6 +823,11 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
+  /* 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;
@@ -828,6 +840,7 @@ static regs *
 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
 tryAgain:
   /* try for gpr type */
@@ -842,6 +855,11 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
+  /* 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;
@@ -1198,6 +1216,31 @@ void reassignUnusedLRs (bitVect *unused)
     }
 }
 
+/*------------------------------------------------------------------*/
+/* 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  */
 /*-----------------------------------------------------------------*/
@@ -1367,6 +1410,40 @@ serialRegAssign (eBBlock ** ebbs, int count)
        }
       reassignUnusedLRs(unusedLRs);
     }
+
+    /* 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);
+          }
+      }    
+    
 }
 
 /*-----------------------------------------------------------------*/
@@ -1671,7 +1748,7 @@ createRegMask (eBBlock ** ebbs, int count)
                          "createRegMask cannot find live range");
                  exit (0);
                }
-             
+#if 0
              /* special case for ruonly */
              if (sym->ruonly && sym->liveFrom != sym->liveTo) {
                  int size = getSize(sym->type);
@@ -1680,6 +1757,7 @@ createRegMask (eBBlock ** ebbs, int count)
                      ic->rMask = bitVectSetBit (ic->rMask, j++);
                  continue ;
              }
+#endif
              /* if no register assigned to it */
              if (!sym->nRegs || sym->isspilt)
                continue;
@@ -2835,23 +2913,31 @@ packRegisters (eBBlock * ebp)
        {
          /* if we are using a symbol on the stack
             then we should say ds390_ptrRegReq */
+         if (options.useXstack && ic->parmPush
+             && (ic->op == IPUSH || ic->op == IPOP))
+           ds390_ptrRegReq++;
          if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
                  ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ? !options.stack10bit : 0) +
-                                     OP_SYMBOL (IC_COND (ic))->iaccess);
+                                     OP_SYMBOL (IC_COND (ic))->iaccess +
+                                     (SPEC_OCLS(OP_SYMBOL (IC_COND (ic))->etype) == idata));
          else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
                  ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ? !options.stack10bit : 0) +
-                                     OP_SYMBOL (IC_JTCOND (ic))->iaccess);
+                                     OP_SYMBOL (IC_JTCOND (ic))->iaccess +
+                                     (SPEC_OCLS(OP_SYMBOL (IC_JTCOND (ic))->etype) == idata));
          else
            {
              if (IS_SYMOP (IC_LEFT (ic)))
                      ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ? !options.stack10bit : 0) +
-                                         OP_SYMBOL (IC_LEFT (ic))->iaccess);
+                                         OP_SYMBOL (IC_LEFT (ic))->iaccess +
+                                         (SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata));
              if (IS_SYMOP (IC_RIGHT (ic)))
                      ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ? !options.stack10bit : 0) +
-                                         OP_SYMBOL (IC_RIGHT (ic))->iaccess);
+                                         OP_SYMBOL (IC_RIGHT (ic))->iaccess +
+                                         (SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata));
              if (IS_SYMOP (IC_RESULT (ic)))
                      ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ? !options.stack10bit : 0) +
-                                         OP_SYMBOL (IC_RESULT (ic))->iaccess);
+                                         OP_SYMBOL (IC_RESULT (ic))->iaccess +
+                                         (SPEC_OCLS(OP_SYMBOL (IC_RESULT (ic))->etype) == idata));
            }
        }
 
@@ -3025,6 +3111,10 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
   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);
 
@@ -3063,6 +3153,14 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
   if (currFunc)
     redoStackOffsets ();
 
+  /* make sure r0 & r1 are flagged as used if they might be used */
+  /* as pointers */
+  if (currFunc && ds390_ptrRegReq)
+    {
+      currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R0_IDX);
+      currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R1_IDX);
+    }
+    
   if (options.dump_rassgn) {
     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
     dumpLiveRanges (DUMP_LRANGE, liveRanges);