For 296a
[fw/sdcc] / src / ds390 / ralloc.c
index 871e761ff8a1070b4c8d7c7fd3c10a1690d61e70..40bc1c86b7ed9ce886eede19061e7ea99fb1d40e 100644 (file)
@@ -380,15 +380,18 @@ noOverLap (set * itmpStack, symbol * fsym)
 {
   symbol *sym;
 
-
   for (sym = setFirstItem (itmpStack); sym;
        sym = setNextItem (itmpStack))
     {
-      if (sym->liveTo > fsym->liveFrom)
-       return 0;
-
+            // if sym starts before (or on) our end point
+            // and ends after (or on) our start point, 
+            // it is an overlap.
+           if (sym->liveFrom <= fsym->liveTo &&
+               sym->liveTo   >= fsym->liveFrom)
+           {
+               return 0;
+           }
     }
-
   return 1;
 }
 
@@ -505,7 +508,11 @@ createStackSpil (symbol * sym)
   /* set the type to the spilling symbol */
   sloc->type = copyLinkChain (sym->type);
   sloc->etype = getSpec (sloc->type);
-  SPEC_SCLS (sloc->etype) = options.model ? S_XDATA : S_DATA;
+  if (options.model == MODEL_SMALL) {
+    SPEC_SCLS (sloc->etype) = S_DATA;
+  } else {
+    SPEC_SCLS (sloc->etype) = S_XDATA;
+  }
   SPEC_EXTR (sloc->etype) = 0;
 
   /* we don't allow it to be allocated`
@@ -610,7 +617,7 @@ spillThis (symbol * sym)
      LIVE ranges */
   if (!ds390_ptrRegReq && isSpiltOnStack (sym))
     {
-      ds390_ptrRegReq++;
+      ds390_ptrRegReq += !options.stack10bit;
       spillLRWithPtrReg (sym);
     }
 
@@ -753,9 +760,9 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
 
   /* if spilt on stack then free up r0 & r1 
      if they could have been assigned to as gprs */
-  if (!ds390_ptrRegReq && isSpiltOnStack (ssym))
+  if (!ds390_ptrRegReq && isSpiltOnStack (ssym) && !options.stack10bit)
     {
-      ds390_ptrRegReq++;
+           ds390_ptrRegReq++;
       spillLRWithPtrReg (ssym);
     }
 
@@ -1149,19 +1156,21 @@ serialRegAssign (eBBlock ** ebbs, int count)
 
              /* if it has a spillocation & is used less than
                 all other live ranges then spill this */
-             if (willCS && sym->usl.spillLoc)
-               {
-
-                 symbol *leastUsed =
-                 leastUsedLR (liveRangesWith (spillable,
-                                              allLRs,
-                                              ebbs[i],
-                                              ic));
-                 if (leastUsed &&
-                     leastUsed->used > sym->used)
-                   {
-                     spillThis (sym);
-                     continue;
+               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)) {
+                           spillThis (sym);
+                           continue;
+                       }
                    }
                }
 
@@ -1432,6 +1441,7 @@ regTypeNum ()
              (ic = hTabItemWithKey (iCodehTab,
                                     bitVectFirstBit (sym->defs))) &&
              POINTER_GET (ic) &&
+             !sym->noSpilLoc &&
              !IS_BITVAR (sym->etype))
            {
 
@@ -1614,24 +1624,12 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
      we cannot */
   for (dic = ic->prev; dic; dic = dic->prev)
     {
-#if 0 // jwk 20010410, the JanVanBelle case
-      /* 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;
@@ -1747,9 +1745,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 */
@@ -1899,13 +1897,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)) > (fReturnSizeDS390 - 2) &&
-      ic->op != RETURN &&
+  if (getSize (operandType (op)) > (fReturnSizeDS390 - 2))
+    return 0;
+
+  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 &&
@@ -1927,6 +1927,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)
@@ -2021,7 +2031,7 @@ static bool
 isBitwiseOptimizable (iCode * ic)
 {
   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
-  // jwk sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
+  sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
 
   /* bitwise operations are considered optimizable
      under the following conditions (Jean-Louis VERN) 
@@ -2148,6 +2158,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))))
@@ -2155,6 +2169,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 &&
@@ -2205,10 +2220,22 @@ packForPush (iCode * ic, eBBlock * ebp)
   /* make sure the right side does not have any definitions
      inbetween */
   dbv = OP_DEFS(IC_RIGHT(dic));
-  for (lic = ic; lic != dic ; lic = lic->prev) {
+  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 (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 */
   IC_LEFT (ic) = IC_RIGHT (dic);
@@ -2310,22 +2337,22 @@ packRegisters (eBBlock * ebp)
          /* if we are using a symbol on the stack
             then we should say ds390_ptrRegReq */
          if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
-           ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
-                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
+                 ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ? !options.stack10bit : 0) +
+                                     OP_SYMBOL (IC_COND (ic))->iaccess);
          else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
-           ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
-                             OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
+                 ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ? !options.stack10bit : 0) +
+                                     OP_SYMBOL (IC_JTCOND (ic))->iaccess);
          else
            {
              if (IS_SYMOP (IC_LEFT (ic)))
-               ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
-                               OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
+                     ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ? !options.stack10bit : 0) +
+                                         OP_SYMBOL (IC_LEFT (ic))->iaccess);
              if (IS_SYMOP (IC_RIGHT (ic)))
-               ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
-                              OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
+                     ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ? !options.stack10bit : 0) +
+                                         OP_SYMBOL (IC_RIGHT (ic))->iaccess);
              if (IS_SYMOP (IC_RESULT (ic)))
-               ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
-                             OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
+                     ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ? !options.stack10bit : 0) +
+                                         OP_SYMBOL (IC_RESULT (ic))->iaccess);
            }
        }
 
@@ -2426,7 +2453,7 @@ packRegisters (eBBlock * ebp)
 
              /* if the type from and type to are the same
                 then if this is the only use then packit */
-             if (checkType (operandType (IC_RIGHT (ic)),
+             if (compareType (operandType (IC_RIGHT (ic)),
                             operandType (IC_LEFT (ic))) == 1)
                {
                  iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
@@ -2463,11 +2490,10 @@ 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)))
          ) &&
          IS_ITEMP (IC_RESULT (ic)) &&
          getSize (operandType (IC_RESULT (ic))) <= 2)
@@ -2488,20 +2514,15 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
 
   setToNull ((void *) &_G.funcrUsed);
   ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-  /* if not register extentions then reduce number
-     of registers */
-  if (options.regExtend)
-    ds390_nRegs = 13;
-  else
-    ds390_nRegs = 8;
-
+  ds390_nRegs = 8;
+  if (options.model != MODEL_FLAT24) options.stack10bit = 0;
   /* change assignments this will remove some
      live ranges reducing some register pressure */
   for (i = 0; i < count; i++)
     packRegisters (ebbs[i]);
 
   if (options.dump_pack)
-    dumpEbbsToFileExt (".dumppack", ebbs, count);
+    dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
 
   /* first determine for each live range the number of 
      registers & the type of registers required for each */
@@ -2533,7 +2554,7 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
   redoStackOffsets ();
 
   if (options.dump_rassgn)
-    dumpEbbsToFileExt (".dumprassgn", ebbs, count);
+    dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
 
   /* do the overlaysegment stuff SDCCmem.c */
   doOverlays (ebbs, count);