new option -o
[fw/sdcc] / src / pic / ralloc.c
index 87921515ea21a5a2c8b226df26f36053cfea2931..d4ab0afc798b72c3012899f27cd08e41bd03a72c 100644 (file)
 #include "pcode.h"
 #include "gen.h"
 
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
 /*-----------------------------------------------------------------*/
 /* At this point we start getting processor specific although      */
 /* some routines are non-processor specific & can be reused when   */
@@ -39,6 +45,7 @@
 /*-----------------------------------------------------------------*/
 
 extern void genpic14Code (iCode *);
+extern void assignConfigWordValue(int address, int value);
 
 /* Global data */
 static struct
@@ -57,35 +64,28 @@ _G;
 /* Shared with gen.c */
 int pic14_ptrRegReq;           /* one byte pointer register required */
 
-/* pic14 registers */
-regs regspic14[] =
-{
-
-  {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
-  {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
-
-};
-
-int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
+
+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;
+
+int pic14_nRegs = 128;   // = sizeof (regspic14) / sizeof (regs);
+
+int Gstack_base_addr=0; /* The starting address of registers that
+                        * are used to pass and return parameters */
+
+
+
+
 static void spillThis (symbol *);
 static int debug = 1;
 static FILE *debugF = NULL;
@@ -102,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"))))
@@ -316,20 +316,6 @@ decodeOp (unsigned int op)
       return "RANGE";
     case FAR:
       return "FAR";
-    case _XDATA:
-      return "_XDATA";
-    case _CODE:
-      return "_CODE";
-    case _GENERIC:
-      return "_GENERIC";
-    case _NEAR:
-      return "_NEAR";
-    case _PDATA:
-      return "_PDATA";
-    case _IDATA:
-      return "_IDATA";
-    case _EEPROM:
-      return "_EEPROM";
     case CASE:
       return "CASE";
     case DEFAULT:
@@ -422,86 +408,477 @@ 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            */
+/*-----------------------------------------------------------------*/
+static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
+{
+
+  regs *dReg;
+
+  dReg = Safe_calloc(1,sizeof(regs));
+  dReg->type = type;
+  dReg->pc_type = pc_type;
+  dReg->rIdx = rIdx;
+  if(name) 
+    dReg->name = Safe_strdup(name);
+  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)
+    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;
+}
+
+/*-----------------------------------------------------------------*/
+/* regWithIdx - Search through a set of registers that matches idx */
+/*-----------------------------------------------------------------*/
+static regs *
+regWithIdx (set *dRegs, int idx, int fixed)
+{
+  regs *dReg;
+
+  for (dReg = setFirstItem(dRegs) ; dReg ; 
+       dReg = setNextItem(dRegs)) {
+
+    if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
+      return dReg;
+    }
+  }
+
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* regFindFree - Search for a free register in a set of registers  */
+/*-----------------------------------------------------------------*/
+static regs *
+regFindFree (set *dRegs)
+{
+  regs *dReg;
+
+  for (dReg = setFirstItem(dRegs) ; dReg ; 
+       dReg = setNextItem(dRegs)) {
+
+    if(dReg->isFree)
+      return dReg;
+  }
+
+  return NULL;
+}
+/*-----------------------------------------------------------------*/
+/* initStack - allocate registers for a psuedo stack               */
+/*-----------------------------------------------------------------*/
+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_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);
+  }
+
+  return NULL;
+}
 /*-----------------------------------------------------------------*/
 /* allocReg - allocates register of given type                     */
 /*-----------------------------------------------------------------*/
 static regs *
 allocReg (short type)
 {
-  int i;
 
   debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
+  //fprintf(stderr,"allocReg\n");
 
-  for (i = 0; i < pic14_nRegs; i++)
-    {
 
-      /* if type is given as 0 then any
-         free register will do */
-      if (!type &&
-         regspic14[i].isFree)
-       {
-         regspic14[i].isFree = 0;
-         regspic14[i].wasUsed = 1;
-         if (currFunc)
-           currFunc->regsUsed =
-             bitVectSetBit (currFunc->regsUsed, i);
-         debugLog ("  returning %s\n", regspic14[i].name);
-         return &regspic14[i];
-       }
-      /* other wise look for specific type
-         of register */
-      if (regspic14[i].isFree &&
-         regspic14[i].type == type)
-       {
-         regspic14[i].isFree = 0;
-         regspic14[i].wasUsed = 1;
-         if (currFunc)
-           currFunc->regsUsed =
-             bitVectSetBit (currFunc->regsUsed, i);
-         debugLog ("  returning %s\n", regspic14[i].name);
-         return &regspic14[i];
-       }
+  return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* dirregWithName - search for register by name                    */
+/*-----------------------------------------------------------------*/
+regs *
+dirregWithName (char *name)
+{
+  int hkey;
+  regs *reg;
+
+  if(!name)
+    return NULL;
+
+  /* hash the name to get a key */
+
+  hkey = regname2key(name);
+
+  reg = hTabFirstItemWK(dynDirectRegNames, hkey);
+
+  while(reg) {
+
+    if(STRCASECMP(reg->name, name) == 0) {
+      return(reg);
+    }
+
+    reg = hTabNextItemWK (dynDirectRegNames);
+  
+  }
+
+  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                  */
+/*-----------------------------------------------------------------*/
+regs *
+allocDirReg (operand *op )
+{
+
+  regs *reg;
+  char *name;
+
+  if(!IS_SYMOP(op)) {
+    debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
+    return NULL;
+  }
+
+  name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+
+  /* If the symbol is at a fixed address, then remove the leading underscore
+   * from the name. This is hack to allow the .asm include file named registers
+   * to match the .c declared register names */
+
+  //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
+  //name++;
+
+  debugLog ("%s symbol name %s\n", __FUNCTION__,name);
+  {
+    if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
+      debugLog(" %d  const char\n",__LINE__);
+      debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+    }
+
+    debugLog("  %d  storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
+    if (IS_CODE ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  code space\n",__LINE__);
+
+    if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  integral\n",__LINE__);
+    if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  literal\n",__LINE__);
+    if (IS_SPEC ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  specifier\n",__LINE__);
+    debugAopGet(NULL, op);
+  }
+
+  if (IS_CODE ( OP_SYM_ETYPE(op)) )
+    return NULL;
+
+  /* First, search the hash table to see if there is a register with this 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;
+
+    /* 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)) ) {
+
+       //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
+       reg->type = REG_SFR;
+      }
+
+      if (IS_BITVAR (OP_SYM_ETYPE(op))) {
+       addSet(&dynDirectBitRegs, reg);
+       reg->isBitField = 1;
+      } 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);
+  }
+
+  return reg;
+}
+
+/*-----------------------------------------------------------------*/
+/* allocDirReg - allocates register of given type                  */
+/*-----------------------------------------------------------------*/
+regs *
+allocRegByName (char *name, int size)
+{
+
+  regs *reg;
+
+  if(!name) {
+    fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
+    exit(1);
+  }
+
+  /* First, search the hash table to see if there is a register with this name */
+  reg = dirregWithName(name);
+
+  if(!reg) {
+
+    /* 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);
+    addSet(&dynDirectRegs, reg);
+  }
+
+  return reg;
+}
+
+/*-----------------------------------------------------------------*/
+/* RegWithIdx - returns pointer to register with index number       */
+/*-----------------------------------------------------------------*/
+regs *
+typeRegWithIdx (int idx, int type, int fixed)
+{
+
+  regs *dReg;
+
+  debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
+
+  switch (type) {
+
+  case REG_GPR:
+    if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
+
+      debugLog ("Found a Dynamic 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;
+    }
+
+  case REG_CND:
+  case REG_PTR:
+  default:
+    break;
+  }
+
+
   return NULL;
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_regWithIdx - returns pointer to register wit index number       */
+/* pic14_regWithIdx - returns pointer to register with index number*/
 /*-----------------------------------------------------------------*/
 regs *
 pic14_regWithIdx (int idx)
 {
-  int i;
+  regs *dReg;
 
-  debugLog ("%s\n", __FUNCTION__);
+  if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
+    return dReg;
 
-  for (i = 0; i < pic14_nRegs; i++)
-    if (regspic14[i].rIdx == idx)
-      return &regspic14[i];
+  if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
+    return dReg;
 
-  return &regspic14[0];
+  if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
+    return dReg;
 
-  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-         "regWithIdx not found");
-  exit (1);
+  return NULL;
 }
 
 /*-----------------------------------------------------------------*/
+/* pic14_regWithIdx - returns pointer to register with index number       */
 /*-----------------------------------------------------------------*/
 regs *
-pic14_findFreeReg(void)
+pic14_allocWithIdx (int idx)
 {
-  int i;
 
-  for (i = 0; i < pic14_nRegs; i++)
-    if (regspic14[i].isFree)
-      return &regspic14[i];
+  regs *dReg;
 
-  return NULL;
+  debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
+
+  if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
+
+    debugLog ("Found a Dynamic Register!\n");
+  } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
+    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");
+
+
+    //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
+    werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+           "regWithIdx not found");
+    exit (1);
+
+  }
+
+  dReg->wasUsed = 1;
+  dReg->isFree = 0;
+
+  return dReg;
+}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+regs *
+pic14_findFreeReg(short type)
+{
+  //  int i;
+  regs* dReg;
+
+  switch (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:
+
+    if((dReg = regFindFree(dynStackRegs)) != NULL)
+      return dReg;
+
+    return NULL;
+
+  case REG_PTR:
+  case REG_CND:
+  case REG_SFR:
+  default:
+    return NULL;
+  }
 }
 /*-----------------------------------------------------------------*/
 /* freeReg - frees a register                                      */
@@ -520,6 +897,11 @@ freeReg (regs * reg)
 static int
 nFreeRegs (int type)
 {
+  /* dynamically allocate as many as we need and worry about
+   * fitting them into a PIC later */
+
+  return 100;
+#if 0
   int i;
   int nfr = 0;
 
@@ -528,6 +910,7 @@ nFreeRegs (int type)
     if (regspic14[i].isFree && regspic14[i].type == type)
       nfr++;
   return nfr;
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -547,7 +930,167 @@ nfreeRegsType (int type)
   return nFreeRegs (type);
 }
 
+void writeSetUsedRegs(FILE *of, set *dRegs)
+{
+
+  regs *dReg;
+
+  for (dReg = setFirstItem(dRegs) ; dReg ; 
+       dReg = setNextItem(dRegs)) {
+
+    if(dReg->wasUsed)
+      fprintf (of, "\t%s\n",dReg->name);
+  }
+
+}
+extern void assignFixedRegisters(set *regset);
+extern void assignRelocatableRegisters(set *regset,int used);
+extern void dump_map(void);
+extern void dump_cblock(FILE *of);
+
+
+void packBits(set *bregs)
+{
+  set *regset;
+  regs *breg;
+  regs *bitfield=NULL;
+  regs *relocbitfield=NULL;
+  int bit_no=0;
+  int byte_no=-1;
+  char buffer[20];
+
+
+  for (regset = bregs ; regset ;
+       regset = regset->next) {
+
+    breg = regset->item;
+    breg->isBitField = 1;
+    //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+    if(breg->isFixed) {
+      //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
+
+      bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
+      breg->rIdx = breg->address & 7;
+      breg->address >>= 3;
+
+      if(!bitfield) {
+       sprintf (buffer, "fbitfield%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);
+       //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
+      } else {
+       //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
+       ;
+      }
+      breg->reg_alias = bitfield;
+      bitfield = NULL;
+
+    } else {
+      if(!relocbitfield || bit_no >7) {
+       byte_no++;
+       bit_no=0;
+       sprintf (buffer, "bitfield%d", byte_no);
+       //fprintf(stderr,"new relocatable bit field\n");
+       relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
+       relocbitfield->isBitField = 1;
+       addSet(&dynDirectRegs,relocbitfield);
+       //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+
+      }
+
+      breg->reg_alias = relocbitfield;
+      breg->address = rDirectIdx;   /* byte_no; */
+      breg->rIdx = bit_no++;
+    }
+  }
+      
+}
+
+
 
+void bitEQUs(FILE *of, set *bregs)
+{
+  regs *breg,*bytereg;
+  int bit_no=0;
+
+  //fprintf(stderr," %s\n",__FUNCTION__);
+  for (breg = setFirstItem(bregs) ; breg ;
+       breg = setNextItem(bregs)) {
+
+    //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+    bytereg = breg->reg_alias;
+    if(bytereg)
+      fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
+              breg->name,
+              bytereg->name,
+              breg->rIdx & 0x0007);
+
+    else {
+      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,
+              bit_no & 0x0007);
+
+      bit_no++;
+    }
+  }
+      
+}
+void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
+{
+  regs *reg;
+
+
+  for (reg = setFirstItem(fregs) ; reg ;
+       reg = setNextItem(fregs)) {
+
+    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);
+    }
+  }
+      
+}
+
+void writeUsedRegs(FILE *of) 
+{
+  packBits(dynDirectBitRegs);
+
+
+  assignFixedRegisters(dynAllocRegs);
+  assignFixedRegisters(dynStackRegs);
+  assignFixedRegisters(dynDirectRegs);
+
+  assignRelocatableRegisters(dynInternalRegs,0);
+  assignRelocatableRegisters(dynAllocRegs,0);
+  assignRelocatableRegisters(dynStackRegs,0);
+  assignRelocatableRegisters(dynDirectRegs,0);
+
+  //dump_map();
+
+  dump_cblock(of);
+  bitEQUs(of,dynDirectBitRegs);
+  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          */
 /*-----------------------------------------------------------------*/
@@ -574,6 +1117,7 @@ allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
 
   return TRUE;
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
@@ -657,18 +1201,6 @@ rematable (symbol * sym, eBBlock * ebp, iCode * ic)
   return sym->remat;
 }
 
-/*-----------------------------------------------------------------*/
-/* notUsedInBlock - not used in this block                         */
-/*-----------------------------------------------------------------*/
-static int
-notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
-{
-  debugLog ("%s\n", __FUNCTION__);
-  return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
-         allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
-/*     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
-}
-
 /*-----------------------------------------------------------------*/
 /* notUsedInRemaining - not used or defined in remain of the block */
 /*-----------------------------------------------------------------*/
@@ -900,6 +1432,7 @@ createStackSpil (symbol * sym)
   sloc->etype = getSpec (sloc->type);
   SPEC_SCLS (sloc->etype) = S_DATA;
   SPEC_EXTR (sloc->etype) = 0;
+  SPEC_STAT (sloc->etype) = 0;
 
   /* we don't allow it to be allocated`
      onto the external stack since : so we
@@ -1566,8 +2099,11 @@ serialRegAssign (eBBlock ** ebbs, int count)
                        /* 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)) {
-                           spillThis (sym);
-                           continue;
+                           /* 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;
+                           }
                        }
                    }
                }
@@ -1587,6 +2123,8 @@ serialRegAssign (eBBlock ** ebbs, int count)
              _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
 
              debugLog ("  %d - \n", __LINE__);
+             if(debugF) 
+               bitVectDebugOn(_G.regAssigned, debugF);
 
              for (j = 0; j < sym->nRegs; j++)
                {
@@ -1774,6 +2312,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    */
 /*-----------------------------------------------------------------*/
@@ -1809,6 +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);
          return buffer;
        }
 
@@ -1820,6 +2401,7 @@ rematStr (symbol * sym)
   printf ("%s\n", buffer);
   return buffer;
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* regTypeNum - computes the type & number of registers required   */
@@ -1834,116 +2416,138 @@ regTypeNum ()
   debugLog ("%s\n", __FUNCTION__);
   /* for each live range do */
   for (sym = hTabFirstItem (liveRanges, &k); sym;
-       sym = hTabNextItem (liveRanges, &k))
-    {
+       sym = hTabNextItem (liveRanges, &k)) {
 
-      debugLog ("  %d - %s\n", __LINE__, sym->rname);
+    debugLog ("  %d - %s\n", __LINE__, sym->rname);
 
-      /* if used zero times then no registers needed */
-      if ((sym->liveTo - sym->liveFrom) == 0)
-       continue;
+    /* if used zero times then no registers needed */
+    if ((sym->liveTo - sym->liveFrom) == 0)
+      continue;
 
 
-      /* if the live range is a temporary */
-      if (sym->isitmp)
-       {
+    /* if the live range is a temporary */
+    if (sym->isitmp) {
 
-         debugLog ("  %d - \n", __LINE__);
+      debugLog ("  %d - itemp register\n", __LINE__);
 
-         /* if the type is marked as a conditional */
-         if (sym->regType == REG_CND)
-           continue;
+      /* if the type is marked as a conditional */
+      if (sym->regType == REG_CND)
+       continue;
 
-         /* if used in return only then we don't 
-            need registers */
-         if (sym->ruonly || sym->accuse)
-           {
-             if (IS_AGGREGATE (sym->type) || sym->isptr)
-               sym->type = aggrToPtr (sym->type, FALSE);
-             debugLog ("  %d - \n", __LINE__);
+      /* if used in return only then we don't 
+        need registers */
+      if (sym->ruonly || 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__);
 
-             continue;
-           }
+       continue;
+      }
 
-         /* 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 */
-
-         if (bitVectnBitsOn (sym->defs) == 1 &&
-             (ic = hTabItemWithKey (iCodehTab,
-                                    bitVectFirstBit (sym->defs))) &&
-             POINTER_GET (ic) &&
-             !sym->noSpilLoc &&
-             !IS_BITVAR (sym->etype))
-           {
+      /* 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 */
+
+      if (bitVectnBitsOn (sym->defs) == 1 &&
+         (ic = hTabItemWithKey (iCodehTab,
+                                bitVectFirstBit (sym->defs))) &&
+         POINTER_GET (ic) &&
+         !sym->noSpilLoc &&
+         !IS_BITVAR (sym->etype)) {
+       
+
+       debugLog ("  %d - \n", __LINE__);
+
+       /* if remat in data space */
+       if (OP_SYMBOL (IC_LEFT (ic))->remat &&
+           DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
+
+         /* create a psuedo symbol & force a spil */
+         //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);
+         sym->isspilt = 1;
+         sym->usl.spillLoc = psym;
+         continue;
+       }
 
-             debugLog ("  %d - \n", __LINE__);
+       /* if in data space or idata space then try to
+          allocate pointer register */
 
-             /* if remat in data space */
-             if (OP_SYMBOL (IC_LEFT (ic))->remat &&
-                 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
-               {
+      }
 
-                 /* create a psuedo symbol & force a spil */
-                 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
-                 psym->type = sym->type;
-                 psym->etype = sym->etype;
-                 strcpy (psym->rname, psym->name);
-                 sym->isspilt = 1;
-                 sym->usl.spillLoc = psym;
-                 continue;
-               }
+      /* if not then we require registers */
+      sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
+                   getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
+                   getSize (sym->type));
 
-             /* if in data space or idata space then try to
-                allocate pointer register */
 
-           }
+    if(IS_PTR_CONST (sym->type)) {
+      debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
+      sym->nRegs = 2;
+    }
 
-         /* if not then we require registers */
-         sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
-                       getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
-                       getSize (sym->type));
+      if (sym->nRegs > 4) {
+       fprintf (stderr, "allocated more than 4 or 0 registers for type ");
+       printTypeChain (sym->type, stderr);
+       fprintf (stderr, "\n");
+      }
 
-         if (sym->nRegs > 4)
-           {
-             fprintf (stderr, "allocated more than 4 or 0 registers for type ");
-             printTypeChain (sym->type, stderr);
-             fprintf (stderr, "\n");
-           }
+      /* determine the type of register required */
+      if (sym->nRegs == 1 &&
+         IS_PTR (sym->type) &&
+         sym->uptr)
+       sym->regType = REG_PTR;
+      else
+       sym->regType = REG_GPR;
 
-         debugLog ("  %d - \n", __LINE__);
 
-         /* determine the type of register required */
-         if (sym->nRegs == 1 &&
-             IS_PTR (sym->type) &&
-             sym->uptr)
-           sym->regType = REG_PTR;
-         else
-           sym->regType = REG_GPR;
-         debugLog ("  reg type %s\n", debugLogRegType (sym->regType));
+      debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
 
-       }
-      else
-       /* for the first run we don't provide */
-       /* registers for true symbols we will */
-       /* see how things go                  */
-       sym->nRegs = 0;
     }
+    else
+      /* for the first run we don't provide */
+      /* registers for true symbols we will */
+      /* see how things go                  */
+      sym->nRegs = 0;
+  }
+
+}
+DEFSETFUNC (markRegFree)
+{
+  ((regs *)item)->isFree = 1;
 
+  return 0;
 }
 
+DEFSETFUNC (deallocReg)
+{
+  fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
+  ((regs *)item)->isFree = 1;
+  ((regs *)item)->wasUsed = 0;
+
+  return 0;
+}
 /*-----------------------------------------------------------------*/
 /* freeAllRegs - mark all registers as free                        */
 /*-----------------------------------------------------------------*/
 void
 pic14_freeAllRegs ()
 {
-  int i;
+  //  int i;
 
   debugLog ("%s\n", __FUNCTION__);
+
+  applyToSet(dynAllocRegs,markRegFree);
+  applyToSet(dynStackRegs,markRegFree);
+
+/*
   for (i = 0; i < pic14_nRegs; i++)
     regspic14[i].isFree = 1;
+*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1951,13 +2555,20 @@ pic14_freeAllRegs ()
 void
 pic14_deallocateAllRegs ()
 {
-  int i;
+  //  int i;
 
   debugLog ("%s\n", __FUNCTION__);
+
+  applyToSet(dynAllocRegs,deallocReg);
+
+/*
   for (i = 0; i < pic14_nRegs; i++) {
-    regspic14[i].isFree = 1;
-    regspic14[i].wasUsed = 0;
+    if(regspic14[i].pc_type == PO_GPR_TEMP) {
+      regspic14[i].isFree = 1;
+      regspic14[i].wasUsed = 0;
+    }
   }
+*/
 }
 
 
@@ -2057,10 +2668,49 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
   debugAopGet ("  left:", IC_LEFT (ic));
   debugAopGet ("  right:", IC_RIGHT (ic));
 
-  if (!IS_ITEMP (IC_RIGHT (ic)) ||
-      OP_SYMBOL (IC_RIGHT (ic))->isind ||
+  /* 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__);
+  }
+/*
+  if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
+    debugLog ("  %d - left is not temp, allocating\n", __LINE__);
+    allocDirReg(IC_LEFT (ic));
+  }
+*/
+
+  if (!IS_ITEMP (IC_RIGHT (ic))) {
+    debugLog ("  %d - not packing - right is not temp\n", __LINE__);
+    allocDirReg(IC_RIGHT (ic));
+    return 0;
+  }
+
+  if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
     {
+      debugLog ("  %d - not packing - right side fails \n", __LINE__);
       return 0;
     }
 
@@ -2097,7 +2747,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
          IS_OP_VOLATILE (IC_RESULT (dic)))
        {
-         debugLog ("  %d - \n", __LINE__);
+         debugLog ("  %d - dic is VOLATILE \n", __LINE__);
          dic = NULL;
          break;
        }
@@ -2105,7 +2755,9 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
       if (IS_SYMOP (IC_RESULT (dic)) &&
          IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
        {
-         debugLog ("  %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
+         /* A previous result was assigned to the same register - we'll our definition */
+         debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
+                   __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
          if (POINTER_SET (dic))
            dic = NULL;
 
@@ -2116,7 +2768,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
          (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
           IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
        {
-         debugLog ("  %d - \n", __LINE__);
+         debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
          dic = NULL;
          break;
        }
@@ -2125,7 +2777,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
          (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
           IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
        {
-         debugLog ("  %d - \n", __LINE__);
+         debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
          dic = NULL;
          break;
        }
@@ -2133,7 +2785,8 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
       if (POINTER_SET (dic) &&
          IC_RESULT (dic)->key == IC_RESULT (ic)->key)
        {
-         debugLog ("  %d - \n", __LINE__);
+         debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
+                   __LINE__);
          dic = NULL;
          break;
        }
@@ -2162,9 +2815,11 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
     }
 pack:
   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
+  debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
   /* 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)
@@ -2182,6 +2837,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);
   return 1;
@@ -2299,6 +2955,7 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
        IC_RIGHT (dic)->operand.symOperand;
       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
       remiCodeFromeBBlock (ebp, dic);
+      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
       change++;
     }
@@ -2336,6 +2993,7 @@ right:
       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
 
       remiCodeFromeBBlock (ebp, dic);
+      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
       change++;
     }
@@ -2397,7 +3055,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
      a function call */
   if (dic->op == CALL || dic->op == PCALL)
     {
-      if (ic->op != SEND && ic->op != RETURN)
+      if (ic->op != SEND && ic->op != RETURN &&
+         !POINTER_SET(ic) && !POINTER_GET(ic))
        {
          OP_SYMBOL (op)->ruonly = 1;
          return dic;
@@ -2514,11 +3173,19 @@ packRegsForAccUse (iCode * ic)
   iCode *uic;
 
   debugLog ("%s\n", __FUNCTION__);
+
+  /* if this is an aggregate, e.g. a one byte char array */
+  if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
+    return;
+  }
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
+
   /* if + or - then it has to be one byte result */
   if ((ic->op == '+' || ic->op == '-')
       && getSize (operandType (IC_RESULT (ic))) > 1)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* if shift operation make sure right side is not a literal */
   if (ic->op == RIGHT_OP &&
       (isOperandLiteral (IC_RIGHT (ic)) ||
@@ -2548,6 +3215,7 @@ packRegsForAccUse (iCode * ic)
                               bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   if (ic->next != uic)
     return;
 
@@ -2564,6 +3232,7 @@ packRegsForAccUse (iCode * ic)
       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   if (uic->op != '=' &&
       !IS_ARITHMETIC_OP (uic) &&
       !IS_BITWISE_OP (uic) &&
@@ -2571,6 +3240,7 @@ packRegsForAccUse (iCode * ic)
       uic->op != RIGHT_OP)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* if used in ^ operation then make sure right is not a 
      literl */
   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
@@ -2611,14 +3281,17 @@ packRegsForAccUse (iCode * ic)
       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* if one of them is a literal then we can */
-  if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
-      (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
+  if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
+       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
+       (getSize (operandType (IC_RESULT (uic))) <= 1))
     {
       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
       return;
     }
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* if the other one is not on stack then we can */
   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
       (IS_ITEMP (IC_RIGHT (uic)) ||
@@ -2635,6 +3308,7 @@ packRegsForAccUse (iCode * ic)
   return;
 
 accuse:
+  debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
 
 
@@ -2706,9 +3380,57 @@ packForPush (iCode * ic, eBBlock * ebp)
   IC_LEFT (ic) = IC_RIGHT (dic);
 
   remiCodeFromeBBlock (ebp, dic);
+  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
 }
 
+void printSymType(char * str, sym_link *sl)
+{
+  debugLog ("    %s Symbol type: ",str);
+  printTypeChain( sl, debugF);
+  debugLog ("\n");
+
+}
+
+/*-----------------------------------------------------------------*/
+/* 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                                      */
@@ -2721,259 +3443,299 @@ packRegisters (eBBlock * ebp)
 
   debugLog ("%s\n", __FUNCTION__);
 
-  while (1)
-    {
+  while (1) {
 
-      change = 0;
+    change = 0;
 
-      /* look for assignments of the form */
-      /* iTempNN = TRueSym (someoperation) SomeOperand */
-      /*       ....                       */
-      /* TrueSym := iTempNN:1             */
-      for (ic = ebp->sch; ic; ic = ic->next)
-       {
+    /* look for assignments of the form */
+    /* iTempNN = TRueSym (someoperation) SomeOperand */
+    /*       ....                       */
+    /* TrueSym := iTempNN:1             */
+    for (ic = ebp->sch; ic; ic = ic->next)
+      {
 
-         /* find assignment of the form TrueSym := iTempNN:1 */
-         if (ic->op == '=' && !POINTER_SET (ic))
-           change += packRegsForAssign (ic, ebp);
-         /* debug stuff */
-         if (ic->op == '=')
-           {
-             if (POINTER_SET (ic))
-               debugLog ("pointer is set\n");
-             debugAopGet ("  result:", IC_RESULT (ic));
-             debugAopGet ("  left:", IC_LEFT (ic));
-             debugAopGet ("  right:", IC_RIGHT (ic));
-           }
+       /* find assignment of the form TrueSym := iTempNN:1 */
+       if (ic->op == '=' && !POINTER_SET (ic))
+         change += packRegsForAssign (ic, ebp);
+       /* debug stuff */
+       if (ic->op == '=')
+         {
+           if (POINTER_SET (ic))
+             debugLog ("pointer is set\n");
+           debugAopGet ("  result:", IC_RESULT (ic));
+           debugAopGet ("  left:", IC_LEFT (ic));
+           debugAopGet ("  right:", IC_RIGHT (ic));
+         }
 
-       }
+      }
+
+    if (!change)
+      break;
+  }
+
+  for (ic = ebp->sch; ic; ic = ic->next) {
+
+    if(IS_SYMOP ( 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\n");
 
-      if (!change)
-       break;
+      if(IS_OP_VOLATILE(IC_LEFT(ic)))
+       debugLog ("    is volatile\n");
+
+      isData(etype);
+
+      printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
     }
 
-  for (ic = ebp->sch; ic; ic = ic->next)
-    {
+    if(IS_SYMOP ( IC_RIGHT(ic))) {
+      debugAopGet ("  right:", IC_RIGHT (ic));
+      printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
+    }
 
-      /* if this is an itemp & result of a address of a true sym 
-         then mark this as rematerialisable   */
-      if (ic->op == ADDRESS_OF &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
-         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
-         !OP_SYMBOL (IC_LEFT (ic))->onStack)
-       {
+    if(IS_SYMOP ( IC_RESULT(ic))) {
+      debugAopGet ("  result:", IC_RESULT (ic));
+      printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
+    }
 
-         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
-         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+    if (POINTER_SET (ic))
+       debugLog ("  %d - Pointer set\n", __LINE__);
 
-       }
 
-      /* if straight assignment then carry remat flag if
-         this is the only definition */
-      if (ic->op == '=' &&
-         !POINTER_SET (ic) &&
-         IS_SYMOP (IC_RIGHT (ic)) &&
-         OP_SYMBOL (IC_RIGHT (ic))->remat &&
-         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
-       {
+    /* if this is an itemp & result of a address of a true sym 
+       then mark this as rematerialisable   */
+    if (ic->op == ADDRESS_OF &&
+       IS_ITEMP (IC_RESULT (ic)) &&
+       IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+       bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+       !OP_SYMBOL (IC_LEFT (ic))->onStack)
+      {
 
-         OP_SYMBOL (IC_RESULT (ic))->remat =
-           OP_SYMBOL (IC_RIGHT (ic))->remat;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
-           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
-       }
+       debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
 
-      /* if this is a +/- operation with a rematerizable 
-         then mark this as rematerializable as well */
-      if ((ic->op == '+' || ic->op == '-') &&
-         (IS_SYMOP (IC_LEFT (ic)) &&
-          IS_ITEMP (IC_RESULT (ic)) &&
-          OP_SYMBOL (IC_LEFT (ic))->remat &&
-          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
-          IS_OP_LITERAL (IC_RIGHT (ic))))
-       {
+       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
 
-         //int i = 
-         operandLitValue (IC_RIGHT (ic));
-         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
-         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
-       }
+      }
 
-      /* mark the pointer usages */
-      if (POINTER_SET (ic))
-       {
-         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
-         debugLog ("  marking as a pointer (set)\n");
-       }
-      if (POINTER_GET (ic))
-       {
-         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
-         debugLog ("  marking as a pointer (get)\n");
-       }
+    /* if straight assignment then carry remat flag if
+       this is the only definition */
+    if (ic->op == '=' &&
+       !POINTER_SET (ic) &&
+       IS_SYMOP (IC_RIGHT (ic)) &&
+       OP_SYMBOL (IC_RIGHT (ic))->remat &&
+       bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+      {
+       debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
 
-      if (!SKIP_IC2 (ic))
-       {
-         /* if we are using a symbol on the stack
-            then we should say pic14_ptrRegReq */
-         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
-           pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
-                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
-         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
-           pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
-                             OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
-         else
-           {
-             if (IS_SYMOP (IC_LEFT (ic)))
-               pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
-                               OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
-             if (IS_SYMOP (IC_RIGHT (ic)))
-               pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
-                              OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
-             if (IS_SYMOP (IC_RESULT (ic)))
-               pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
-                             OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
-           }
-       }
+       OP_SYMBOL (IC_RESULT (ic))->remat =
+         OP_SYMBOL (IC_RIGHT (ic))->remat;
+       OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+         OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+      }
 
-      /* if the condition of an if instruction
-         is defined in the previous instruction then
-         mark the itemp as a conditional */
-      if ((IS_CONDITIONAL (ic) ||
-          ((ic->op == BITWISEAND ||
-            ic->op == '|' ||
-            ic->op == '^') &&
-           isBitwiseOptimizable (ic))) &&
-         ic->next && ic->next->op == IFX &&
-         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
-         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
-       {
+    /* if this is a +/- operation with a rematerizable 
+       then mark this as rematerializable as well */
+    if ((ic->op == '+' || ic->op == '-') &&
+       (IS_SYMOP (IC_LEFT (ic)) &&
+        IS_ITEMP (IC_RESULT (ic)) &&
+        OP_SYMBOL (IC_LEFT (ic))->remat &&
+        bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+        IS_OP_LITERAL (IC_RIGHT (ic))))
+      {
+       debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
+       //int i = 
+       operandLitValue (IC_RIGHT (ic));
+       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+      }
 
-         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
-         continue;
-       }
+    /* 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))
+      {
+       OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+       debugLog ("  marking as a pointer (get) =>");
+       debugAopGet ("  left:", IC_LEFT (ic));
+      }
 
-      /* reduce for support function calls */
-      if (ic->supportRtn || ic->op == '+' || ic->op == '-')
-       packRegsForSupport (ic, ebp);
-
-      /* if a parameter is passed, it's in W, so we may not
-         need to place a copy in a register */
-      if (ic->op == RECEIVE)
-       packForReceive (ic, ebp);
-
-      /* some cases the redundant moves can
-         can be eliminated for return statements */
-      if ((ic->op == RETURN || ic->op == SEND) &&
-         !isOperandInFarSpace (IC_LEFT (ic)) &&
-         !options.model)
-       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
-      /* if pointer set & left has a size more than
-         one and right is not in far space */
-      if (POINTER_SET (ic) &&
-         !isOperandInFarSpace (IC_RIGHT (ic)) &&
-         !OP_SYMBOL (IC_RESULT (ic))->remat &&
-         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
-         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
-
-       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
-
-      /* if pointer get */
-      if (POINTER_GET (ic) &&
-         !isOperandInFarSpace (IC_RESULT (ic)) &&
-         !OP_SYMBOL (IC_LEFT (ic))->remat &&
-         !IS_OP_RUONLY (IC_RESULT (ic)) &&
-         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
-
-       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
-
-      /* if this is cast for intergral promotion then
-         check if only use of  the definition of the 
-         operand being casted/ if yes then replace
-         the result of that arithmetic operation with 
-         this result and get rid of the cast */
-      if (ic->op == CAST)
-       {
-         sym_link *fromType = operandType (IC_RIGHT (ic));
-         sym_link *toType = operandType (IC_LEFT (ic));
+    if (!SKIP_IC2 (ic))
+      {
+       /* if we are using a symbol on the stack
+          then we should say pic14_ptrRegReq */
+       if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
+         pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
+                              OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
+       else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
+         pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
+                              OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
+       else
+         {
+           if (IS_SYMOP (IC_LEFT (ic)))
+             pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
+                                  OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
+           if (IS_SYMOP (IC_RIGHT (ic)))
+             pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
+                                  OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
+           if (IS_SYMOP (IC_RESULT (ic)))
+             pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
+                                  OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
+         }
 
-         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
-             getSize (fromType) != getSize (toType))
-           {
+       debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
 
-             iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
-             if (dic)
-               {
-                 if (IS_ARITHMETIC_OP (dic))
-                   {
-                     IC_RESULT (dic) = IC_RESULT (ic);
-                     remiCodeFromeBBlock (ebp, ic);
-                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-                     ic = ic->prev;
-                   }
-                 else
-                   OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
-               }
-           }
-         else
-           {
+      }
 
-             /* if the type from and type to are the same
-                then if this is the only use then packit */
-             if (compareType (operandType (IC_RIGHT (ic)),
-                            operandType (IC_LEFT (ic))) == 1)
-               {
-                 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
-                 if (dic)
-                   {
-                     IC_RESULT (dic) = IC_RESULT (ic);
-                     remiCodeFromeBBlock (ebp, ic);
-                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-                     ic = ic->prev;
-                   }
-               }
-           }
-       }
+    /* if the condition of an if instruction
+       is defined in the previous instruction then
+       mark the itemp as a conditional */
+    if ((IS_CONDITIONAL (ic) ||
+        ((ic->op == BITWISEAND ||
+          ic->op == '|' ||
+          ic->op == '^') &&
+         isBitwiseOptimizable (ic))) &&
+       ic->next && ic->next->op == IFX &&
+       isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+       OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+      {
 
-      /* pack for PUSH 
-         iTempNN := (some variable in farspace) V1
-         push iTempNN ;
-         -------------
-         push V1
-       */
-      if (ic->op == IPUSH)
-       {
-         packForPush (ic, ebp);
+       debugLog ("  %d\n", __LINE__);
+       OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+       continue;
+      }
+
+    /* reduce for support function calls */
+    if (ic->supportRtn || ic->op == '+' || ic->op == '-')
+      packRegsForSupport (ic, ebp);
+
+    /* if a parameter is passed, it's in W, so we may not
+       need to place a copy in a register */
+    if (ic->op == RECEIVE)
+      packForReceive (ic, ebp);
+
+    /* some cases the redundant moves can
+       can be eliminated for return statements */
+    if ((ic->op == RETURN || ic->op == SEND) &&
+       !isOperandInFarSpace (IC_LEFT (ic)) &&
+       !options.model)
+      packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+    /* if pointer set & left has a size more than
+       one and right is not in far space */
+    if (POINTER_SET (ic) &&
+       !isOperandInFarSpace (IC_RIGHT (ic)) &&
+       !OP_SYMBOL (IC_RESULT (ic))->remat &&
+       !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+       getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
+
+      packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+
+    /* if pointer get */
+    if (POINTER_GET (ic) &&
+       !isOperandInFarSpace (IC_RESULT (ic)) &&
+       !OP_SYMBOL (IC_LEFT (ic))->remat &&
+       !IS_OP_RUONLY (IC_RESULT (ic)) &&
+       getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
+
+      packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+
+    /* if this is cast for intergral promotion then
+       check if only use of  the definition of the 
+       operand being casted/ if yes then replace
+       the result of that arithmetic operation with 
+       this result and get rid of the cast */
+    if (ic->op == CAST) {
+       
+      sym_link *fromType = operandType (IC_RIGHT (ic));
+      sym_link *toType = operandType (IC_LEFT (ic));
+
+      debugLog ("  %d - casting\n", __LINE__);
+
+      if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
+         getSize (fromType) != getSize (toType)) {
+           
+
+       iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+       if (dic) {
+               
+         if (IS_ARITHMETIC_OP (dic)) {
+                   
+           bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+           IC_RESULT (dic) = IC_RESULT (ic);
+           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);
+           ic = ic->prev;
+         }  else
+               
+           OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
+       }
+      } else {
+
+       /* if the type from and type to are the same
+          then if this is the only use then packit */
+       if (compareType (operandType (IC_RIGHT (ic)),
+                        operandType (IC_LEFT (ic))) == 1) {
+               
+         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+         if (dic) {
+                   
+           bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+           IC_RESULT (dic) = IC_RESULT (ic);
+           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);
+           ic = ic->prev;
+         }
        }
+      }
+    }
 
+    /* pack for PUSH 
+       iTempNN := (some variable in farspace) V1
+       push iTempNN ;
+       -------------
+       push V1
+    */
+    if (ic->op == IPUSH)
+      {
+       packForPush (ic, ebp);
+      }
 
-      /* pack registers for accumulator use, when the
-         result of an arithmetic or bit wise operation
-         has only one use, that use is immediately following
-         the defintion and the using iCode has only one
-         operand or has two operands but one is literal &
-         the result of that operation is not on stack then
-         we can leave the result of this operation in acc:b
-         combination */
-      if ((IS_ARITHMETIC_OP (ic)
 
-          || IS_BITWISE_OP (ic)
+    /* pack registers for accumulator use, when the
+       result of an arithmetic or bit wise operation
+       has only one use, that use is immediately following
+       the defintion and the using iCode has only one
+       operand or has two operands but one is literal &
+       the result of that operation is not on stack then
+       we can leave the result of this operation in acc:b
+       combination */
+    if ((IS_ARITHMETIC_OP (ic)
 
-          || ic->op == LEFT_OP || ic->op == RIGHT_OP
+        || IS_BITWISE_OP (ic)
 
-         ) &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         getSize (operandType (IC_RESULT (ic))) <= 2)
+        || ic->op == LEFT_OP || ic->op == RIGHT_OP
 
-       packRegsForAccUse (ic);
+        ) &&
+       IS_ITEMP (IC_RESULT (ic)) &&
+       getSize (operandType (IC_RESULT (ic))) <= 2)
 
-    }
+      packRegsForAccUse (ic);
+
+  }
 }
 
 static void
@@ -3029,7 +3791,7 @@ pic14_assignRegisters (eBBlock ** ebbs, int count)
   int i;
 
   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
-  debugLog ("ebbs before optimizing:\n");
+  debugLog ("\nebbs before optimizing:\n");
   dumpEbbsToDebug (ebbs, count);
 
   setToNull ((void *) &_G.funcrUsed);
@@ -3041,6 +3803,21 @@ pic14_assignRegisters (eBBlock ** ebbs, int count)
   for (i = 0; i < count; i++)
     packRegisters (ebbs[i]);
 
+  {
+    regs *reg;
+    int hkey;
+    int i=0;
+
+    debugLog("dir registers allocated so far:\n");
+    reg = hTabFirstItem(dynDirectRegNames, &hkey);
+
+    while(reg) {
+      debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
+      reg = hTabNextItem(dynDirectRegNames, &hkey);
+    }
+
+  }
+
   if (options.dump_pack)
     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
 
@@ -3091,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 ();