* src/pic/device.c,
[fw/sdcc] / src / pic / ralloc.c
index a8599cd75e00e3e9aacdc22e3d5eb4b21f70f82c..809c6dbea5e8784d5aba93311a4be752ff12a60a 100644 (file)
@@ -35,6 +35,9 @@
 #define STRCASECMP strcasecmp
 #endif
 
+/* this should go in SDCCicode.h, but it doesn't. */
+#define IS_REF(op)       (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
+
 /*-----------------------------------------------------------------*/
 /* At this point we start getting processor specific although      */
 /* some routines are non-processor specific & can be reused when   */
@@ -102,14 +105,14 @@ debugLog (char *fmt,...)
   //char *bufferP=buffer;
   va_list ap;
 
-  if (!debug || !srcFileName)
+  if (!debug || !dstFileName)
     return;
 
 
   if (!debugF)
     {
       /* create the file name */
-      strcpy (buffer, srcFileName);
+      strcpy (buffer, dstFileName);
       strcat (buffer, ".d");
 
       if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
@@ -389,7 +392,7 @@ decodeOp (unsigned int op)
     case SEND:
       return "SEND";
     }
-  sprintf (buffer, "unkown op %d %c", op, op & 0xff);
+  sprintf (buffer, "unknown op %d %c", op, op & 0xff);
   return buffer;
 }
 /*-----------------------------------------------------------------*/
@@ -443,24 +446,24 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
   dReg->type = type;
   dReg->pc_type = pc_type;
   dReg->rIdx = rIdx;
-  if(name) 
+  if(name) {
     dReg->name = Safe_strdup(name);
-  else {
+  else {
     sprintf(buffer,"r0x%02X", dReg->rIdx);
-    if(type == REG_STK)
-      *buffer = 's';
     dReg->name = Safe_strdup(buffer);
   }
   //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
   dReg->isFree = 0;
   dReg->wasUsed = 1;
-  if(type == REG_SFR)
+  if (type == REG_SFR)
     dReg->isFixed = 1;
   else
     dReg->isFixed = 0;
 
   dReg->isMapped = 0;
   dReg->isEmitted = 0;
+  dReg->isPublic = 0;
+  dReg->isExtern = 0;
   dReg->address = 0;
   dReg->size = size;
   dReg->alias = alias;
@@ -484,7 +487,7 @@ regWithIdx (set *dRegs, int idx, int fixed)
   for (dReg = setFirstItem(dRegs) ; dReg ; 
        dReg = setNextItem(dRegs)) {
 
-    if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
+    if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
       return dReg;
     }
   }
@@ -492,6 +495,64 @@ regWithIdx (set *dRegs, int idx, int fixed)
   return NULL;
 }
 
+/*-----------------------------------------------------------------*/
+/* regWithName - Search through a set of registers that matches name */
+/*-----------------------------------------------------------------*/
+static regs *
+regWithName (set *dRegs, const char *name)
+{
+  regs *dReg;
+
+  for (dReg = setFirstItem(dRegs) ; dReg ; 
+       dReg = setNextItem(dRegs)) {
+
+    if((strcmp(name,dReg->name)==0)) {
+      return dReg;
+    }
+  }
+
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* regWithName - Search for a registers that matches name          */
+/*-----------------------------------------------------------------*/
+regs *
+regFindWithName (const char *name)
+{
+  regs *dReg;
+
+    if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
+      debugLog ("Found a Direct Register!\n");
+      return dReg;
+    }
+    if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
+      debugLog ("Found a Direct Bit Register!\n");
+      return dReg;
+    }
+
+       if (*name=='_') name++; // Step passed '_'
+
+    if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
+      debugLog ("Found a Dynamic Register!\n");
+      return dReg;
+    }
+    if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
+      debugLog ("Found a Processor Register!\n");
+      return dReg;
+    }
+    if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
+      debugLog ("Found an Internal Register!\n");
+      return dReg;
+    }
+    if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
+      debugLog ("Found an Stack Register!\n");
+      return dReg;
+    }
+
+  return NULL;
+}
+
 /*-----------------------------------------------------------------*/
 /* regFindFree - Search for a free register in a set of registers  */
 /*-----------------------------------------------------------------*/
@@ -520,8 +581,15 @@ void initStack(int base_address, int size)
   Gstack_base_addr = base_address;
   //fprintf(stderr,"initStack");
 
-  for(i = 0; i<size; i++)
-    addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
+  for(i = 0; i<size; i++) {
+       regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,NULL,1,0);
+    r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
+    r->isFixed = 1;
+    r->name[0] = 's';
+       r->alias = 0x180; // Using shared memory for pseudo stack
+    addSet(&dynStackRegs,r);
+       base_address--;
+  }
 }
 
 /*-----------------------------------------------------------------*
@@ -603,6 +671,68 @@ int IS_CONFIG_ADDRESS(int address)
   return address == 0x2007;
 }
 
+/*-----------------------------------------------------------------*/
+/* allocNewDirReg - allocates a new register of given type         */
+/*-----------------------------------------------------------------*/
+regs *
+allocNewDirReg (sym_link *symlnk,const char *name)
+{
+  regs *reg;
+  int address = 0;
+
+  /* if this is at an absolute address, then get the address. */
+  if (SPEC_ABSA (symlnk) ) {
+    address = SPEC_ADDR (symlnk);
+    //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
+  }
+
+  /* Register wasn't found in hash, so let's create
+   * a new one and put it in the hash table AND in the 
+   * dynDirectRegNames set */
+  if (IS_CONFIG_ADDRESS(address)) {
+    debugLog ("  -- %s is declared at address 0x2007\n",name);
+       reg = 0;
+  } else {
+    int idx;
+    if (address) {
+      if (IS_BITVAR (symlnk))
+        idx = address >> 3;
+      else
+       idx = address;
+    } else {
+      idx = rDirectIdx++;
+    }
+    reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
+    debugLog ("  -- added %s to hash, size = %d\n", (char*)name,reg->size);
+
+    if (SPEC_ABSA (symlnk) ) {
+      reg->type = REG_SFR;
+    }
+
+    if (IS_BITVAR (symlnk)) {
+      addSet(&dynDirectBitRegs, reg);
+      reg->isBitField = 1;
+    } else
+      addSet(&dynDirectRegs, reg);
+
+    if (!IS_STATIC (symlnk)) {
+      reg->isPublic = 1;
+    }
+    if (IS_EXTERN (symlnk)) {
+      reg->isExtern = 1;
+    }
+
+  }
+
+  if (address && reg) {
+    reg->isFixed = 1;
+    reg->address = address;
+    debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
+  }
+
+  return reg;
+}
+
 /*-----------------------------------------------------------------*/
 /* allocDirReg - allocates register of given type                  */
 /*-----------------------------------------------------------------*/
@@ -667,6 +797,7 @@ allocDirReg (operand *op )
     reg = dirregWithName(name);
   }
 
+#if 0
   if(!reg) {
     int address = 0;
 
@@ -699,6 +830,14 @@ allocDirReg (operand *op )
       } else
        addSet(&dynDirectRegs, reg);
 
+      if (!IS_STATIC (OP_SYM_ETYPE(op))) {
+        reg->isPublic = 1;
+      }
+      if (IS_EXTERN (OP_SYM_ETYPE(op))) {
+        reg->isExtern = 1;
+      }
+         
+
     } else {
       debugLog ("  -- %s is declared at address 0x2007\n",name);
 
@@ -710,12 +849,24 @@ allocDirReg (operand *op )
     reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
     debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
   }
+#endif
+
+  if(reg) {
+    if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+      reg->isFixed = 1;
+      reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+      debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
+    }
+  } else {
+    allocNewDirReg (OP_SYM_ETYPE(op),name);
+  }
 
   return reg;
 }
 
+
 /*-----------------------------------------------------------------*/
-/* allocDirReg - allocates register of given type                  */
+/* allocRegByName - allocates register with given name             */
 /*-----------------------------------------------------------------*/
 regs *
 allocRegByName (char *name, int size)
@@ -731,17 +882,58 @@ allocRegByName (char *name, int size)
   /* First, search the hash table to see if there is a register with this name */
   reg = dirregWithName(name);
 
-  if(!reg) {
 
+  if(!reg) {
+    int found = 0;
+    symbol *sym;
     /* Register wasn't found in hash, so let's create
      * a new one and put it in the hash table AND in the 
      * dynDirectRegNames set */
     //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
     reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
+    for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
+               if (strcmp(reg->name+1,sym->name)==0) {
+                          unsigned a = SPEC_ADDR(sym->etype);
+                                 reg->address = a;
+                                 reg->isFixed = 1;
+                               reg->type = REG_SFR;
+                         if (!IS_STATIC (sym->etype)) {
+                               reg->isPublic = 1;
+                         }
+                         if (IS_EXTERN (sym->etype)) {
+                               reg->isExtern = 1;
+                         }
+                     if (IS_BITVAR (sym->etype)) 
+                               reg->isBitField = 1;
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found) {
+               for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
+                       if (strcmp(reg->name+1,sym->name)==0) {
+                               unsigned a = SPEC_ADDR(sym->etype);
+                               reg->address = a;
+                               if (!IS_STATIC (sym->etype)) {
+                                       reg->isPublic = 1;
+                               }
+                               if (IS_EXTERN (sym->etype)) {
+                                       reg->isExtern = 1;
+                       }
+                               if (IS_BITVAR (sym->etype)) 
+                                       reg->isBitField = 1;
+                               found = 1;
+                       break;
+               }
+       }
+       }
 
     debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
 
     //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+      if (reg->isBitField) {
+               addSet(&dynDirectBitRegs, reg);
+      } else
     addSet(&dynDirectRegs, reg);
   }
 
@@ -809,9 +1001,6 @@ pic14_regWithIdx (int idx)
   if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
     return dReg;
 
-  if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
-    return dReg;
-
   return NULL;
 }
 
@@ -835,6 +1024,8 @@ pic14_allocWithIdx (int idx)
     debugLog ("Found a Processor Register!\n");
   } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
     debugLog ("Found an Internal Register!\n");
+  } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
+    debugLog ("Found an Internal Register!\n");
   } else {
     
     debugLog ("Dynamic Register not found\n");
@@ -946,8 +1137,7 @@ void writeSetUsedRegs(FILE *of, set *dRegs)
 extern void assignFixedRegisters(set *regset);
 extern void assignRelocatableRegisters(set *regset,int used);
 extern void dump_map(void);
-extern void dump_cblock(FILE *of);
-
+extern void dump_sfr(FILE *of);
 
 void packBits(set *bregs)
 {
@@ -975,13 +1165,15 @@ void packBits(set *bregs)
       breg->address >>= 3;
 
       if(!bitfield) {
-       sprintf (buffer, "fbitfield%02x", breg->address);
+       //sprintf (buffer, "fbitfield%02x", breg->address);
+       sprintf (buffer, "0x%02x", breg->address);
        //fprintf(stderr,"new bit field\n");
        bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
        bitfield->isBitField = 1;
        bitfield->isFixed = 1;
        bitfield->address = breg->address;
-       addSet(&dynDirectRegs,bitfield);
+       //addSet(&dynDirectRegs,bitfield);
+       addSet(&dynInternalRegs,bitfield);
        //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
       } else {
        //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
@@ -998,7 +1190,8 @@ void packBits(set *bregs)
        //fprintf(stderr,"new relocatable bit field\n");
        relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
        relocbitfield->isBitField = 1;
-       addSet(&dynDirectRegs,relocbitfield);
+       //addSet(&dynDirectRegs,relocbitfield);
+       addSet(&dynInternalRegs,relocbitfield);
        //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
 
       }
@@ -1032,7 +1225,7 @@ void bitEQUs(FILE *of, set *bregs)
               breg->rIdx & 0x0007);
 
     else {
-      fprintf(stderr, "bit field is not assigned to a register\n");
+      //fprintf(stderr, "bit field is not assigned to a register\n");
       fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
               breg->name,
               bit_no>>3,
@@ -1051,7 +1244,8 @@ void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
   for (reg = setFirstItem(fregs) ; reg ;
        reg = setNextItem(fregs)) {
 
-    if(!reg->isEmitted && reg->wasUsed) {
+    //if(!reg->isEmitted && reg->wasUsed) {
+    if(reg->wasUsed) {
       if(use_rIdx)
        fprintf (of, "%s\tEQU\t0x%03x\n",
                 reg->name,
@@ -1069,7 +1263,7 @@ void writeUsedRegs(FILE *of)
 {
   packBits(dynDirectBitRegs);
 
-
+  assignFixedRegisters(dynInternalRegs);
   assignFixedRegisters(dynAllocRegs);
   assignFixedRegisters(dynStackRegs);
   assignFixedRegisters(dynDirectRegs);
@@ -1077,17 +1271,21 @@ void writeUsedRegs(FILE *of)
   assignRelocatableRegisters(dynInternalRegs,0);
   assignRelocatableRegisters(dynAllocRegs,0);
   assignRelocatableRegisters(dynStackRegs,0);
-  assignRelocatableRegisters(dynDirectRegs,0);
 
+/*
+  assignRelocatableRegisters(dynDirectRegs,0);
+  printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
+*/
   //dump_map();
 
-  dump_cblock(of);
+  dump_sfr(of);
   bitEQUs(of,dynDirectBitRegs);
+/*
   aliasEQUs(of,dynAllocRegs,0);
   aliasEQUs(of,dynDirectRegs,0);
   aliasEQUs(of,dynStackRegs,0);
   aliasEQUs(of,dynProcessorRegs,1);
-
+*/
 }
 
 #if 0
@@ -1288,7 +1486,7 @@ leastUsedLR (set * sset)
 
     }
 
-  setToNull ((void **) &sset);
+  setToNull ((void *) &sset);
   sym->blockSpil = 0;
   return sym;
 }
@@ -2125,7 +2323,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
              debugLog ("  %d - \n", __LINE__);
              if(debugF) 
                bitVectDebugOn(_G.regAssigned, debugF);
-
              for (j = 0; j < sym->nRegs; j++)
                {
                  if (sym->regType == REG_PTR)
@@ -2133,7 +2330,7 @@ serialRegAssign (eBBlock ** ebbs, int count)
                  else
                    sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
 
-                 /* if the allocation falied which means
+                 /* if the allocation failed which means
                     this was spilt then break */
                  if (!sym->regs[j])
                    break;
@@ -2436,14 +2633,22 @@ regTypeNum ()
 
       /* if used in return only then we don't 
         need registers */
-      if (sym->ruonly || sym->accuse) {
+      if (sym->accuse) {
        if (IS_AGGREGATE (sym->type) || sym->isptr)
          sym->type = aggrToPtr (sym->type, FALSE);
-       debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
+       debugLog ("  %d - no reg needed - accumulator used\n", __LINE__);
 
        continue;
       }
 
+      if (sym->ruonly) {
+       //if (IS_AGGREGATE (sym->type) || sym->isptr)
+       //  sym->type = aggrToPtr (sym->type, FALSE);
+       debugLog ("  %d - used as a return\n", __LINE__);
+
+       //continue;
+      }
+
       /* if the symbol has only one definition &
         that definition is a get_pointer and the
         pointer we are getting is rematerializable and
@@ -2703,7 +2908,10 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
 
   if (!IS_ITEMP (IC_RIGHT (ic))) {
     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
-    allocDirReg(IC_RIGHT (ic));
+
+    /* only pack if this is not a function pointer */
+    if (!IS_REF (IC_RIGHT (ic)))
+      allocDirReg(IC_RIGHT (ic));
     return 0;
   }
 
@@ -2839,7 +3047,7 @@ pack:
   remiCodeFromeBBlock (ebp, ic);
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-  OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+  OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
   return 1;
 
 
@@ -3675,7 +3883,7 @@ packRegisters (eBBlock * ebp)
            remiCodeFromeBBlock (ebp, ic);
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
            hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-           OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+           OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
            ic = ic->prev;
          }  else
                
@@ -3696,7 +3904,7 @@ packRegisters (eBBlock * ebp)
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
            remiCodeFromeBBlock (ebp, ic);
            hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-           OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+           OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
            ic = ic->prev;
          }
        }
@@ -3865,8 +4073,8 @@ pic14_assignRegisters (eBBlock ** ebbs, int count)
   /* free up any _G.stackSpil locations allocated */
   applyToSet (_G.stackSpil, deallocStackSpil);
   _G.slocNum = 0;
-  setToNull ((void **) &_G.stackSpil);
-  setToNull ((void **) &_G.spiltSet);
+  setToNull ((void *) &_G.stackSpil);
+  setToNull ((void *) &_G.spiltSet);
   /* mark all registers as free */
   //pic14_freeAllRegs ();