xa 51, work in progress
[fw/sdcc] / src / xa51 / ralloc.c
index abd08afa6772580f83882596ce262c5ca5970e8f..037e79830a8d88a10e18fd8d78ebcececbf1167a 100755 (executable)
@@ -37,6 +37,7 @@
 /*-----------------------------------------------------------------*/
 
 extern void genXA51Code (iCode *);
+
 #define D(x)
 
 /* Global data */
@@ -65,7 +66,7 @@ regs regsXA51[]={
   {0x25, 2, REG_PTR, "r5",  0x0c00, 10, 1, NULL}, 
   {0x26, 2, REG_PTR, "r6",  0x3000, 12, 1, NULL}, 
   {0x27, 2, REG_STK, "r7",  0xc000, 14, 1, NULL}, // r7=SP
-#if 0 // some derivates have even more! (only word access and gpr use)
+#if 0 // some derivates have even more! (only bit/word access no ptr use)
   {0x28, 2, REG_GPR, "r8",  0x10000, 16, 1, NULL},
   {0x29, 2, REG_GPR, "r9",  0x20000, 18, 1, NULL},
   {0x2a, 2, REG_GPR, "r10", 0x40000, 20, 1, NULL},
@@ -166,7 +167,8 @@ static void freeReg (regs * reg, bool silent) {
   }
   
   if (!silent) {
-    fprintf (stderr, "freeReg: (%08x) %s ", xa51RegsInUse, reg->name);
+    D(fprintf (stderr, "freeReg: (%08x) %s (%s) ", xa51RegsInUse, 
+            reg->name, reg->sym->name));
   }
 
   if (reg->isFree || ((xa51RegsInUse&reg->regMask)!=reg->regMask)) {
@@ -177,7 +179,7 @@ static void freeReg (regs * reg, bool silent) {
   xa51RegsInUse &= ~reg->regMask;
   reg->isFree = 1;
   reg->sym = NULL;
-  if (!silent) fprintf (stderr, "(%08x)\n", xa51RegsInUse);
+  if (!silent) D(fprintf (stderr, "(%08x)\n", xa51RegsInUse));
 
   checkRegMask(__FUNCTION__);
 }
@@ -193,15 +195,15 @@ static bool allocReg (short size, short type, symbol *sym,
   checkRegMask(__FUNCTION__);
 
   if (!silent) {
-    fprintf (stderr, "allocReg (0x%08x) for %s size:%d, type:%s ", 
+    D(fprintf (stderr, "allocReg (%08x) for %s size:%d, type:%s ", 
             xa51RegsInUse,
             sym->name,
-            size, regTypeToStr(type));
+            size, regTypeToStr(type)));
   }
 
   switch (size) 
     {
-      // TODO: gaps should be filled for dwords too
+      // TODO: gaps could be filled for dwords too
     case 1:
       // let's see if we can fill a gap
       for (i=0; i<xa51_nRegs; i++) {
@@ -215,7 +217,7 @@ static bool allocReg (short size, short type, symbol *sym,
            reg->isFree=0; // redundant
            reg->sym = sym;
            if (!silent) {
-             fprintf (stderr, "(using gap) %s\n", reg->name);
+             D(fprintf (stderr, "(using gap) %s\n", reg->name));
            }
            checkRegMask(__FUNCTION__);
            return TRUE;
@@ -232,7 +234,7 @@ static bool allocReg (short size, short type, symbol *sym,
          regsXA51[i].isFree = 0; // redundant
          regsXA51[i].sym = sym;
          if (!silent) {
-           fprintf (stderr, "%s\n", regsXA51[i].name);
+           D(fprintf (stderr, "%s\n", regsXA51[i].name));
          }
          sym->regs[offset]=&regsXA51[i];
          checkRegMask(__FUNCTION__);
@@ -240,7 +242,7 @@ static bool allocReg (short size, short type, symbol *sym,
        }
       }
       if (!silent) {
-       fprintf (stderr, "failed (%08x)\n", xa51RegsInUse);
+       D(fprintf (stderr, "failed (%08x)\n", xa51RegsInUse));
       }
       checkRegMask(__FUNCTION__);
       return FALSE;
@@ -248,25 +250,25 @@ static bool allocReg (short size, short type, symbol *sym,
     case 3:
       // this must be a generic pointer
       if (!silent) {
-       fprintf (stderr, "trying 2+1\n");
+       D(fprintf (stderr, "trying 1+2\n"));
       }
-      // get the pointer part
-      if (allocReg (2, REG_PTR, sym, offset, silent)) {
-       // get the generic part
-       if ((xa51HasGprRegs && allocReg (1, REG_GPR, sym, offset+1, silent)) ||
-           allocReg (1, REG_PTR, sym, offset+1, silent)) {
+      // get the generic part
+      if ((xa51HasGprRegs && allocReg (1, REG_GPR, sym, offset+1, silent)) ||
+         allocReg (1, REG_PTR, sym, offset+1, silent)) {
+       // get the pointer part
+       if (allocReg (2, REG_PTR, sym, offset, silent)) {
          checkRegMask(__FUNCTION__);
          return TRUE;
        }
-       freeReg(sym->regs[offset], silent);
-       sym->regs[offset]=NULL;
+       freeReg(sym->regs[offset+1], silent);
+       sym->regs[offset+1]=NULL;
       }
       checkRegMask(__FUNCTION__);
       return FALSE;
       break;
     case 4: // this is a dword
       if (!silent) {
-       fprintf (stderr, "trying 2+2\n");
+       D(fprintf (stderr, "trying 2+2\n"));
       }
       if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset, silent)) ||
          allocReg (2, REG_PTR, sym, offset, silent)) {
@@ -276,8 +278,10 @@ static bool allocReg (short size, short type, symbol *sym,
          return TRUE;
        }
       }
-      freeReg(sym->regs[offset], FALSE);
-      sym->regs[offset]=NULL;
+      if (sym->regs[offset]) {
+       freeReg(sym->regs[offset], FALSE);
+       sym->regs[offset]=NULL;
+      }
       checkRegMask(__FUNCTION__);
       return FALSE;
       break;
@@ -520,29 +524,29 @@ noOverLap (set * itmpStack, symbol * fsym)
 /*-----------------------------------------------------------------*/
 /* isFree - will return 1 if the a free spil location is found     */
 /*-----------------------------------------------------------------*/
-static
-DEFSETFUNC (isFree)
-{
+static DEFSETFUNC (isFree) {
   symbol *sym = item;
   V_ARG (symbol **, sloc);
   V_ARG (symbol *, fsym);
-
+  
   /* if already found */
   if (*sloc)
     return 0;
-
+  
   /* if it is free && and the itmp assigned to
      this does not have any overlapping live ranges
      with the one currently being assigned and
      the size can be accomodated  */
   if (sym->isFree &&
       noOverLap (sym->usl.itmpStack, fsym) &&
-      getSize (sym->type) >= getSize (fsym->type))
-    {
-      *sloc = sym;
-      return 1;
-    }
-
+      /* TODO: this is a waste but causes to many problems 
+        getSize (sym->type) >= getSize (fsym->type)) {
+      */
+      getSize (sym->type) == getSize (fsym->type)) {
+    *sloc = sym;
+    return 1;
+  }
+  
   return 0;
 }
 
@@ -553,11 +557,9 @@ static symbol *
 createStackSpil (symbol * sym)
 {
   symbol *sloc = NULL;
-  int useXstack, model;
-
   char slocBuffer[30];
 
-  fprintf (stderr, "  createStackSpil: %s\n", sym->name);
+  D(fprintf (stderr, "  createStackSpil: %s\n", sym->name));
 
   /* first go try and find a free one that is already 
      existing on the stack */
@@ -571,17 +573,7 @@ createStackSpil (symbol * sym)
       return sym;
     }
 
-  /* could not then have to create one , this is the hard part
-     we need to allocate this on the stack : this is really a
-     hack!! but cannot think of anything better at this time */
-
-  if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
-    {
-      fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
-              __FILE__, __LINE__);
-      exit (1);
-    }
-
+  sprintf (slocBuffer, "sloc%d", _G.slocNum++);
   sloc = newiTemp (slocBuffer);
 
   /* set the type to the spilling symbol */
@@ -593,34 +585,12 @@ createStackSpil (symbol * sym)
   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
-     temporarily turn it off ; we also
-     turn off memory model to prevent
-     the spil from going to the external storage
-   */
-
-  useXstack = options.useXstack;
-  model = options.model;
-/*     noOverlay = options.noOverlay; */
-/*     options.noOverlay = 1; */
-  options.model = options.useXstack = 0;
-
   allocLocal (sloc);
 
-  options.useXstack = useXstack;
-  options.model = model;
-/*     options.noOverlay = noOverlay; */
   sloc->isref = 1;             /* to prevent compiler warning */
 
-  /* if it is on the stack then update the stack */
-  if (IN_STACK (sloc->etype))
-    {
-      currFunc->stack += getSize (sloc->type);
-      _G.stackExtend += getSize (sloc->type);
-    }
-  else
-    _G.dataExtend += getSize (sloc->type);
+  currFunc->stack += getSize (sloc->type);
+  _G.stackExtend += getSize (sloc->type);
 
   /* add it to the _G.stackSpil set */
   addSetHead (&_G.stackSpil, sloc);
@@ -641,7 +611,7 @@ spillThis (symbol * sym)
 {
   int i;
   
-  fprintf (stderr, "  spillThis: %s\n", sym->name);
+  D(fprintf (stderr, "  spillThis: %s\n", sym->name));
 
   /* if this is rematerializable or has a spillLocation
      we are okay, else we need to create a spillLocation
@@ -773,7 +743,7 @@ spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
   /* get something we can spil */
   ssym = selectSpil (ic, ebp, forSym);
 
-  fprintf (stderr, "  spillSomething: spilling %s\n", ssym->name);
+  D(fprintf (stderr, "  spillSomething: spilling %s\n", ssym->name));
 
   /* mark it as spilt */
   ssym->isspilt = ssym->spillA = 1;
@@ -831,9 +801,9 @@ spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
 /*-----------------------------------------------------------------*/
 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
 
-  fprintf (stderr, "getRegPtr: %s ", sym->name);
-  printTypeChain(sym->type, stderr);
-  fprintf (stderr, "\n");
+  D(fprintf (stderr, "getRegPtr: %s ", sym->name));
+  D(printTypeChain(sym->type, stderr));
+  D(fprintf (stderr, "\n"));
 
 tryAgain:
   /* try for a ptr type */
@@ -859,9 +829,9 @@ tryAgain:
 /*-----------------------------------------------------------------*/
 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
 
-  fprintf (stderr, "getRegGpr: %s ", sym->name);
-  printTypeChain(sym->type, stderr);
-  fprintf (stderr, "\n");
+  D(fprintf (stderr, "getRegGpr: %s ", sym->name));
+  D(printTypeChain(sym->type, stderr));
+  D(fprintf (stderr, "\n"));
 
 tryAgain:
   /* try for gpr type */
@@ -942,7 +912,7 @@ static bool willCauseSpill (symbol *sym) {
     }
     return FALSE;
   }
-  fprintf (stderr, "  %s will cause a spill\n", sym->name);
+  D(fprintf (stderr, "  %s will cause a spill\n", sym->name));
   return TRUE;
 }
 
@@ -1010,8 +980,9 @@ serialRegAssign (eBBlock ** ebbs, int count)
 
            /* if result is present && is a true symbol */
            if (IC_RESULT (ic) && ic->op != IFX &&
-               IS_TRUE_SYMOP (IC_RESULT (ic)))
-               OP_SYMBOL (IC_RESULT (ic))->allocreq++;
+               IS_TRUE_SYMOP (IC_RESULT (ic))) {
+             OP_SYMBOL (IC_RESULT (ic))->allocreq++;
+           }
 
            /* take away registers from live
               ranges that end at this instruction */
@@ -1026,6 +997,39 @@ serialRegAssign (eBBlock ** ebbs, int count)
                (IC_RESULT (ic) && POINTER_SET (ic)))
                continue;
 
+#if 0
+           /* xa51 has advance compare instructions */
+           if (ic->op == '<' || ic->op == '>' || 
+               ic->op == LE_OP || ic->op == GE_OP ||
+               ic->op == NE_OP || ic->op == EQ_OP) {
+             /* if this result is only used for an ifx, we don't
+                need registers nor the ifx */
+             int used=bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->uses);
+             iCode *nic;
+             if (used!=1) {
+               fprintf (stderr, "unexpected \"used\" for cmp:%d\n", ic->op);
+               exit (1);
+             }
+             // find the ifx
+             for (nic=ic->next; nic; nic=nic->next) {
+               if (nic->op == IFX) {
+                 break;
+               }
+             }
+             if (!nic) {
+               // we are in big trouble
+               fprintf (stderr, "No ifx found for %d\n",
+                        ic->op);
+               exit (1);
+             }
+             // remove the ifx
+             nic->prev->next=nic->next;
+             if (nic->next) {
+               nic->next->prev=nic->prev;
+             }
+           }
+#endif
+
            /* now we need to allocate registers
               only for the result */
            if (IC_RESULT (ic)) {
@@ -1063,24 +1067,24 @@ serialRegAssign (eBBlock ** ebbs, int count)
                /* if it has a spillocation & is used less than
                   all other live ranges then spill this */
                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)) {
-                           /* if this is local to this block then we might find a block spil */
-                           if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
-                               spillThis (sym);
-                               continue;
-                           }
-                       }
+                 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)) {
+                     /* if this is local to this block then we might find a block spil */
+                     if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
+                       spillThis (sym);
+                       continue;
+                     }
                    }
+                 }
                }
 
                /* else we assign registers to it */
@@ -1325,10 +1329,7 @@ regTypeNum (eBBlock *ebbs)
 #endif
 
          /* if the symbol has only one definition &
-            that definition is a get_pointer and the
-            pointer we are getting is rematerializable and
-            in "data" space */
-
+            that definition is a get_pointer */
          if (bitVectnBitsOn (sym->defs) == 1 &&
              (ic = hTabItemWithKey (iCodehTab,
                                     bitVectFirstBit (sym->defs))) &&
@@ -1336,12 +1337,10 @@ regTypeNum (eBBlock *ebbs)
              !sym->noSpilLoc &&
              !IS_BITVAR (sym->etype))
            {
-
-
-             /* if remat in data space */
+             /* and that pointer is remat in data space */
              if (OP_SYMBOL (IC_LEFT (ic))->remat &&
                  !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
-                 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
+                 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
                {
                  /* create a psuedo symbol & force a spil */
                  symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
@@ -1402,6 +1401,7 @@ regTypeNum (eBBlock *ebbs)
              fprintf (stderr, "allocated more than 4 or 0 registers for type ");
              printTypeChain (sym->type, stderr);
              fprintf (stderr, "\n");
+             exit (1);
            }
 
          /* determine the type of register required */
@@ -1883,6 +1883,8 @@ static void packRegisters (eBBlock * ebp) {
   iCode *ic;
   int change = 0;
   
+  return; // that's it for now
+
   while (1) {
     change = 0;
     
@@ -1894,7 +1896,6 @@ static void packRegisters (eBBlock * ebp) {
     if (!change)
       break;
   }
-  return; // that's it for now
 
   for (ic = ebp->sch; ic; ic = ic->next)
     {