* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / src / pic16 / ralloc.c
index 58cc571a10d15dc2a8b3a131effe82ae664509d5..5fa12896432b93910d0a3eac2bcd074ac268af39 100644 (file)
@@ -154,7 +154,7 @@ debugLog (char *fmt,...)
 
   fprintf (debugF, "%s", buffer);
 /*
-   while (isspace(*bufferP)) bufferP++;
+   while (isspace((unsigned char)*bufferP)) bufferP++;
 
    if (bufferP && *bufferP) 
    lineCurr = (lineCurr ?
@@ -314,6 +314,7 @@ pic16_decodeOp (unsigned int op)
                case LABEL:             return "LABEL";
                case RECEIVE:           return "RECEIVE";
                case SEND:              return "SEND";
+               case DUMMY_READ_VOLATILE:       return "DUMMY_READ_VOLATILE";
        }
        sprintf (buffer, "unkown op %d %c", op, op & 0xff);
 
@@ -446,6 +447,26 @@ regFindFree (set *dRegs)
 
   return NULL;
 }
+
+static regs *
+regFindFreeNext(set *dRegs, regs *creg)
+{
+  regs *dReg;
+
+    if(creg) {
+      /* position at current register */
+      for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
+    }
+    
+    for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
+      if(dReg->isFree) {
+        return dReg;
+      }
+    }
+  
+  return NULL;
+}
+
 /*-----------------------------------------------------------------*/
 /* pic16_initStack - allocate registers for a pseudo stack               */
 /*-----------------------------------------------------------------*/
@@ -737,7 +758,7 @@ pic16_allocDirReg (operand *op )
 
 
        if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
-#if 1
+#if 0
                if(pic16_debug_verbose)
                {
                        fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
@@ -906,8 +927,8 @@ pic16_allocDirReg (operand *op )
                reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
 
                /* work around for user defined registers in access bank */
-               if((reg->address>= 0x00 && reg->address < 0x80)
-                       || (reg->address >= 0xf80 && reg->address <= 0xfff))
+               if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
+                       || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
                        reg->accessBank = 1;
                
                debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
@@ -939,7 +960,7 @@ pic16_allocRegByName (char *name, int size, operand *op)
      * a new one and put it in the hash table AND in the 
      * dynDirectRegNames set */
 
-       fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
+       //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
 
     reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
 
@@ -1089,6 +1110,33 @@ pic16_findFreeReg(short type)
     return NULL;
   }
 }
+
+regs *
+pic16_findFreeRegNext(short type, regs *creg)
+{
+  //  int i;
+  regs* dReg;
+
+  switch (type) {
+  case REG_GPR:
+    if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
+      return dReg;
+    return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+
+  case REG_STK:
+
+    if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
+      return dReg;
+
+    return NULL;
+
+  case REG_PTR:
+  case REG_CND:
+  case REG_SFR:
+  default:
+    return NULL;
+  }
+}
 /*-----------------------------------------------------------------*/
 /* freeReg - frees a register                                      */
 /*-----------------------------------------------------------------*/
@@ -2275,6 +2323,13 @@ serialRegAssign (eBBlock ** ebbs, int count)
              int j;
              int ptrRegSet = 0;
 
+             /* Make sure any spill location is definately allocated */
+             if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+                 !sym->usl.spillLoc->allocreq)
+               {
+                 sym->usl.spillLoc->allocreq++;
+               }
+
              /* if it does not need or is spilt 
                 or is already assigned to registers
                 or will not live beyond this instructions */
@@ -2297,6 +2352,10 @@ serialRegAssign (eBBlock ** ebbs, int count)
                 or this one is rematerializable then
                 spill this one */
              willCS = willCauseSpill (sym->nRegs, sym->regType);
+
+             /* explicit turn off register spilling */
+             willCS = 0;
+             
              spillable = computeSpillable (ic);
              if (sym->remat ||
                  (willCS && bitVectIsZero (spillable)))
@@ -2312,12 +2371,13 @@ serialRegAssign (eBBlock ** ebbs, int count)
                 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 0
              if (sym->liveFrom < ic->seq)
                {
                    spillThis (sym);
                    continue;                 
                }
-
+#endif
              /* if it has a spillocation & is used less than
                 all other live ranges then spill this */
                if (willCS) {
@@ -2920,13 +2980,32 @@ farSpacePackable (iCode * ic)
   return NULL;
 }
 
+#if 0
+static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
+{
+  iCode *dic, *sic;
+
+    debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
+    debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
+    debugAopGet ("  result:", IC_RESULT (ic));
+    debugAopGet ("  left:", IC_LEFT (ic));
+    debugAopGet ("  right:", IC_RIGHT (ic));
+
+    dic = ic->prev;
+    if((dic->op == '=')
+      && (
+}
+#endif
+
+
+void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
+
 /*-----------------------------------------------------------------*/
 /* packRegsForAssign - register reduction for assignment           */
 /*-----------------------------------------------------------------*/
 static int
 packRegsForAssign (iCode * ic, eBBlock * ebp)
 {
-
   iCode *dic, *sic;
 
   debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
@@ -3099,34 +3178,35 @@ pack:
   /* found the definition */
   /* replace the result with the result of */
   /* this assignment and remove this assignment */
-  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
-  IC_RESULT (dic) = IC_RESULT (ic);
-
-  if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
-    {
-      OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
-    }
-  /* delete from liverange table also 
-     delete from all the points inbetween and the new
-     one */
-  for (sic = dic; sic != ic; sic = sic->next)
-    {
-      bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
-      if (IS_ITEMP (IC_RESULT (dic)))
-       bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
-    }
 
-  remiCodeFromeBBlock (ebp, ic);
-  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+  
+    bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+    IC_RESULT (dic) = IC_RESULT (ic);
 
-       debugLog("  %d\n", __LINE__ );
-  hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-  OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-  return 1;
+    if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
+      {
+        OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
+      }
+    /* delete from liverange table also 
+       delete from all the points inbetween and the new
+       one */
+    for (sic = dic; sic != ic; sic = sic->next)
+      {
+        bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
+        if (IS_ITEMP (IC_RESULT (dic)))
+          bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
+      }
 
+    remiCodeFromeBBlock (ebp, ic);
+    bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
 
+    debugLog("  %d\n", __LINE__ );
+    hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+    OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+    return 1;
 }
 
+
 #if 1
 
 #define NO_packRegsForAccUse
@@ -3315,11 +3395,17 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   if (!IS_SYMOP (op))
     return NULL;
 
+  if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
+    return NULL;
+
   /* only upto 2 bytes since we cannot predict
      the usage of b, & acc */
-  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) &&       /* was 2, changed to 3 -- VR */
-      ic->op != RETURN &&
-      ic->op != SEND)
+  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
+      && 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 
@@ -3328,10 +3414,18 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
      that definition is either a return value from a 
      function or does not contain any variables in
      far space */
+
+#if 0
   uses = bitVectCopy (OP_USES (op));
   bitVectUnSetBit (uses, ic->key);     /* take away this iCode */
   if (!bitVectIsZero (uses))   /* has other uses */
     return NULL;
+#endif
+
+#if 1
+  if (bitVectnBitsOn (OP_USES (op)) > 1)
+    return NULL;
+#endif
 
   /* if it has only one defintion */
   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
@@ -3360,6 +3454,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
        }
       dic = dic->next;
     }
+  else
+    {
 
 
   /* otherwise check that the definition does
@@ -3381,6 +3477,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   if (POINTER_GET (dic) &&
       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
     return NULL;
+    }
 
   sic = dic;
 
@@ -3411,7 +3508,7 @@ 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 (operandType (op)) >= 3)
+         getSize (operandType (op)) >= 2)
        return NULL;
 
       /* if left or right or result is in far space */
@@ -3948,13 +4045,58 @@ pic16_packRegisters (eBBlock * ebp)
        OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
       }
 
+
+#if 0
+    /* if this is an arithmetic operation
+     *   && result or left is not rematerializable (so it is a plain arithmetic op)
+     *   && and left is not used after this iCode */
+     
+    if(getenv("OPTIMIZE_NEAR_POINTER_GET"))
+
+    if (IS_ARITHMETIC_OP(ic)
+      && !IS_OP_LITERAL (IC_LEFT (ic))
+      && !OP_SYMBOL (IC_RESULT(ic))->rematiCode
+      && !OP_SYMBOL (IC_LEFT(ic))->rematiCode
+      && (OP_LIVETO (IC_LEFT(ic) ) <= ic->seq)
+      ) {
+        iCode *dic = ic->prev;
+        
+          /* search backwards to find assignment from a remat pointer */
+          while(dic && dic->seq >= OP_LIVEFROM( IC_LEFT(ic) )) {
+
+            /* is it a pointer_get? */
+            if(POINTER_GET(dic)
+              && IS_DATA_PTR(OP_SYM_TYPE (IC_LEFT (dic)))) {
+                fprintf(stderr, "%s:%d `%s' is a data pointer (ic seq: %d)\n", __FILE__, __LINE__,
+                          OP_SYMBOL(IC_LEFT(dic))->rname, dic->seq);
+                          
+                /* so we can replace ic->left with dic->left, & remove assignment */
+                ReplaceOpWithCheaperOp( &IC_LEFT(ic), IC_LEFT(dic) );
+                
+                bitVectUnSetBit(OP_USES( IC_LEFT(ic) ), ic->key);
+                bitVectUnSetBit(OP_DEFS( IC_RESULT(dic) ), dic->key );
+                
+//                dic->op = DUMMY_READ_VOLATILE;
+#if 1
+                remiCodeFromeBBlock(ebp, dic);
+                hTabDeleteItem(&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+#endif
+                break;
+            }
+            dic = dic->prev;
+          }
+    }
+#endif
+          
     /* mark the pointer usages */
     if (POINTER_SET (ic))
       {
        OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
        debugLog ("  marking as a pointer (set) =>");
        debugAopGet ("  result:", IC_RESULT (ic));
+
       }
+
     if (POINTER_GET (ic))
       {
         if(IS_SYMOP(IC_LEFT(ic))) {
@@ -3962,6 +4104,32 @@ pic16_packRegisters (eBBlock * ebp)
           debugLog ("  marking as a pointer (get) =>");
           debugAopGet ("  left:", IC_LEFT (ic));
         }
+        
+        if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
+          if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
+            iCode *dic = ic->prev;
+
+            fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
+          
+            if(dic && dic->op == '='
+              && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
+              
+                fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
+
+
+                /* replace prev->left with ic->left */
+                IC_LEFT(ic) = IC_RIGHT(dic);
+                IC_RIGHT(ic->prev) = NULL;
+                
+                /* remove ic->prev iCode (assignment) */
+                remiCodeFromeBBlock (ebp, dic);
+                bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
+
+
+                hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+            }
+          }
+        }
       }
 
        //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);
@@ -4208,8 +4376,10 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count)
 /* pic16_assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
 void
-pic16_assignRegisters (eBBlock ** ebbs, int count)
+pic16_assignRegisters (ebbIndex * ebbi)
 {
+  eBBlock ** ebbs = ebbi->bbOrder;
+  int count = ebbi->count;
   iCode *ic;
   int i;
 
@@ -4249,7 +4419,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   recomputeLiveRanges (ebbs, count);
 
   if (options.dump_pack)
-    dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+    dumpEbbsToFileExt (DUMP_PACK, ebbi);
 
   /* first determine for each live range the number of 
      registers & the type of registers required for each */
@@ -4291,7 +4461,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   redoStackOffsets ();
 
   if (options.dump_rassgn)
-    dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+    dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
 
   /* now get back the chain */
   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));