Numerous bug fixes in PIC Port (pointers, shifting, bank selection,...)
[fw/sdcc] / src / pic / ralloc.c
index 7b7f125b14b2545c692498869aebde04d0c1b889..58258c9a5d26c27d751e29679cf5d01be7940b86 100644 (file)
@@ -430,7 +430,7 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
       *buffer = 's';
     dReg->name = Safe_strdup(buffer);
   }
-  //fprintf(stderr,"newReg: %s\n",dReg->name);
+  //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
   dReg->isFree = 0;
   dReg->wasUsed = 1;
   dReg->isFixed = 0;
@@ -548,7 +548,7 @@ static int regname2key(char const *name)
 /* dirregWithName - search for register by name                    */
 /*-----------------------------------------------------------------*/
 regs *
-dirregWithName (char *name )
+dirregWithName (char *name)
 {
   int hkey;
   regs *reg;
@@ -575,6 +575,12 @@ dirregWithName (char *name )
   return NULL; // name wasn't found in the hash table
 }
 
+int IS_CONFIG_ADDRESS(int address)
+{
+
+  return address == 0x2007;
+}
+
 /*-----------------------------------------------------------------*/
 /* allocDirReg - allocates register of given type                  */
 /*-----------------------------------------------------------------*/
@@ -626,25 +632,35 @@ allocDirReg (operand *op )
   reg = dirregWithName(name);
 
   if(!reg) {
+    int address = 0;
+
+    /* 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));
+    }
 
     /* 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)) {
+      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);
+
+      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);
+      }
 
-    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 (IS_BITVAR (OP_SYM_ETYPE(op)))
+       addSet(&dynDirectBitRegs, reg);
+      else
+       addSet(&dynDirectRegs, reg);
+    } else {
+      debugLog ("  -- %s is declared at address 0x2007\n",name);
 
-    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);
     }
-
-    hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
-    if (IS_BITVAR (OP_SYM_ETYPE(op)))
-      addSet(&dynDirectBitRegs, reg);
-    else
-      addSet(&dynDirectRegs, reg);
   }
 
   return reg;
@@ -654,7 +670,7 @@ allocDirReg (operand *op )
 /* allocDirReg - allocates register of given type                  */
 /*-----------------------------------------------------------------*/
 regs *
-allocRegByName (char *name )
+allocRegByName (char *name, int size)
 {
 
   regs *reg;
@@ -675,7 +691,7 @@ allocRegByName (char *name )
      * a new one and put it in the hash table AND in the 
      * dynDirectRegNames set */
 
-    reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,1,0 );
+    reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
 
     debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
 
@@ -760,6 +776,8 @@ pic14_allocWithIdx (int idx)
     debugLog ("Found a Stack Register!\n");
   } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
     debugLog ("Found a Processor Register!\n");
+  } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
+    debugLog ("Found an Internal Register!\n");
   } else {
     
     debugLog ("Dynamic Register not found\n");
@@ -790,7 +808,7 @@ pic14_findFreeReg(short type)
     if((dReg = regFindFree(dynAllocRegs)) != NULL)
       return dReg;
 
-    return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,0,0));
+    return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
 
   case REG_STK:
 
@@ -871,7 +889,7 @@ void writeSetUsedRegs(FILE *of, set *dRegs)
 
 }
 extern void assignFixedRegisters(set *regset);
-extern void assignRelocatableRegisters(set *regset);
+extern void assignRelocatableRegisters(set *regset,int used);
 extern void dump_map(void);
 extern void dump_cblock(FILE *of);
 
@@ -993,9 +1011,10 @@ void writeUsedRegs(FILE *of)
   assignFixedRegisters(dynStackRegs);
   assignFixedRegisters(dynDirectRegs);
 
-  assignRelocatableRegisters(dynAllocRegs);
-  assignRelocatableRegisters(dynStackRegs);
-  assignRelocatableRegisters(dynDirectRegs);
+  assignRelocatableRegisters(dynInternalRegs,1);
+  assignRelocatableRegisters(dynAllocRegs,0);
+  assignRelocatableRegisters(dynStackRegs,0);
+  assignRelocatableRegisters(dynDirectRegs,0);
 
   //dump_map();
 
@@ -2229,6 +2248,48 @@ createRegMask (eBBlock ** ebbs, int count)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* rematStr - returns the rematerialized string for a remat var    */
+/*-----------------------------------------------------------------*/
+static symbol *
+rematStr (symbol * sym)
+{
+  char *s = buffer;
+  iCode *ic = sym->rematiCode;
+  symbol *psym = NULL;
+
+  debugLog ("%s\n", __FUNCTION__);
+
+  //printf ("%s\n", s);
+
+  /* if plus or minus print the right hand side */
+
+  if (ic->op == '+' || ic->op == '-') {
+       
+    iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+
+    sprintf (s, "(%s %c 0x%04x)",
+            OP_SYMBOL (IC_LEFT (ric))->rname,
+            ic->op,
+            (int) operandLitValue (IC_RIGHT (ic)));
+
+
+    //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+
+    psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
+    psym->offset = (int) operandLitValue (IC_RIGHT (ic));
+
+    return psym;
+  }
+
+  sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+  psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
+
+  //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
+  return psym;
+}
+
+#if 0
 /*-----------------------------------------------------------------*/
 /* rematStr - returns the rematerialized string for a remat var    */
 /*-----------------------------------------------------------------*/
@@ -2264,6 +2325,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);
          return buffer;
        }
 
@@ -2275,6 +2337,7 @@ rematStr (symbol * sym)
   printf ("%s\n", buffer);
   return buffer;
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* regTypeNum - computes the type & number of registers required   */
@@ -2337,7 +2400,8 @@ regTypeNum ()
            DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
 
          /* create a psuedo symbol & force a spil */
-         symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+         //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+         symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
          psym->type = sym->type;
          psym->etype = sym->etype;
          strcpy (psym->rname, psym->name);
@@ -2539,6 +2603,28 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
   debugAopGet ("  left:", IC_LEFT (ic));
   debugAopGet ("  right:", IC_RIGHT (ic));
 
+  /* if this is at an absolute address, then get the address. */
+  if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
+    if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
+      debugLog ("  %d - found config word declaration\n", __LINE__);
+      if(IS_VALOP(IC_RIGHT(ic))) {
+       debugLog ("  setting config word to %x\n", 
+                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+       assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
+                               (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+      }
+
+      /* remove the assignment from the iCode chain. */
+
+      remiCodeFromeBBlock (ebp, ic);
+      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+      hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+
+      return 1;
+
+    }
+  }
+
   if (!IS_ITEMP (IC_RESULT (ic))) {
     allocDirReg(IC_RESULT (ic));
     debugLog ("  %d - result is not temp\n", __LINE__);