fix segfault on casting int to pointer
[fw/sdcc] / src / mcs51 / ralloc.c
index 2ae154ab80cf6b6b565f92f8bfbb4dad1f90b33f..09fd032dfcc3b2d7ef83d7ee2ab34bc5b3d5a684 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "common.h"
 #include "ralloc.h"
+#include "gen.h"
 
 /*-----------------------------------------------------------------*/
 /* At this point we start getting processor specific although      */
@@ -271,7 +272,7 @@ static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
 static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
 {
     return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
-           allDefsOutOfRange (sym->defs,ic->seq,ebp->lSeq));
+           allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
 }
 
 /*-----------------------------------------------------------------*/
@@ -440,7 +441,8 @@ static symbol *createStackSpil (symbol *sym)
 {
     symbol *sloc= NULL;
     int useXstack, model, noOverlay;
-    int stackAuto;
+
+    char slocBuffer[30];
 
     /* first go try and find a free one that is already 
        existing on the stack */
@@ -457,13 +459,19 @@ static symbol *createStackSpil (symbol *sym)
        we need to allocate this on the stack : this is really a
        hack!! but cannot think of anything better at this time */
        
-    sprintf(buffer,"sloc%d",_G.slocNum++);
-    sloc = newiTemp(buffer);
+    if (sprintf(slocBuffer,"sloc%d",_G.slocNum++) >= sizeof(slocBuffer))
+    {
+       fprintf(stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
+               __FILE__, __LINE__);
+       exit(1);        
+    }
+
+    sloc = newiTemp(slocBuffer);
 
     /* set the type to the spilling symbol */
     sloc->type = copyLinkChain(sym->type);
     sloc->etype = getSpec(sloc->type);
-    SPEC_SCLS(sloc->etype) = S_AUTO ;    
+    SPEC_SCLS(sloc->etype) = S_DATA ;
     SPEC_EXTR(sloc->etype) = 0;
 
     /* we don't allow it to be allocated`
@@ -471,22 +479,19 @@ static symbol *createStackSpil (symbol *sym)
        temporarily turn it off ; we also
        turn off memory model to prevent
        the spil from going to the external storage
-       and turn off overlaying 
     */
     
     useXstack = options.useXstack;
     model = options.model;
-    noOverlay = options.noOverlay;
-    stackAuto = options.stackAuto;
-    options.noOverlay = 1;
+/*     noOverlay = options.noOverlay; */
+/*     options.noOverlay = 1; */
     options.model = options.useXstack = 0;
 
     allocLocal(sloc);
 
     options.useXstack = useXstack;
     options.model     = model;
-    options.noOverlay = noOverlay;
-    options.stackAuto = stackAuto;
+/*     options.noOverlay = noOverlay; */
     sloc->isref = 1; /* to prevent compiler warning */
     
     /* if it is on the stack then update the stack */
@@ -603,8 +608,8 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
        return sym;
     }
 
-    /* if the symbol is local to the block then */        
-    if (forSym->liveTo < ebp->lSeq ) {       
+    /* if the symbol is local to the block then */
+    if (forSym->liveTo < ebp->lSeq) {       
 
        /* check if there are any live ranges allocated
           to registers that are not used in this block */
@@ -622,11 +627,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
           used in the remainder of the block */
        if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
            sym = leastUsedLR (selectS);
-           if (!sym->remat) {
-               sym->remainSpil = 1;
-               _G.blockSpil++;
+           if (sym != forSym) {
+               if (!sym->remat) {
+                   sym->remainSpil = 1;
+                   _G.blockSpil++;
+               }
+               return sym;
            }
-           return sym;
        }
     }   
 
@@ -731,7 +738,7 @@ static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
 /*-----------------------------------------------------------------*/
 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
 /*-----------------------------------------------------------------*/
-regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
+static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
 {
     regs *reg;
 
@@ -768,7 +775,7 @@ static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
     if (!mcs51_ptrRegReq)
        if ((reg = allocReg(REG_PTR)))
            return reg ;
-
+       
     /* we have to spil */
     if (!spilSomething (ic,ebp,sym))
        return NULL ;
@@ -863,7 +870,7 @@ static void deassignLRs (iCode *ic, eBBlock *ebp)
                  sym->nRegs) >= result->nRegs)
                ) {
                
-               for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
+               for (i = 0 ; i < result->nRegs ; i++)
                    if (i < sym->nRegs )
                        result->regs[i] = sym->regs[i] ;
                    else
@@ -1069,7 +1076,10 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                
                /* if we need ptr regs for the right side
                   then mark it */
-               if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) {
+               if (POINTER_GET(ic) && IS_SYMOP(IC_LEFT(ic)) 
+                && getSize(OP_SYMBOL(IC_LEFT(ic))->type) 
+                   <= PTRSIZE) 
+               {
                    mcs51_ptrRegReq++;
                    ptrRegSet = 1;
                }
@@ -1095,7 +1105,7 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                                     OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
                /* do the same for the right operand */
                if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
-                   OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=')
+                   OP_SYMBOL(IC_RIGHT(ic))->nRegs)
                        positionRegs(OP_SYMBOL(IC_RESULT(ic)),
                                     OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
                
@@ -1131,7 +1141,7 @@ static bitVect *rUmaskForOp (operand *op)
 
     rumask = newBitVect(mcs51_nRegs);
 
-    for (j = 0; j < sym->nRegs; j++) {
+    for (j = 0; j < sym->nRegs; j++) { 
        rumask = bitVectSetBit(rumask,
                               sym->regs[j]->rIdx);
     }
@@ -1451,15 +1461,16 @@ static iCode *farSpacePackable (iCode *ic)
 /*-----------------------------------------------------------------*/
 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
 {
-    iCode *dic, *sic;
-    
-    if (
-/*     !IS_TRUE_SYMOP(IC_RESULT(ic)) ||            */
-       !IS_ITEMP(IC_RIGHT(ic))       ||        
+       iCode *dic, *sic;
+       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 ||
-       OP_SYMBOL(IC_RIGHT(ic))->isind)
+       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 (isOperandInFarSpace(IC_RESULT(ic))) {
@@ -1485,7 +1496,13 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp)
 
        if (SKIP_IC2(dic))
            continue;
-       
+
+       if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
+           IS_OP_VOLATILE(IC_RESULT(dic))) {
+               dic = NULL;
+               break;
+       }
+
        if (IS_SYMOP(IC_RESULT(dic)) &&
            IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
            if (POINTER_SET(dic))
@@ -1517,7 +1534,12 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp)
     
     if (!dic)
        return 0 ; /* did not find */
-           
+       
+    /* if assignment then check that right is not a bit */
+    if (ASSIGNMENT(dic) && !POINTER_SET(dic)) {
+           link *etype = operandType(IC_RIGHT(dic));
+           if (IS_BITFIELD(etype)) return 0;
+    }
     /* if the result is on stack or iaccess then it must be
        the same atleast one of the operands */
     if (OP_SYMBOL(IC_RESULT(ic))->onStack  || 
@@ -1534,7 +1556,7 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp)
              (IC_RIGHT(dic) &&
               IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
            return 0;                
-    }
+    }    
 pack:
     /* found the definition */
     /* replace the result with the result of */
@@ -1554,6 +1576,8 @@ pack:
     }
         
     remiCodeFromeBBlock(ebp,ic);
+    hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
+    OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
     return 1;
     
 }
@@ -1655,7 +1679,8 @@ static int packRegsForSupport (iCode *ic, eBBlock *ebp)
        IC_LEFT(ic)->operand.symOperand =
            IC_RIGHT(dic)->operand.symOperand;
        IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
-       remiCodeFromeBBlock(ebp,dic);   
+       remiCodeFromeBBlock(ebp,dic);
+       hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
        change++;      
     }
     
@@ -1687,6 +1712,7 @@ static int packRegsForSupport (iCode *ic, eBBlock *ebp)
        IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
        
        remiCodeFromeBBlock(ebp,dic);
+       hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
        change ++;
     }
    
@@ -1710,9 +1736,11 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
     
     /* only upto 2 bytes since we cannot predict
        the usage of b, & acc */
-    if (getSize(operandType(op)) > 2 && 
+    if (getSize(operandType(op)) >  (fReturnSize - 2) &&
        ic->op != RETURN             &&
-       ic->op != SEND)
+       ic->op != SEND               &&
+       !POINTER_SET(ic)             &&
+       !POINTER_GET(ic))
        return NULL;
 
     /* this routine will mark the a symbol as used in one 
@@ -1775,7 +1803,7 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
 
     /* also make sure the intervenening instructions
        don't have any thing in far space */
-    for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
+    for (dic = dic->next ; dic && dic != ic && sic != ic; dic = dic->next) {
                
        /* if there is an intervening function call then no */
        if (dic->op == CALL || dic->op == PCALL)
@@ -1799,11 +1827,11 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
           operation is a '*','/' or '%' then 'b' may
           cause a problem */
        if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
-           getSize(aggrToPtr(operandType(op),FALSE)) >= 3)
+           getSize(operandType(op)) >= 3)
                return NULL;
 
        /* if left or right or result is in far space */
-       if (isOperandInFarSpace(IC_LEFT(dic))   ||
+       if (isOperandInFarSpace(IC_LEFT(dic))   ||
            isOperandInFarSpace(IC_RIGHT(dic))  ||
            isOperandInFarSpace(IC_RESULT(dic)) ||
            IS_OP_RUONLY(IC_LEFT(dic))          ||
@@ -1869,6 +1897,10 @@ static void packRegsForAccUse (iCode *ic)
          getSize(operandType(IC_RESULT(ic))) > 1))
        return ;
        
+    if (IS_BITWISE_OP(ic) &&
+       getSize(operandType(IC_RESULT(ic))) > 1)
+       return ;
+           
        
     /* has only one definition */
     if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
@@ -1994,14 +2026,15 @@ static void packForPush(iCode *ic, eBBlock *ebp)
                                bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
        return ;
 
-    if (dic->op != '=' || POINTER_SET(dic) || IS_ITEMP(IC_RESULT(dic)))
+    if (dic->op != '=' || POINTER_SET(dic))
        return;
 
     /* 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);
 
-    remiCodeFromeBBlock(ebp,dic);      
+    remiCodeFromeBBlock(ebp,dic);
+    hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2064,11 +2097,8 @@ static void packRegisters (eBBlock *ebp)
        }
 
        /* if this is a +/- operation with a rematerizable 
-          then mark this as rematerializable as well only
-          if the literal value is within the range -255 and + 255
-          the assembler cannot handle it other wise */
+          then mark this as rematerializable as well */
        if ((ic->op == '+' || ic->op == '-') &&
-
            (IS_SYMOP(IC_LEFT(ic)) && 
             IS_ITEMP(IC_RESULT(ic)) &&
             OP_SYMBOL(IC_LEFT(ic))->remat &&
@@ -2076,11 +2106,9 @@ static void packRegisters (eBBlock *ebp)
             IS_OP_LITERAL(IC_RIGHT(ic))) ) {
 
            int i = operandLitValue(IC_RIGHT(ic));
-           if ( i < 255 && i > -255) {
-               OP_SYMBOL(IC_RESULT(ic))->remat = 1;
-               OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
-               OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
-           }
+           OP_SYMBOL(IC_RESULT(ic))->remat = 1;
+           OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
+           OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
        }
 
        /* mark the pointer usages */
@@ -2137,7 +2165,7 @@ static void packRegisters (eBBlock *ebp)
           can be eliminated for return statements */
        if ((ic->op == RETURN || ic->op == SEND) &&
            !isOperandInFarSpace(IC_LEFT(ic))    &&
-           !options.model)
+           options.model == MODEL_SMALL)
            packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
 
        /* if pointer set & left has a size more than
@@ -2170,13 +2198,16 @@ static void packRegisters (eBBlock *ebp)
            link *toType = operandType(IC_LEFT(ic));
 
            if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
-               getSize(fromType) != getSize(toType) ) {
+               getSize(fromType) != getSize(toType)  &&
+               SPEC_USIGN(fromType) == SPEC_USIGN(toType)) {
 
                iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
                if (dic) {
                    if (IS_ARITHMETIC_OP(dic)) {
                        IC_RESULT(dic) = IC_RESULT(ic);
                        remiCodeFromeBBlock(ebp,ic);
+                       hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
+                       OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
                        ic = ic->prev;
                    } else
                        OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
@@ -2191,6 +2222,8 @@ static void packRegisters (eBBlock *ebp)
                    if (dic) {
                        IC_RESULT(dic) = IC_RESULT(ic);
                        remiCodeFromeBBlock(ebp,ic);
+                       hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
+                       OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
                        ic = ic->prev;
                    }
                }
@@ -2216,12 +2249,10 @@ static void packRegisters (eBBlock *ebp)
           the result of that operation is not on stack then
           we can leave the result of this operation in acc:b
           combination */
-       if ((IS_ARITHMETIC_OP(ic) 
-            
-            || IS_BITWISE_OP(ic) 
-            
+       if ((IS_ARITHMETIC_OP(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)
@@ -2283,8 +2314,13 @@ void mcs51_assignRegisters (eBBlock **ebbs, int count)
     /* redo that offsets for stacked automatic variables */
     redoStackOffsets ();
 
-    if (options.dump_rassgn)
+    if (options.dump_rassgn) {
        dumpEbbsToFileExt(".dumprassgn",ebbs,count);
+       dumpLiveRanges(".lrange",liveRanges);
+    }
+
+    /* do the overlaysegment stuff SDCCmem.c */
+    doOverlays(ebbs,count);
 
     /* now get back the chain */
     ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));