fixed an integral promotion bug
[fw/sdcc] / src / ds390 / ralloc.c
index 527ffeb81fe9271031efea44ec6dc4b906d862d8..d731417dbf76deb8ffa770e67a6310d8825db95a 100644 (file)
@@ -537,6 +537,7 @@ createStackSpil (symbol * sym)
   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`
      onto the external stack since : so we
@@ -1365,7 +1366,7 @@ static void fillGaps()
                sym->regs[i] = getRegGprNoSpil ();                
        }
 
-       /* for all its definitions check if the registers
+       /* for all its definitions & uses check if the registers
           allocated needs positioning NOTE: we can position
           only ONCE if more than One positioning required 
           then give up */
@@ -1388,10 +1389,25 @@ static void fillGaps()
                if (pdone > 1) break;
            }
        }
+               for (i = 0 ; i < sym->uses->size ; i++ ) {
+           if (bitVectBitValue(sym->uses,i)) {
+               iCode *ic;
+               if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+               if (SKIP_IC(ic)) continue;
+               if (!IS_ASSIGN_ICODE(ic)) continue ;
+
+               /* if result is assigned to registers */
+               if (IS_SYMOP(IC_RESULT(ic)) && 
+                   bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+                   pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
+               }
+               if (pdone > 1) break;
+           }
+       }
        /* had to position more than once GIVE UP */
        if (pdone > 1) {
            /* UNDO all the changes we made to try this */
-           sym->isspilt = 0;
+           sym->isspilt = 1;
            for (i=0; i < sym->nRegs ; i++ ) {
                sym->regs[i] = NULL;
            }
@@ -2007,8 +2023,9 @@ findAssignToSym (operand * op, iCode * ic)
 /*-----------------------------------------------------------------*/
 static int
 packRegsForSupport (iCode * ic, eBBlock * ebp)
-{
+{    
   int change = 0;
+  
   /* for the left & right operand :- look to see if the
      left was assigned a true symbol in far space in that
      case replace them */
@@ -2023,11 +2040,14 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
 
       /* found it we need to remove it from the
          block */
-      for (sic = dic; sic != ic; sic = sic->next)
+      for (sic = dic; sic != ic; sic = sic->next) {
        bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
+       sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
+      }
 
       IC_LEFT (ic)->operand.symOperand =
        IC_RIGHT (dic)->operand.symOperand;
+      OP_SYMBOL(IC_LEFT(ic))->liveTo = ic->seq;
       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
       remiCodeFromeBBlock (ebp, dic);
@@ -2057,13 +2077,15 @@ right:
        }
       /* found it we need to remove it from the
          block */
-      for (sic = dic; sic != ic; sic = sic->next)
+      for (sic = dic; sic != ic; sic = sic->next) {
        bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
+       sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
+      }
 
       IC_RIGHT (ic)->operand.symOperand =
        IC_RIGHT (dic)->operand.symOperand;
       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
-
+      OP_SYMBOL(IC_RIGHT(ic))->liveTo = ic->seq;
       remiCodeFromeBBlock (ebp, dic);
       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
@@ -2121,9 +2143,8 @@ packRegsDPTRuse (operand * op)
            if (OP_SYMBOL(IC_RESULT(ic))->liveTo == 
                OP_SYMBOL(IC_RESULT(ic))->liveFrom) continue ;
            etype = getSpec(type = operandType(IC_RESULT(ic)));
-           //if (getSize(type) == 0 || isOperandEqual(op,IC_RESULT(ic))) 
-           if (getSize(type) == 0) 
-             continue ;
+           if (getSize(type) == 0 || isOperandEqual(op,IC_RESULT(ic))) 
+               continue ;
            return NULL ;
        }
 
@@ -2142,10 +2163,20 @@ packRegsDPTRuse (operand * op)
        if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op) &&
            getSize(operandType(IC_RESULT(ic))) > 1 ) return NULL;
 
-       /* conditionals can destroy 'b' - make sure B wont be used in this one*/
-       if ((IS_CONDITIONAL(ic) || ic->op == '*' || ic->op == '/' ) && 
+       /* conditionals can destroy 'b' - make sure B wont 
+          be used in this one*/
+       if ((IS_CONDITIONAL(ic) || ic->op == '*' || ic->op == '/'  || 
+            ic->op == LEFT_OP || ic->op == RIGHT_OP ) && 
            getSize(operandType(op)) > 3) return NULL;
 
+       /* if this is a cast to a bigger type */
+       if (ic->op==CAST) {
+         if (getSize(OP_SYM_TYPE(IC_RESULT(ic))) >
+             getSize(OP_SYM_TYPE(IC_RIGHT(ic)))) {
+           return 0;
+         }
+       }
+
        /* general case */
        if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && 
            !isOperandEqual(IC_RESULT(ic),op) &&
@@ -2155,7 +2186,7 @@ packRegsDPTRuse (operand * op)
 
        if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && 
            !isOperandEqual(IC_RIGHT(ic),op) &&
-           (OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->seq || 
+           (OP_SYMBOL(IC_RIGHT(ic))->liveTo >= ic->seq || 
             IS_TRUE_SYMOP(IC_RIGHT(ic))               ||
             OP_SYMBOL(IC_RIGHT(ic))->ruonly) &&
            ((isOperandInFarSpace(IC_RIGHT(ic)) && !isOperandInReg(IC_RIGHT(ic)))|| 
@@ -2221,6 +2252,17 @@ packRegsForAccUse (iCode * ic)
     return;
   }
 
+  /* if we are calling a reentrant function that has stack parameters */
+  if (ic->op == CALL &&
+       IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
+       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
+      return;
+
+  if (ic->op == PCALL &&
+       IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
+       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
+      return;
+
   /* if + or - then it has to be one byte result */
   if ((ic->op == '+' || ic->op == '-')
       && getSize (operandType (IC_RESULT (ic))) > 1)
@@ -2585,8 +2627,12 @@ packRegisters (eBBlock * ebp)
          packRegsDPTRuse (IC_LEFT (ic));
       }
 
-      if ((ic->op == CALL && getSize(operandType(IC_RESULT(ic))) <= 4)) {
-         packRegsDPTRuse (IC_RESULT (ic));       
+      if (ic->op == CALL) {
+         sym_link *ftype = operandType(IC_LEFT(ic));
+         if (getSize(operandType(IC_RESULT(ic))) <= 4 &&
+             !IFFUNC_ISBUILTIN(ftype)) {
+             packRegsDPTRuse (IC_RESULT (ic));   
+         }
       }
 
       /* if pointer set & left has a size more than