new option -o
[fw/sdcc] / src / pic / ralloc.c
index f417f06481752bce556717ecd8e80da7ca83f7c1..d4ab0afc798b72c3012899f27cd08e41bd03a72c 100644 (file)
@@ -45,6 +45,7 @@
 /*-----------------------------------------------------------------*/
 
 extern void genpic14Code (iCode *);
+extern void assignConfigWordValue(int address, int value);
 
 /* Global data */
 static struct
@@ -64,14 +65,15 @@ _G;
 int pic14_ptrRegReq;           /* one byte pointer register required */
 
 
-static set *dynAllocRegs=NULL;
-static set *dynStackRegs=NULL;
-static set *dynProcessorRegs=NULL;
-static set *dynDirectRegs=NULL;
-static set *dynDirectBitRegs=NULL;
-static set *dynInternalRegs=NULL;
+set *dynAllocRegs=NULL;
+set *dynStackRegs=NULL;
+set *dynProcessorRegs=NULL;
+set *dynDirectRegs=NULL;
+set *dynDirectBitRegs=NULL;
+set *dynInternalRegs=NULL;
 
 static hTab  *dynDirectRegNames= NULL;
+// static hTab  *regHash = NULL;    /* a hash table containing ALL registers */
 
 static int dynrIdx=0x20;
 static int rDirectIdx=0;
@@ -100,14 +102,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"))))
@@ -406,10 +408,29 @@ debugLogRegType (short type)
       return "REG_CND";
     }
 
-  sprintf (buffer, "unkown reg type %d", type);
+  sprintf (buffer, "unknown reg type %d", type);
   return buffer;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static int regname2key(char const *name)
+{
+  int key = 0;
+
+  if(!name)
+    return 0;
+
+  while(*name) {
+
+    key += (*name++) + 1;
+
+  }
+
+  return ( (key + (key >> 4) + (key>>8)) & 0x3f);
+
+}
+
 /*-----------------------------------------------------------------*/
 /* newReg - allocate and init memory for a new register            */
 /*-----------------------------------------------------------------*/
@@ -433,13 +454,21 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
   //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
   dReg->isFree = 0;
   dReg->wasUsed = 1;
-  dReg->isFixed = 0;
+  if(type == REG_SFR)
+    dReg->isFixed = 1;
+  else
+    dReg->isFixed = 0;
+
   dReg->isMapped = 0;
   dReg->isEmitted = 0;
   dReg->address = 0;
   dReg->size = size;
   dReg->alias = alias;
   dReg->reg_alias = NULL;
+  dReg->reglives.usedpFlows = newSet();
+  dReg->reglives.assignedpFlows = newSet();
+
+  hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
 
   return dReg;
 }
@@ -489,21 +518,31 @@ void initStack(int base_address, int size)
   int i;
 
   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));
 }
 
+/*-----------------------------------------------------------------*
+ *-----------------------------------------------------------------*/
 regs *
 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
 {
+
+  //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
   return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
 }
 
+/*-----------------------------------------------------------------*
+ *-----------------------------------------------------------------*/
+
 regs *
 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 {
-  regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
+  regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
 
+  //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
   if(reg) {
     reg->wasUsed = 0;
     return addSet(&dynInternalRegs,reg);
@@ -519,30 +558,13 @@ allocReg (short type)
 {
 
   debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
+  //fprintf(stderr,"allocReg\n");
 
 
   return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
 
 }
 
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static int regname2key(char const *name)
-{
-  int key = 0;
-
-  if(!name)
-    return 0;
-
-  while(*name) {
-
-    key += (*name++) + 1;
-
-  }
-
-  return ( (key + (key >> 4) + (key>>8)) & 0x3f);
-
-}
 
 /*-----------------------------------------------------------------*/
 /* dirregWithName - search for register by name                    */
@@ -629,7 +651,21 @@ allocDirReg (operand *op )
     return NULL;
 
   /* First, search the hash table to see if there is a register with this name */
-  reg = dirregWithName(name);
+  if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
+    reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
+/*
+    if(!reg) 
+      fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
+             name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
+    else
+      fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
+             name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
+*/
+  } else {
+    //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
+    
+    reg = dirregWithName(name);
+  }
 
   if(!reg) {
     int address = 0;
@@ -637,26 +673,32 @@ allocDirReg (operand *op )
     /* if this is at an absolute address, then get the address. */
     if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
       address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+      //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)) {
+      //fprintf(stderr,"allocating new reg %s\n",name);
+
       reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
       debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
-/*
+
+      //hTabAddItem(&dynDirectRegNames, regname2key(name), 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);
+
+       //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
+       reg->type = REG_SFR;
       }
-*/
-      hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
-      if (IS_BITVAR (OP_SYM_ETYPE(op)))
+
+      if (IS_BITVAR (OP_SYM_ETYPE(op))) {
        addSet(&dynDirectBitRegs, reg);
-      else
+       reg->isBitField = 1;
+      } else
        addSet(&dynDirectRegs, reg);
+
     } else {
       debugLog ("  -- %s is declared at address 0x2007\n",name);
 
@@ -686,8 +728,6 @@ allocRegByName (char *name, int size)
     exit(1);
   }
 
-  debugLog ("%s symbol name %s\n", __FUNCTION__,name);
-
   /* First, search the hash table to see if there is a register with this name */
   reg = dirregWithName(name);
 
@@ -696,12 +736,12 @@ allocRegByName (char *name, int size)
     /* 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 );
 
     debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
 
-    hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+    //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
     addSet(&dynDirectRegs, reg);
   }
 
@@ -711,7 +751,7 @@ allocRegByName (char *name, int size)
 /*-----------------------------------------------------------------*/
 /* RegWithIdx - returns pointer to register with index number       */
 /*-----------------------------------------------------------------*/
-static regs *
+regs *
 typeRegWithIdx (int idx, int type, int fixed)
 {
 
@@ -719,38 +759,39 @@ typeRegWithIdx (int idx, int type, int fixed)
 
   debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
 
-  if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
+  switch (type) {
 
-    debugLog ("Found a Dynamic Register!\n");
-    return dReg;
-  }
+  case REG_GPR:
+    if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
 
-  if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
-    debugLog ("Found a Stack Register!\n");
-    return dReg;
-  }
+      debugLog ("Found a Dynamic Register!\n");
+      return dReg;
+    }
+    if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
+      debugLog ("Found a Direct Register!\n");
+      return dReg;
+    }
 
-  if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
-    debugLog ("Found a Direct Register!\n");
-    return dReg;
-  }
+    break;
+  case REG_STK:
+    if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
+      debugLog ("Found a Stack Register!\n");
+      return dReg;
+    }
+    break;
+  case REG_SFR:
+    if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
+      debugLog ("Found a Processor Register!\n");
+      return dReg;
+    }
 
-  if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
-    debugLog ("Found a Processor Register!\n");
-    return dReg;
-  }
-/*
-  if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
-    debugLog ("Found a bit Register!\n");
-    return dReg;
+  case REG_CND:
+  case REG_PTR:
+  default:
+    break;
   }
-*/
-/*
-  fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
-  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-         "regWithIdx not found");
-  exit (1);
-*/
+
+
   return NULL;
 }
 
@@ -760,8 +801,18 @@ typeRegWithIdx (int idx, int type, int fixed)
 regs *
 pic14_regWithIdx (int idx)
 {
+  regs *dReg;
+
+  if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
+    return dReg;
+
+  if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
+    return dReg;
+
+  if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
+    return dReg;
 
-  return typeRegWithIdx(idx,-1,0);
+  return NULL;
 }
 
 /*-----------------------------------------------------------------*/
@@ -789,7 +840,7 @@ pic14_allocWithIdx (int idx)
     debugLog ("Dynamic Register not found\n");
 
 
-    fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
+    //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
     werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
            "regWithIdx not found");
     exit (1);
@@ -813,7 +864,6 @@ pic14_findFreeReg(short type)
   case REG_GPR:
     if((dReg = regFindFree(dynAllocRegs)) != NULL)
       return dReg;
-
     return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
 
   case REG_STK:
@@ -880,7 +930,6 @@ nfreeRegsType (int type)
   return nFreeRegs (type);
 }
 
-//<<<<<<< ralloc.c
 void writeSetUsedRegs(FILE *of, set *dRegs)
 {
 
@@ -910,6 +959,7 @@ void packBits(set *bregs)
   int byte_no=-1;
   char buffer[20];
 
+
   for (regset = bregs ; regset ;
        regset = regset->next) {
 
@@ -927,12 +977,12 @@ void packBits(set *bregs)
       if(!bitfield) {
        sprintf (buffer, "fbitfield%02x", breg->address);
        //fprintf(stderr,"new bit field\n");
-       bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
+       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);
-       hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
+       //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
       } else {
        //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
        ;
@@ -949,7 +999,7 @@ void packBits(set *bregs)
        relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
        relocbitfield->isBitField = 1;
        addSet(&dynDirectRegs,relocbitfield);
-       hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+       //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
 
       }
 
@@ -993,7 +1043,7 @@ void bitEQUs(FILE *of, set *bregs)
   }
       
 }
-void aliasEQUs(FILE *of, set *fregs)
+void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
 {
   regs *reg;
 
@@ -1001,10 +1051,16 @@ void aliasEQUs(FILE *of, set *fregs)
   for (reg = setFirstItem(fregs) ; reg ;
        reg = setNextItem(fregs)) {
 
-    if(!reg->isEmitted)
-      fprintf (of, "%s\tEQU\t0x%03x\n",
-              reg->name,
-              reg->address);
+    if(!reg->isEmitted && reg->wasUsed) {
+      if(use_rIdx)
+       fprintf (of, "%s\tEQU\t0x%03x\n",
+                reg->name,
+                reg->rIdx);
+      else
+       fprintf (of, "%s\tEQU\t0x%03x\n",
+                reg->name,
+                reg->address);
+    }
   }
       
 }
@@ -1013,11 +1069,12 @@ void writeUsedRegs(FILE *of)
 {
   packBits(dynDirectBitRegs);
 
+
   assignFixedRegisters(dynAllocRegs);
   assignFixedRegisters(dynStackRegs);
   assignFixedRegisters(dynDirectRegs);
 
-  assignRelocatableRegisters(dynInternalRegs,1);
+  assignRelocatableRegisters(dynInternalRegs,0);
   assignRelocatableRegisters(dynAllocRegs,0);
   assignRelocatableRegisters(dynStackRegs,0);
   assignRelocatableRegisters(dynDirectRegs,0);
@@ -1026,11 +1083,13 @@ void writeUsedRegs(FILE *of)
 
   dump_cblock(of);
   bitEQUs(of,dynDirectBitRegs);
-  aliasEQUs(of,dynAllocRegs);
-  aliasEQUs(of,dynDirectRegs);
-  aliasEQUs(of,dynStackRegs);
+  aliasEQUs(of,dynAllocRegs,0);
+  aliasEQUs(of,dynDirectRegs,0);
+  aliasEQUs(of,dynStackRegs,0);
+  aliasEQUs(of,dynProcessorRegs,1);
 
 }
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* allDefsOutOfRange - all definitions are out of a range          */
@@ -1059,8 +1118,7 @@ allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
   return TRUE;
 }
 #endif
-//=======
-//>>>>>>> 1.28
+
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
 /*-----------------------------------------------------------------*/
@@ -2331,7 +2389,7 @@ rematStr (symbol * sym)
          //s += strlen(s);
          //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
          //continue ;
-         fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+         //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
          return buffer;
        }
 
@@ -2467,6 +2525,7 @@ DEFSETFUNC (markRegFree)
 
 DEFSETFUNC (deallocReg)
 {
+  fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
   ((regs *)item)->isFree = 1;
   ((regs *)item)->wasUsed = 0;
 
@@ -3333,6 +3392,45 @@ void printSymType(char * str, sym_link *sl)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* some debug code to print the symbol S_TYPE. Note that
+ * the function checkSClass in src/SDCCsymt.c dinks with
+ * the S_TYPE in ways the PIC port doesn't fully like...*/
+/*-----------------------------------------------------------------*/
+void isData(sym_link *sl)
+{
+  FILE *of = stderr;
+
+  if(!sl)
+    return;
+
+  if(debugF)
+    of = debugF;
+
+  for ( ; sl; sl=sl->next) {
+    if(!IS_DECL(sl) ) {
+      switch (SPEC_SCLS(sl)) {
+       
+      case S_DATA: fprintf (of, "data "); break;
+      case S_XDATA: fprintf (of, "xdata "); break;
+      case S_SFR: fprintf (of, "sfr "); break;
+      case S_SBIT: fprintf (of, "sbit "); break;
+      case S_CODE: fprintf (of, "code "); break;
+      case S_IDATA: fprintf (of, "idata "); break;
+      case S_PDATA: fprintf (of, "pdata "); break;
+      case S_LITERAL: fprintf (of, "literal "); break;
+      case S_STACK: fprintf (of, "stack "); break;
+      case S_XSTACK: fprintf (of, "xstack "); break;
+      case S_BIT: fprintf (of, "bit "); break;
+      case S_EEPROM: fprintf (of, "eeprom "); break;
+      default: break;
+      }
+
+    }
+
+  }
+    
+}
 /*-----------------------------------------------------------------*/
 /* packRegisters - does some transformations to reduce register    */
 /*                   pressure                                      */
@@ -3378,11 +3476,16 @@ packRegisters (eBBlock * ebp)
   for (ic = ebp->sch; ic; ic = ic->next) {
 
     if(IS_SYMOP ( IC_LEFT(ic))) {
-      //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
+      sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
 
       debugAopGet ("  left:", IC_LEFT (ic));
       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
-       debugLog ("    is a pointer");
+       debugLog ("    is a pointer\n");
+
+      if(IS_OP_VOLATILE(IC_LEFT(ic)))
+       debugLog ("    is volatile\n");
+
+      isData(etype);
 
       printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
     }
@@ -3765,7 +3868,7 @@ pic14_assignRegisters (eBBlock ** ebbs, int count)
   setToNull ((void **) &_G.stackSpil);
   setToNull ((void **) &_G.spiltSet);
   /* mark all registers as free */
-  pic14_freeAllRegs ();
+  //pic14_freeAllRegs ();
 
   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
   debugLogClose ();