* sim/ucsim/cmd.src/cmdutil.cc: NUL device is detected as CG_FILE type
[fw/sdcc] / src / pic16 / ralloc.c
index cb96f41e1b37f5943dfb359fcab2dd69cbbd45d9..1319ff89e97ba01cb0ae31a4c2cc8463879e9117 100644 (file)
 #include "ralloc.h"
 #include "pcode.h"
 #include "gen.h"
+#include "device.h"
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
+#ifndef debugf
+#define debugf(frm, rest)       _debugf(__FILE__, __LINE__, frm, rest)
 #endif
+void _debugf(char *f, int l, char *frm, ...);
+
+#define NEWREG_DEBUG   0
+//#define USE_ONSTACK
+
 
 /*-----------------------------------------------------------------*/
 /* At this point we start getting processor specific although      */
@@ -45,9 +49,8 @@
 /* since the pack the registers depending strictly on the MCU      */
 /*-----------------------------------------------------------------*/
 
-static regs *typeRegWithIdx (int idx, int type, int fixed);
+regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
 extern void genpic16Code (iCode *);
-extern void pic16_assignConfigWordValue(int address, int value);
 
 /* Global data */
 static struct
@@ -73,15 +76,25 @@ set *pic16_dynProcessorRegs=NULL;
 set *pic16_dynDirectRegs=NULL;
 set *pic16_dynDirectBitRegs=NULL;
 set *pic16_dynInternalRegs=NULL;
+set *pic16_dynAccessRegs=NULL;
 
-static hTab  *dynDirectRegNames= NULL;
+static hTab *dynDirectRegNames=NULL;
+static hTab *dynAllocRegNames=NULL;
+static hTab *dynProcRegNames=NULL;
+static hTab *dynAccessRegNames=NULL;
 //static hTab  *regHash = NULL;    /* a hash table containing ALL registers */
 
-set *pic16_rel_udata=NULL;
-set *pic16_fix_udata=NULL;
+extern set *sectNames;
 
+set *pic16_rel_udata=NULL;     /* relocatable uninitialized registers */
+set *pic16_fix_udata=NULL;     /* absolute uninitialized registers */
+set *pic16_equ_data=NULL;      /* registers used by equates */
+set *pic16_int_regs=NULL;      /* internal registers placed in access bank 0 to 0x7f */
+set *pic16_acs_udata=NULL;     /* access bank variables */
 
-static int dynrIdx=0x20;
+set *pic16_builtin_functions=NULL;
+
+static int dynrIdx=0x00;               //0x20;         // starting temporary register rIdx
 static int rDirectIdx=0;
 
 int pic16_nRegs = 128;   // = sizeof (regspic16) / sizeof (regs);
@@ -90,10 +103,12 @@ int pic16_Gstack_base_addr=0; /* The starting address of registers that
                         * are used to pass and return parameters */
 
 
-
+int _inRegAllocator=0; /* flag that marks whther allocReg happens while
+                         * inside the register allocator function */
+                         
 
 static void spillThis (symbol *);
-static int debug = 1;
+int pic16_ralloc_debug = 0;
 static FILE *debugF = NULL;
 /*-----------------------------------------------------------------*/
 /* debugLog - open a file for debugging information                */
@@ -108,7 +123,7 @@ debugLog (char *fmt,...)
   //char *bufferP=buffer;
   va_list ap;
 
-  if (!debug || !dstFileName)
+  if (!pic16_ralloc_debug || !dstFileName)
     return;
 
 
@@ -132,8 +147,9 @@ debugLog (char *fmt,...)
   vsprintf (buffer, fmt, ap);
 
   fprintf (debugF, "%s", buffer);
+  //fprintf (stderr, "%s", buffer);
 /*
-   while (isspace(*bufferP)) bufferP++;
+   while (isspace((unsigned char)*bufferP)) bufferP++;
 
    if (bufferP && *bufferP) 
    lineCurr = (lineCurr ?
@@ -149,6 +165,8 @@ debugLog (char *fmt,...)
 static void
 debugNewLine (void)
 {
+  if(!pic16_ralloc_debug)return;
+
   if (debugF)
     fputc ('\n', debugF);
 }
@@ -158,263 +176,173 @@ debugNewLine (void)
 static void
 debugLogClose (void)
 {
-  if (debugF)
-    {
-      fclose (debugF);
-      debugF = NULL;
-    }
+  if (debugF) {
+    fclose (debugF);
+    debugF = NULL;
+  }
 }
+
 #define AOP(op) op->aop
 
 static char *
 debugAopGet (char *str, operand * op)
 {
-  if (str)
-    debugLog (str);
+       if(!pic16_ralloc_debug)return NULL;
 
-  printOperand (op, debugF);
-  debugNewLine ();
+       if (str)
+               debugLog (str);
 
-  return NULL;
+       printOperand (op, debugF);
+       debugNewLine ();
 
+  return NULL;
 }
 
-static char *
-decodeOp (unsigned int op)
+char *
+pic16_decodeOp (unsigned int op)
 {
+       if (op < 128 && op > ' ') {
+               buffer[0] = (op & 0xff);
+               buffer[1] = 0;
+         return buffer;
+       }
 
-  if (op < 128 && op > ' ')
-    {
-      buffer[0] = (op & 0xff);
-      buffer[1] = 0;
-      return buffer;
-    }
+       switch (op) {
+               case IDENTIFIER:        return "IDENTIFIER";
+               case TYPE_NAME:         return "TYPE_NAME";
+               case CONSTANT:          return "CONSTANT";
+               case STRING_LITERAL:    return "STRING_LITERAL";
+               case SIZEOF:            return "SIZEOF";
+               case PTR_OP:            return "PTR_OP";
+               case INC_OP:            return "INC_OP";
+               case DEC_OP:            return "DEC_OP";
+               case LEFT_OP:           return "LEFT_OP";
+               case RIGHT_OP:          return "RIGHT_OP";
+               case LE_OP:             return "LE_OP";
+               case GE_OP:             return "GE_OP";
+               case EQ_OP:             return "EQ_OP";
+               case NE_OP:             return "NE_OP";
+               case AND_OP:            return "AND_OP";
+               case OR_OP:             return "OR_OP";
+               case MUL_ASSIGN:        return "MUL_ASSIGN";
+               case DIV_ASSIGN:        return "DIV_ASSIGN";
+               case MOD_ASSIGN:        return "MOD_ASSIGN";
+               case ADD_ASSIGN:        return "ADD_ASSIGN";
+               case SUB_ASSIGN:        return "SUB_ASSIGN";
+               case LEFT_ASSIGN:       return "LEFT_ASSIGN";
+               case RIGHT_ASSIGN:      return "RIGHT_ASSIGN";
+               case AND_ASSIGN:        return "AND_ASSIGN";
+               case XOR_ASSIGN:        return "XOR_ASSIGN";
+               case OR_ASSIGN:         return "OR_ASSIGN";
+               case TYPEDEF:           return "TYPEDEF";
+               case EXTERN:            return "EXTERN";
+               case STATIC:            return "STATIC";
+               case AUTO:              return "AUTO";
+               case REGISTER:          return "REGISTER";
+               case CODE:              return "CODE";
+               case EEPROM:            return "EEPROM";
+               case INTERRUPT:         return "INTERRUPT";
+               case SFR:               return "SFR";
+               case AT:                return "AT";
+               case SBIT:              return "SBIT";
+               case REENTRANT:         return "REENTRANT";
+               case USING:             return "USING";
+               case XDATA:             return "XDATA";
+               case DATA:              return "DATA";
+               case IDATA:             return "IDATA";
+               case PDATA:             return "PDATA";
+               case VAR_ARGS:          return "VAR_ARGS";
+               case CRITICAL:          return "CRITICAL";
+               case NONBANKED:         return "NONBANKED";
+               case BANKED:            return "BANKED";
+               case CHAR:              return "CHAR";
+               case SHORT:             return "SHORT";
+               case INT:               return "INT";
+               case LONG:              return "LONG";
+               case SIGNED:            return "SIGNED";
+               case UNSIGNED:          return "UNSIGNED";
+               case FLOAT:             return "FLOAT";
+               case DOUBLE:            return "DOUBLE";
+               case CONST:             return "CONST";
+               case VOLATILE:          return "VOLATILE";
+               case VOID:              return "VOID";
+               case BIT:               return "BIT";
+               case STRUCT:            return "STRUCT";
+               case UNION:             return "UNION";
+               case ENUM:              return "ENUM";
+               case RANGE:             return "RANGE";
+               case FAR:               return "FAR";
+               case CASE:              return "CASE";
+               case DEFAULT:           return "DEFAULT";
+               case IF:                return "IF";
+               case ELSE:              return "ELSE";
+               case SWITCH:            return "SWITCH";
+               case WHILE:             return "WHILE";
+               case DO:                return "DO";
+               case FOR:               return "FOR";
+               case GOTO:              return "GOTO";
+               case CONTINUE:          return "CONTINUE";
+               case BREAK:             return "BREAK";
+               case RETURN:            return "RETURN";
+               case INLINEASM:         return "INLINEASM";
+               case IFX:               return "IFX";
+               case ADDRESS_OF:        return "ADDRESS_OF";
+               case GET_VALUE_AT_ADDRESS:      return "GET_VALUE_AT_ADDRESS";
+               case SPIL:              return "SPIL";
+               case UNSPIL:            return "UNSPIL";
+               case GETHBIT:           return "GETHBIT";
+               case BITWISEAND:        return "BITWISEAND";
+               case UNARYMINUS:        return "UNARYMINUS";
+               case IPUSH:             return "IPUSH";
+               case IPOP:              return "IPOP";
+               case PCALL:             return "PCALL";
+                case FUNCTION:          return "FUNCTION";
+               case ENDFUNCTION:       return "ENDFUNCTION";
+               case JUMPTABLE:         return "JUMPTABLE";
+               case RRC:               return "RRC";
+               case RLC:               return "RLC";
+               case CAST:              return "CAST";
+               case CALL:              return "CALL";
+               case PARAM:             return "PARAM  ";
+               case NULLOP:            return "NULLOP";
+               case BLOCK:             return "BLOCK";
+               case LABEL:             return "LABEL";
+               case RECEIVE:           return "RECEIVE";
+               case SEND:              return "SEND";
+               case DUMMY_READ_VOLATILE:       return "DUMMY_READ_VOLATILE";
+       }
+       sprintf (buffer, "unkown op %d %c", op, op & 0xff);
 
-  switch (op)
-    {
-    case IDENTIFIER:
-      return "IDENTIFIER";
-    case TYPE_NAME:
-      return "TYPE_NAME";
-    case CONSTANT:
-      return "CONSTANT";
-    case STRING_LITERAL:
-      return "STRING_LITERAL";
-    case SIZEOF:
-      return "SIZEOF";
-    case PTR_OP:
-      return "PTR_OP";
-    case INC_OP:
-      return "INC_OP";
-    case DEC_OP:
-      return "DEC_OP";
-    case LEFT_OP:
-      return "LEFT_OP";
-    case RIGHT_OP:
-      return "RIGHT_OP";
-    case LE_OP:
-      return "LE_OP";
-    case GE_OP:
-      return "GE_OP";
-    case EQ_OP:
-      return "EQ_OP";
-    case NE_OP:
-      return "NE_OP";
-    case AND_OP:
-      return "AND_OP";
-    case OR_OP:
-      return "OR_OP";
-    case MUL_ASSIGN:
-      return "MUL_ASSIGN";
-    case DIV_ASSIGN:
-      return "DIV_ASSIGN";
-    case MOD_ASSIGN:
-      return "MOD_ASSIGN";
-    case ADD_ASSIGN:
-      return "ADD_ASSIGN";
-    case SUB_ASSIGN:
-      return "SUB_ASSIGN";
-    case LEFT_ASSIGN:
-      return "LEFT_ASSIGN";
-    case RIGHT_ASSIGN:
-      return "RIGHT_ASSIGN";
-    case AND_ASSIGN:
-      return "AND_ASSIGN";
-    case XOR_ASSIGN:
-      return "XOR_ASSIGN";
-    case OR_ASSIGN:
-      return "OR_ASSIGN";
-    case TYPEDEF:
-      return "TYPEDEF";
-    case EXTERN:
-      return "EXTERN";
-    case STATIC:
-      return "STATIC";
-    case AUTO:
-      return "AUTO";
-    case REGISTER:
-      return "REGISTER";
-    case CODE:
-      return "CODE";
-    case EEPROM:
-      return "EEPROM";
-    case INTERRUPT:
-      return "INTERRUPT";
-    case SFR:
-      return "SFR";
-    case AT:
-      return "AT";
-    case SBIT:
-      return "SBIT";
-    case REENTRANT:
-      return "REENTRANT";
-    case USING:
-      return "USING";
-    case XDATA:
-      return "XDATA";
-    case DATA:
-      return "DATA";
-    case IDATA:
-      return "IDATA";
-    case PDATA:
-      return "PDATA";
-    case VAR_ARGS:
-      return "VAR_ARGS";
-    case CRITICAL:
-      return "CRITICAL";
-    case NONBANKED:
-      return "NONBANKED";
-    case BANKED:
-      return "BANKED";
-    case CHAR:
-      return "CHAR";
-    case SHORT:
-      return "SHORT";
-    case INT:
-      return "INT";
-    case LONG:
-      return "LONG";
-    case SIGNED:
-      return "SIGNED";
-    case UNSIGNED:
-      return "UNSIGNED";
-    case FLOAT:
-      return "FLOAT";
-    case DOUBLE:
-      return "DOUBLE";
-    case CONST:
-      return "CONST";
-    case VOLATILE:
-      return "VOLATILE";
-    case VOID:
-      return "VOID";
-    case BIT:
-      return "BIT";
-    case STRUCT:
-      return "STRUCT";
-    case UNION:
-      return "UNION";
-    case ENUM:
-      return "ENUM";
-    case ELIPSIS:
-      return "ELIPSIS";
-    case RANGE:
-      return "RANGE";
-    case FAR:
-      return "FAR";
-    case CASE:
-      return "CASE";
-    case DEFAULT:
-      return "DEFAULT";
-    case IF:
-      return "IF";
-    case ELSE:
-      return "ELSE";
-    case SWITCH:
-      return "SWITCH";
-    case WHILE:
-      return "WHILE";
-    case DO:
-      return "DO";
-    case FOR:
-      return "FOR";
-    case GOTO:
-      return "GOTO";
-    case CONTINUE:
-      return "CONTINUE";
-    case BREAK:
-      return "BREAK";
-    case RETURN:
-      return "RETURN";
-    case INLINEASM:
-      return "INLINEASM";
-    case IFX:
-      return "IFX";
-    case ADDRESS_OF:
-      return "ADDRESS_OF";
-    case GET_VALUE_AT_ADDRESS:
-      return "GET_VALUE_AT_ADDRESS";
-    case SPIL:
-      return "SPIL";
-    case UNSPIL:
-      return "UNSPIL";
-    case GETHBIT:
-      return "GETHBIT";
-    case BITWISEAND:
-      return "BITWISEAND";
-    case UNARYMINUS:
-      return "UNARYMINUS";
-    case IPUSH:
-      return "IPUSH";
-    case IPOP:
-      return "IPOP";
-    case PCALL:
-      return "PCALL";
-    case ENDFUNCTION:
-      return "ENDFUNCTION";
-    case JUMPTABLE:
-      return "JUMPTABLE";
-    case RRC:
-      return "RRC";
-    case RLC:
-      return "RLC";
-    case CAST:
-      return "CAST";
-    case CALL:
-      return "CALL";
-    case PARAM:
-      return "PARAM  ";
-    case NULLOP:
-      return "NULLOP";
-    case BLOCK:
-      return "BLOCK";
-    case LABEL:
-      return "LABEL";
-    case RECEIVE:
-      return "RECEIVE";
-    case SEND:
-      return "SEND";
-    }
-  sprintf (buffer, "unkown op %d %c", op, op & 0xff);
   return buffer;
 }
+
+#if 0
+static char *decodeRegType(short type)
+{
+       switch(type) {
+               case REG_GPR: return "REG_GPR";
+               case REG_PTR: return "REG_PTR";
+               case REG_CND: return "REG_CNT";
+       
+       default:
+               return "<unknown>";
+       }
+}
+#endif
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 static char *
 debugLogRegType (short type)
 {
+       if(!pic16_ralloc_debug)return NULL;
+       switch (type) {
+               case REG_GPR: return "REG_GPR";
+               case REG_PTR: return "REG_PTR";
+               case REG_CND: return "REG_CND";
+       }
+       sprintf (buffer, "unknown reg type %d", type);
 
-  switch (type)
-    {
-    case REG_GPR:
-      return "REG_GPR";
-    case REG_PTR:
-      return "REG_PTR";
-    case REG_CND:
-      return "REG_CND";
-    }
-
-  sprintf (buffer, "unknown reg type %d", type);
   return buffer;
 }
 
@@ -440,7 +368,7 @@ static int regname2key(char const *name)
 /*-----------------------------------------------------------------*/
 /* 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, operand *refop)
+regs* newReg(int type, short pc_type, int rIdx, char *name, unsigned size, int alias, operand *refop)
 {
 
   regs *dReg;
@@ -452,28 +380,36 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
        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);
+          if(xinst && pc_type == PO_GPR_TEMP) {
+            sprintf(buffer,"0x%02x", dReg->rIdx);
+          } 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;
-
-//     dReg->isMapped = 0;
        dReg->isEmitted = 0;
-       dReg->accessBank = 0;
 
        if(type == REG_SFR) {
                dReg->isFixed = 1;
                dReg->address = rIdx;
+               dReg->accessBank = 1;
        } else {
                dReg->isFixed = 0;
                dReg->address = 0;
+               dReg->accessBank = 0;
        }
-       
+
+#if NEWREG_DEBUG
+       fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
+#endif
        dReg->size = size;
        dReg->alias = alias;
        dReg->reg_alias = NULL;
@@ -481,7 +417,8 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
        dReg->reglives.assignedpFlows = newSet();
        dReg->regop = refop;
   
-       hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+       if(!(type == REG_SFR && alias == 0x80))
+               hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
 
   return dReg;
 }
@@ -490,16 +427,22 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
 /* regWithIdx - Search through a set of registers that matches idx */
 /*-----------------------------------------------------------------*/
 static regs *
-regWithIdx (set *dRegs, int idx, int fixed)
+regWithIdx (set *dRegs, int idx, unsigned fixed)
 {
   regs *dReg;
 
+//#define D(text)      text
+#define D(text)
+
   for (dReg = setFirstItem(dRegs) ; dReg ; 
        dReg = setNextItem(dRegs)) {
 
+       D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed));
     if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
+         D(fprintf(stderr, "found!\n"));
       return dReg;
-    }
+    } else
+         D(fprintf(stderr, "not found!\n"));
   }
 
   return NULL;
@@ -516,12 +459,38 @@ regFindFree (set *dRegs)
   for (dReg = setFirstItem(dRegs) ; dReg ; 
        dReg = setNextItem(dRegs)) {
 
-    if(dReg->isFree)
+//     fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
+//             __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
+
+    if(dReg->isFree) {
+//             fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx);
+               
       return dReg;
+    }
   }
 
   return NULL;
 }
+
+static regs *
+regFindFreeNext(set *dRegs, regs *creg)
+{
+  regs *dReg;
+
+    if(creg) {
+      /* position at current register */
+      for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
+    }
+    
+    for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
+      if(dReg->isFree) {
+        return dReg;
+      }
+    }
+  
+  return NULL;
+}
+
 /*-----------------------------------------------------------------*/
 /* pic16_initStack - allocate registers for a pseudo stack               */
 /*-----------------------------------------------------------------*/
@@ -549,6 +518,8 @@ pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
        reg->wasUsed = 0;               // we do not know if they are going to be used at all
        reg->accessBank = 1;            // implicit add access Bank
 
+       hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
+
   return addSet(&pic16_dynProcessorRegs, reg);
 }
 
@@ -560,27 +531,77 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 {
   regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
 
-//  fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
+//  fprintf(stderr,"%s:%d: %s  %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
 
-  if(reg) {
-    reg->wasUsed = 0;
-    return addSet(&pic16_dynInternalRegs,reg);
-  }
+    if(reg) {
+      reg->wasUsed = 0;
+      return addSet(&pic16_dynInternalRegs,reg);
+    }
 
   return NULL;
 }
+
+
 /*-----------------------------------------------------------------*/
 /* allocReg - allocates register of given type                     */
 /*-----------------------------------------------------------------*/
 static regs *
 allocReg (short type)
 {
+  regs * reg=NULL;
+  
+#define MAX_P16_NREGS  16
 
-  debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
-  //fprintf(stderr,"allocReg\n");
 
+#if 0
+  if(dynrIdx > pic16_nRegs)
+       werror(W_POSSBUG2, __FILE__, __LINE__);
+       return NULL;
+#endif
 
-  return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
+       /* try to reuse some unused registers */
+       reg = regFindFree( pic16_dynAllocRegs );
+
+       if(reg) {
+//             fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
+       }
+
+       if(!reg) {
+               reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
+//             fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
+//                                     (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
+
+#if 1
+               if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
+                 //                  debugf("allocating more registers than available\n", 0);
+                 //                  return (NULL);
+               }
+               
+               addSet(&pic16_dynAllocRegs, reg);
+               hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
+//             fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
+#endif
+       }
+       
+       debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
+
+#if 0
+       fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
+               __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
+#endif
+       if(reg) {
+               reg->isFree=0;
+               reg->accessBank = 1;    /* this is a temporary register alloc in accessBank */
+               reg->isLocal = 1;       /* this is a local frame register */
+//             reg->wasUsed = 1;
+       }
+       
+       if (currFunc) {
+//             fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
+               currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
+       }
+  return (reg);                // addSet(&pic16_dynAllocRegs,reg);
 
 }
 
@@ -608,6 +629,7 @@ pic16_dirregWithName (char *name)
   while(reg) {
 
     if(STRCASECMP(reg->name, name) == 0) {
+//             fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
       return(reg);
     }
 
@@ -618,137 +640,323 @@ pic16_dirregWithName (char *name)
   return NULL; // name wasn't found in the hash table
 }
 
-static int IS_CONFIG_ADDRESS(int address)
+/*-----------------------------------------------------------------*/
+/* pic16_allocregWithName - search for register by name                    */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_allocregWithName (char *name)
 {
+  int hkey;
+  regs *reg;
+
+  if(!name)
+    return NULL;
+
+  /* hash the name to get a key */
+
+  hkey = regname2key(name);
+
+  //fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+
+  reg = hTabFirstItemWK(dynAllocRegNames, hkey);
+
+  while(reg) {
+
+    if(STRCASECMP(reg->name, name) == 0) {
+      return(reg);
+    }
+
+    reg = hTabNextItemWK (dynAllocRegNames);
+  
+  }
+
+  return NULL; // name wasn't found in the hash table
 
-  return address >= 0x300000 && address <= 0x300000d;
 }
 
+
 /*-----------------------------------------------------------------*/
-/* pic16_allocDirReg - allocates register of given type                  */
+/* pic16_procregWithName - search for register by name                    */
 /*-----------------------------------------------------------------*/
 regs *
-pic16_allocDirReg (operand *op )
+pic16_procregWithName (char *name)
 {
-
+  int hkey;
   regs *reg;
-  char *name;
 
-  if(!IS_SYMOP(op)) {
-    debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
+  if(!name)
     return NULL;
-  }
 
-  name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+  /* hash the name to get a key */
 
-  /* 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 */
+  hkey = regname2key(name);
 
-  //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
-  //name++;
+//     fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
 
-  /* The above hack is not necessery anymore, since .asm include files are not
-   * used by current implementation of the port -- VR 03-Jan-04 */
+  reg = hTabFirstItemWK(dynProcRegNames, hkey);
 
-  debugLog ("%s symbol name %s\n", __FUNCTION__,name);
-//  fprintf(stderr, "%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)));
-//      fprintf(stderr, " %d  const char\n",__LINE__);
-//      fprintf(stderr, " 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);
+  while(reg) {
+
+    if(STRCASECMP(reg->name, name) == 0) {
+      return(reg);
+    }
+
+    reg = hTabNextItemWK (dynProcRegNames);
+  
   }
 
-  if (IS_CODE ( OP_SYM_ETYPE(op)) )
+  return NULL; // name wasn't found in the hash table
+
+}
+
+/*-----------------------------------------------------------------*/
+/* pic16_accessregWithName - search for register by name           */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_accessregWithName (char *name)
+{
+  int hkey;
+  regs *reg;
+
+  if(!name)
     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 (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
+  /* hash the name to get a key */
+
+  hkey = regname2key(name);
+
+//     fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+
+  reg = hTabFirstItemWK(dynAccessRegNames, hkey);
+
+  while(reg) {
+
+    if(STRCASECMP(reg->name, name) == 0) {
+      return(reg);
+    }
+
+    reg = hTabNextItemWK (dynAccessRegNames);
+  
+  }
+
+  return NULL; // name wasn't found in the hash table
+
+}
+
+regs *pic16_regWithName(char *name)
+{
+  regs *reg;
+
+       reg = pic16_dirregWithName( name );
+       if(reg)return reg;
+       
+       reg = pic16_procregWithName( name );
+       if(reg)return reg;
+       
+       reg = pic16_allocregWithName( name );
+       if(reg)return reg;
+
+       reg = pic16_accessregWithName( name );
+       if(reg)return reg;
+       
+  return NULL;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* pic16_allocDirReg - allocates register of given type                  */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_allocDirReg (operand *op )
+{
+  regs *reg;
+  char *name;
+
+       if(!IS_SYMOP(op)) {
+               debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
+//             fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
+         return NULL;
+       }
 
+       name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+
+
+       if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
 #if 0
-    if(!reg) 
-      fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
-               __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
-    else
-      fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
-               __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
+               if(pic16_debug_verbose)
+               {
+                       fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
+                               OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
+               }
 #endif
-  } else {
-//     fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
-    
-    reg = pic16_dirregWithName(name);
-  }
+               return NULL;
+       }
 
-  if(!reg) {
-    int address = 0;
+       if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+               || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(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);
-    }
+#if 0
+               if(pic16_debug_verbose) {
+                       fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
+                               IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                               IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                               IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                               IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                               IN_STACK( OP_SYM_ETYPE(op)),
+                               SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
+                               IS_REGPARM(OP_SYM_ETYPE(op)),
+                               IS_PARM(op));
+
+                       fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
+                       OP_SYMBOL(op)->name);
+               }
+#endif
 
-    /* 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,"%s:allocating new reg %s\n",__FUNCTION__, name);
+       }
 
-      reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
-      debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
 
-      //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);       /* commented out */
 
-      if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+       if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
+//             fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
+               return NULL;
+       }
 
-       //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
-       reg->type = REG_SFR;
-      }
+       if(IS_ITEMP(op))return NULL;
+       
+//     if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
+       
+       if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
+       
+       debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
+//     fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
 
-      if (IS_BITVAR (OP_SYM_ETYPE(op))) {
-       addSet(&pic16_dynDirectBitRegs, reg);
-       reg->isBitField = 1;
-      } else
-       addSet(&pic16_dynDirectRegs, reg);
+       {
+               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)));
+//                     fprintf(stderr, " %d  const char\n",__LINE__);
+//                     fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+               }
 
-    } else {
-      debugLog ("  -- %s is declared at address 0x30000x\n",name);
-      fprintf(stderr, "  -- %s is declared at address 0x30000x\n",name);
+       
+               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__);
 
-/*
-       fprintf(stderr, "  setting config word to %x\n", 
-                 (int) floatFromVal (op->operand.valOperand)); //IC_RIGHT(ic)->operand.valOperand));
+               if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  integral\n",__LINE__);
 
-       pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
-                               (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
-*/
+               if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  literal\n",__LINE__);
 
+               if (IS_SPEC ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  specifier\n",__LINE__);
 
-      return NULL;
-    }
-  }
+               debugAopGet(NULL, op);
+       }
 
-  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 = pic16_dirregWithName(name);
+
+       if(!reg) {
+         int address = 0;
+         int regtype = REG_GPR;
+    
+               /* 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_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+                       debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
+                 return NULL;
+               }
+
+
+#if 0
+               if(OP_SYMBOL(op)->onStack) {
+                       fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
+                               OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
+               }
+#endif
+
+               if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+                       || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
+
+#if 0
+                       if(pic16_debug_verbose)
+                       {
+                               fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
+                                       IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                       IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                       IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                       IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                       IN_STACK( OP_SYM_ETYPE(op)),
+                                       SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
+
+                                       fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
+                                       OP_SYMBOL(op)->name);
+                       }
+#endif
+               }
+
+               reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
+               debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
+
+               if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
+                       fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
+                               name);
+                               
+                       reg->accessBank = 1;
+                       checkAddReg(&pic16_dynAccessRegs, reg);
+                       hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
+                       
+                 return (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))) {
+//                     fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
+                       addSet(&pic16_dynDirectBitRegs, reg);
+                       reg->isBitField = 1;
+               } else {
+//                     fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
+//                     addSet(&pic16_dynDirectRegs, reg);
+
+#if 1
+                  if(!(IS_STATIC(OP_SYM_ETYPE(op))
+                      && OP_SYMBOL(op)->ival
+                  ))
+#endif
+                    checkAddReg(&pic16_dynDirectRegs, reg);
+               }
+       
+       } else {
+//             debugLog ("  -- %s is declared at address 0x30000x\n",name);
+         return (reg);                 /* This was NULL before, but since we found it
+                                        * why not just return it?! */
+       }
+
+       if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+               reg->isFixed = 1;
+               reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+
+               /* work around for user defined registers in access bank */
+               if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
+                       || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
+                       reg->accessBank = 1;
+               
+               debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
+       }
 
   return reg;
 }
@@ -757,7 +965,7 @@ pic16_allocDirReg (operand *op )
 /* pic16_allocRegByName - allocates register of given type                  */
 /*-----------------------------------------------------------------*/
 regs *
-pic16_allocRegByName (char *name, int size)
+pic16_allocRegByName (char *name, int size, operand *op)
 {
 
   regs *reg;
@@ -775,11 +983,13 @@ pic16_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, NULL);
+
+       //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
+
+    reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
 
     debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
-    //fprintf(stderr, "  -- added %s to hash, size = %d\n", name,reg->size);
+       //fprintf(stderr, "  -- added %s to hash, size = %d\n", name,reg->size);
 
     //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
     addSet(&pic16_dynDirectRegs, reg);
@@ -791,13 +1001,13 @@ pic16_allocRegByName (char *name, int size)
 /*-----------------------------------------------------------------*/
 /* RegWithIdx - returns pointer to register with index number       */
 /*-----------------------------------------------------------------*/
-static regs *
-typeRegWithIdx (int idx, int type, int fixed)
+regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
 {
 
   regs *dReg;
 
   debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
+//  fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type));
 
   switch (type) {
 
@@ -812,6 +1022,11 @@ typeRegWithIdx (int idx, int type, int fixed)
       return dReg;
     }
 
+       if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
+      debugLog ("Found an Internal Register!\n");
+      return dReg;
+    }
+               
     break;
   case REG_STK:
     if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
@@ -820,7 +1035,7 @@ typeRegWithIdx (int idx, int type, int fixed)
     }
     break;
   case REG_SFR:
-    if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
+    if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
       debugLog ("Found a Processor Register!\n");
       return dReg;
     }
@@ -843,14 +1058,16 @@ pic16_regWithIdx (int idx)
 {
   regs *dReg;
 
-  if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
+  if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
     return dReg;
 
-  if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
+  if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
     return dReg;
 
-  if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
+#if 0
+  if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
     return dReg;
+#endif
 
   return NULL;
 }
@@ -862,16 +1079,17 @@ regs *
 pic16_allocWithIdx (int idx)
 {
 
-  regs *dReg;
+  regs *dReg=NULL;
 
   debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
+//  fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
 
   if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
 
     debugLog ("Found a Dynamic Register!\n");
   } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
     debugLog ("Found a Stack Register!\n");
-  } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
+  } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
     debugLog ("Found a Processor Register!\n");
     fprintf(stderr, "Found a processor register! %s\n", dReg->name);
   } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
@@ -880,12 +1098,19 @@ pic16_allocWithIdx (int idx)
     
     debugLog ("Dynamic Register not found\n");
 
+#if 1
+       dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL);
+       addSet(&pic16_dynAllocRegs, dReg);
+       hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg);
+#endif
 
+       if(!dReg) {
+//     return (NULL);
     //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
-    werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-           "regWithIdx not found");
-    exit (1);
-
+           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                   "allocWithIdx not found");
+           exit (1);
+       }
   }
 
   dReg->wasUsed = 1;
@@ -905,7 +1130,8 @@ pic16_findFreeReg(short type)
   case REG_GPR:
     if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
       return dReg;
-    return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
+//     return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+    return allocReg( REG_GPR );
 
   case REG_STK:
 
@@ -921,6 +1147,34 @@ pic16_findFreeReg(short type)
     return NULL;
   }
 }
+
+regs *
+pic16_findFreeRegNext(short type, regs *creg)
+{
+  //  int i;
+  regs* dReg;
+
+  switch (type) {
+  case REG_GPR:
+    if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
+      return dReg;
+//       return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+    return (allocReg( REG_GPR ) );
+
+  case REG_STK:
+
+    if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
+      return dReg;
+
+    return NULL;
+
+  case REG_PTR:
+  case REG_CND:
+  case REG_SFR:
+  default:
+    return NULL;
+  }
+}
 /*-----------------------------------------------------------------*/
 /* freeReg - frees a register                                      */
 /*-----------------------------------------------------------------*/
@@ -928,6 +1182,7 @@ static void
 freeReg (regs * reg)
 {
        debugLog ("%s\n", __FUNCTION__);
+//     fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
        reg->isFree = 1;
 }
 
@@ -938,20 +1193,27 @@ freeReg (regs * reg)
 static int
 nFreeRegs (int type)
 {
+  regs *reg;
+  int nfr=0;
+
+
+               /* although I fixed the register allocation/freeing scheme
+                * the for loop below doesn't give valid results. I do not
+                * know why yet. -- VR 10-Jan-2003 */
+                
+       return 100;
+
+
   /* 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;
-
   debugLog ("%s\n", __FUNCTION__);
-  for (i = 0; i < pic16_nRegs; i++)
-    if (regspic16[i].isFree && regspic16[i].type == type)
-      nfr++;
+
+       for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
+               if((reg->type == type) && reg->isFree)nfr++;
+
+       fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
   return nfr;
-#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -988,9 +1250,15 @@ static void writeSetUsedRegs(FILE *of, set *dRegs)
 
 extern void pic16_groupRegistersInSection(set *regset);
 
-extern void pic16_dump_map(void);
-extern void pic16_dump_section(FILE *of, char *sname, set *section, int fix);
+extern void pic16_dump_equates(FILE *of, set *equs);
+extern void pic16_dump_access(FILE *of, set *section);
+//extern void pic16_dump_map(void);
+extern void pic16_dump_usection(FILE *of, set *section, int fix);
+extern void pic16_dump_isection(FILE *of, set *section, int fix);
+extern void pic16_dump_int_registers(FILE *of, set *section);
+extern void pic16_dump_idata(FILE *of, set *idataSymSet);
 
+extern void pic16_dump_gsection(FILE *of, set *sections);
 
 static void packBits(set *bregs)
 {
@@ -1013,7 +1281,7 @@ static void packBits(set *bregs)
     if(breg->isFixed) {
       //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
 
-      bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
+      bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
       breg->rIdx = breg->address & 7;
       breg->address >>= 3;
 
@@ -1046,143 +1314,52 @@ static void packBits(set *bregs)
 
       }
 
-      breg->reg_alias = relocbitfield;
-      breg->address = rDirectIdx;   /* byte_no; */
-      breg->rIdx = bit_no++;
-    }
-  }
-      
-}
-
-
-
-#if 0
-static 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++;
-    }
-  }
-      
-}
-
-static 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) {
-        if (reg->type != REG_SFR) {
-         fprintf (of, "%s\tEQU\t0x%03x\n",
-                  reg->name,
-                  reg->rIdx);
-        }
-      }
-      else
-       fprintf (of, "%s\tEQU\t0x%03x\n",
-                reg->name,
-                reg->address);
-    }
-  }
-      
-}
-#endif
-
-void pic16_writeUsedRegs(FILE *of) 
-{
-       packBits(pic16_dynDirectBitRegs);
-
-       pic16_groupRegistersInSection(pic16_dynAllocRegs);
-       pic16_groupRegistersInSection(pic16_dynInternalRegs);
-       pic16_groupRegistersInSection(pic16_dynStackRegs);
-       pic16_groupRegistersInSection(pic16_dynDirectRegs);
-       pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
-       pic16_groupRegistersInSection(pic16_dynProcessorRegs);
-       
-       
-#if 0
-       pic16_assignFixedRegisters(pic16_dynAllocRegs);
-       pic16_assignFixedRegisters(pic16_dynStackRegs);
-       pic16_assignFixedRegisters(pic16_dynDirectRegs);
-       pic16_assignFixedRegisters(pic16_dynProcessorRegs);
-
-       pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
-       pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
-       pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
-       pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
-       pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
-#endif
-
-//     pic16_dump_map();
-//     pic16_dump_cblock(of);
-
-       pic16_dump_section(of, "ud1", pic16_rel_udata, 0);
-       pic16_dump_section(of, "ud2", pic16_fix_udata, 1);
-
-#if 0
-       bitEQUs(of,pic16_dynDirectBitRegs);
-       aliasEQUs(of,pic16_dynAllocRegs,0);
-       aliasEQUs(of,pic16_dynDirectRegs,0);
-       aliasEQUs(of,pic16_dynStackRegs,0);
-       aliasEQUs(of,pic16_dynProcessorRegs,1);
-#endif
-
+      breg->reg_alias = relocbitfield;
+      breg->address = rDirectIdx;   /* byte_no; */
+      breg->rIdx = bit_no++;
+    }
+  }
+      
 }
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* allDefsOutOfRange - all definitions are out of a range          */
-/*-----------------------------------------------------------------*/
-static bool
-allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
+void pic16_writeUsedRegs(FILE *of) 
 {
-  int i;
-
-  debugLog ("%s\n", __FUNCTION__);
-  if (!defs)
-    return TRUE;
+  packBits(pic16_dynDirectBitRegs);
+
+  pic16_groupRegistersInSection(pic16_dynAllocRegs);
+  pic16_groupRegistersInSection(pic16_dynInternalRegs);
+  pic16_groupRegistersInSection(pic16_dynStackRegs);
+  pic16_groupRegistersInSection(pic16_dynDirectRegs);
+  pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
+  pic16_groupRegistersInSection(pic16_dynProcessorRegs);
+  pic16_groupRegistersInSection(pic16_dynAccessRegs);
+       
+  /* dump equates */
+  pic16_dump_equates(of, pic16_equ_data);
 
-  for (i = 0; i < defs->size; i++)
-    {
-      iCode *ic;
+//     pic16_dump_esection(of, pic16_rel_eedata, 0);
+//     pic16_dump_esection(of, pic16_fix_eedata, 0);
 
-      if (bitVectBitValue (defs, i) &&
-         (ic = hTabItemWithKey (iCodehTab, i)) &&
-         (ic->seq >= fseq && ic->seq <= toseq))
+  /* dump access bank symbols */
+  pic16_dump_access(of, pic16_acs_udata);
 
-       return FALSE;
+  /* dump initialised data */
+  pic16_dump_isection(of, rel_idataSymSet, 0);
+  pic16_dump_isection(of, fix_idataSymSet, 1);
 
-    }
+  if(!xinst) {
+    /* dump internal registers */
+    pic16_dump_int_registers(of, pic16_int_regs);
+  }
+       
+  /* dump generic section variables */
+  pic16_dump_gsection(of, sectNames);
 
-  return TRUE;
+  /* dump other variables */
+  pic16_dump_usection(of, pic16_rel_udata, 0);
+  pic16_dump_usection(of, pic16_fix_udata, 1);
 }
-#endif
+
 
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
@@ -1667,7 +1844,9 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
 
       /* check if there are any live ranges that not
          used in the remainder of the block */
-      if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
+      if (!_G.blockSpil &&
+          !isiCodeInFunctionCall (ic) &&       
+          (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
        {
          sym = leastUsedLR (selectS);
          if (!sym->remat)
@@ -1792,6 +1971,7 @@ static regs *
 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
   debugLog ("%s\n", __FUNCTION__);
 tryAgain:
@@ -1807,6 +1987,11 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+      
   /* this looks like an infinite loop but 
      in really selectSpil will abort  */
   goto tryAgain;
@@ -1819,6 +2004,7 @@ static regs *
 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
   debugLog ("%s\n", __FUNCTION__);
 tryAgain:
@@ -1834,6 +2020,11 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+      
   /* this looks like an infinite loop but 
      in really selectSpil will abort  */
   goto tryAgain;
@@ -1891,6 +2082,13 @@ deassignLRs (iCode * ic, eBBlock * ebp)
       if (!bitVectBitValue (_G.regAssigned, sym->key))
        continue;
 
+      /* special case for shifting: there is a case where shift count
+       * can be allocated in the same register as the result, so do not
+       * free right registers if same as result registers, cause genShiftLeft
+       * will fail -- VR */
+       if(ic->op == LEFT_OP)
+         continue;
+
       /* special case check if this is an IFX &
          the privious one was a pop and the 
          previous one was not spilt then keep track
@@ -1921,6 +2119,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
              (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
              result->liveTo > ic->seq &&       /* and will live beyond this */
              result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
+             result->liveFrom == ic->seq &&    /* does not start before here */
              result->regType == sym->regType &&        /* same register types */
              result->nRegs &&  /* which needs registers */
              !result->isspilt &&       /* and does not already have them */
@@ -1932,15 +2131,20 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                sym->nRegs) >= result->nRegs)
            )
            {
+             
 
-             for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
+//           for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
+              /* the above does not free the unsued registers in sym,
+               * leaving them marked as used, and increasing register usage
+               * until the end of the function - VR 23/11/05 */
+
+             for (i = 0; i < result->nRegs; i++)
                if (i < sym->nRegs)
                  result->regs[i] = sym->regs[i];
                else
                  result->regs[i] = getRegGpr (ic, ebp, result);
 
              _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
-
            }
 
          /* free the remaining */
@@ -2059,6 +2263,31 @@ xchgPositions:
     }
 }
 
+/*------------------------------------------------------------------*/
+/* verifyRegsAssigned - make sure an iTemp is properly initialized; */
+/* it should either have registers or have beed spilled. Otherwise, */
+/* there was an uninitialized variable, so just spill this to get   */
+/* the operand in a valid state.                                    */
+/*------------------------------------------------------------------*/
+static void
+verifyRegsAssigned (operand *op, iCode * ic)
+{
+  symbol * sym;
+  
+  if (!op) return;
+  if (!IS_ITEMP (op)) return;
+  
+  sym = OP_SYMBOL (op);
+  if (sym->isspilt) return;
+  if (!sym->nRegs) return;
+  if (sym->regs[0]) return;
+  
+  werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
+           sym->prereqv ? sym->prereqv->name : sym->name);
+  spillThis (sym);
+}
+
+
 /*-----------------------------------------------------------------*/
 /* serialRegAssign - serially allocate registers to the variables  */
 /*-----------------------------------------------------------------*/
@@ -2066,14 +2295,12 @@ static void
 serialRegAssign (eBBlock ** ebbs, int count)
 {
   int i;
-
+  iCode *ic;
+  
   debugLog ("%s\n", __FUNCTION__);
   /* for all blocks */
   for (i = 0; i < count; i++)
     {
-
-      iCode *ic;
-
       if (ebbs[i]->noPath &&
          (ebbs[i]->entryLabel != entryLabel &&
           ebbs[i]->entryLabel != returnLabel))
@@ -2083,7 +2310,16 @@ serialRegAssign (eBBlock ** ebbs, int count)
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
        {
 
-         debugLog ("  op: %s\n", decodeOp (ic->op));
+         debugLog ("  op: %s\n", pic16_decodeOp (ic->op));
+
+               if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
+                       pic16_allocDirReg(IC_RESULT(ic));
+
+               if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
+                       pic16_allocDirReg(IC_LEFT(ic));
+
+               if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
+                       pic16_allocDirReg(IC_RIGHT(ic));
 
          /* if this is an ipop that means some live
             range will have to be assigned again */
@@ -2118,6 +2354,13 @@ serialRegAssign (eBBlock ** ebbs, int count)
              int j;
              int ptrRegSet = 0;
 
+             /* Make sure any spill location is definately allocated */
+             if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+                 !sym->usl.spillLoc->allocreq)
+               {
+                 sym->usl.spillLoc->allocreq++;
+               }
+
              /* if it does not need or is spilt 
                 or is already assigned to registers
                 or will not live beyond this instructions */
@@ -2140,6 +2383,10 @@ serialRegAssign (eBBlock ** ebbs, int count)
                 or this one is rematerializable then
                 spill this one */
              willCS = willCauseSpill (sym->nRegs, sym->regType);
+
+             /* explicit turn off register spilling */
+             willCS = 0;
+             
              spillable = computeSpillable (ic);
              if (sym->remat ||
                  (willCS && bitVectIsZero (spillable)))
@@ -2150,6 +2397,18 @@ serialRegAssign (eBBlock ** ebbs, int count)
 
                }
 
+             /* If the live range preceeds the point of definition 
+                then ideally we must take into account registers that 
+                have been allocated after sym->liveFrom but freed
+                before ic->seq. This is complicated, so spill this
+                symbol instead and let fillGaps handle the allocation. */
+#if 0
+             if (sym->liveFrom < ic->seq)
+               {
+                   spillThis (sym);
+                   continue;                 
+               }
+#endif
              /* if it has a spillocation & is used less than
                 all other live ranges then spill this */
                if (willCS) {
@@ -2176,9 +2435,22 @@ serialRegAssign (eBBlock ** ebbs, int count)
              if (ic->op == RECEIVE)
                debugLog ("When I get clever, I'll optimize the receive logic\n");
 
+              if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
+                && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
+                && (ic->next->op == IFX)
+                && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
+
+                /* skip register allocation since none will be used */
+                for(j=0;j<sym->nRegs;j++)
+                  sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
+//                OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
+                
+                continue;
+              }
+
              /* if we need ptr regs for the right side
                 then mark it */
-             if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
+             if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
                  <= (unsigned) PTRSIZE)
                {
                  pic16_ptrRegReq++;
@@ -2187,7 +2459,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
              /* else we assign registers to it */
              _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
 
-             debugLog ("  %d - \n", __LINE__);
              if(debugF) 
                bitVectDebugOn(_G.regAssigned, debugF);
 
@@ -2228,6 +2499,40 @@ serialRegAssign (eBBlock ** ebbs, int count)
            }
        }
     }
+
+    /* Check for and fix any problems with uninitialized operands */
+    for (i = 0; i < count; i++)
+      {
+       iCode *ic;
+
+       if (ebbs[i]->noPath &&
+           (ebbs[i]->entryLabel != entryLabel &&
+            ebbs[i]->entryLabel != returnLabel))
+           continue;
+
+       for (ic = ebbs[i]->sch; ic; ic = ic->next)
+         {
+           if (SKIP_IC2 (ic))
+             continue;
+
+           if (ic->op == IFX)
+             {
+               verifyRegsAssigned (IC_COND (ic), ic);
+               continue;
+             }
+
+           if (ic->op == JUMPTABLE)
+             {
+               verifyRegsAssigned (IC_JTCOND (ic), ic);
+               continue;
+             }
+
+           verifyRegsAssigned (IC_RESULT (ic), ic);
+           verifyRegsAssigned (IC_LEFT (ic), ic);
+           verifyRegsAssigned (IC_RIGHT (ic), ic);
+          }
+      }    
+    
 }
 
 /*-----------------------------------------------------------------*/
@@ -2506,7 +2811,6 @@ regTypeNum ()
        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;
       }
 
@@ -2519,21 +2823,22 @@ regTypeNum ()
          (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) {
-
+         !IS_BITVAR (sym->etype) &&
+         (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
+
+//        continue;       /* FIXME -- VR */
+       if (ptrPseudoSymSafe (sym, ic)) {
+          
+         symbol *psym;
+         
+         debugLog ("  %d - \n", __LINE__);
+             
          /* 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 = rematStr (OP_SYMBOL (IC_LEFT (ic)));
          psym->type = sym->type;
          psym->etype = sym->etype;
+         psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
          strcpy (psym->rname, psym->name);
          sym->isspilt = 1;
          sym->usl.spillLoc = psym;
@@ -2556,8 +2861,9 @@ regTypeNum ()
 #else
     if(IS_CODEPTR (sym->type)) {
 #endif
-      debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
-      sym->nRegs = 2;
+      // what IS this ???? (HJD)
+      debugLog ("  %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
+      sym->nRegs = 3; // patch 14
     }
 
       if (sym->nRegs > 4) {
@@ -2583,12 +2889,14 @@ regTypeNum ()
       /* registers for true symbols we will */
       /* see how things go                  */
       sym->nRegs = 0;
+      
   }
 
 }
 static DEFSETFUNC (markRegFree)
 {
   ((regs *)item)->isFree = 1;
+//  ((regs *)item)->wasUsed = 0;
 
   return 0;
 }
@@ -2607,17 +2915,10 @@ DEFSETFUNC (pic16_deallocReg)
 void
 pic16_freeAllRegs ()
 {
-  //  int i;
-
   debugLog ("%s\n", __FUNCTION__);
 
   applyToSet(pic16_dynAllocRegs,markRegFree);
   applyToSet(pic16_dynStackRegs,markRegFree);
-
-/*
-  for (i = 0; i < pic16_nRegs; i++)
-    regspic16[i].isFree = 1;
-*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -2625,20 +2926,9 @@ pic16_freeAllRegs ()
 void
 pic16_deallocateAllRegs ()
 {
-  //  int i;
-
   debugLog ("%s\n", __FUNCTION__);
 
   applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
-
-/*
-  for (i = 0; i < pic16_nRegs; i++) {
-    if(regspic16[i].pc_type == PO_GPR_TEMP) {
-      regspic16[i].isFree = 1;
-      regspic16[i].wasUsed = 0;
-    }
-  }
-*/
 }
 
 
@@ -2723,47 +3013,42 @@ farSpacePackable (iCode * ic)
   return NULL;
 }
 
+#if 0
+static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
+{
+  iCode *dic, *sic;
+
+    debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
+    debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
+    debugAopGet ("  result:", IC_RESULT (ic));
+    debugAopGet ("  left:", IC_LEFT (ic));
+    debugAopGet ("  right:", IC_RIGHT (ic));
+
+    dic = ic->prev;
+    if((dic->op == '=')
+      && (
+}
+#endif
+
+
+void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
+
 /*-----------------------------------------------------------------*/
 /* packRegsForAssign - register reduction for assignment           */
 /*-----------------------------------------------------------------*/
 static int
 packRegsForAssign (iCode * ic, eBBlock * ebp)
 {
-
   iCode *dic, *sic;
 
   debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
-  debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
+  debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
   debugAopGet ("  result:", IC_RESULT (ic));
   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));
-       fprintf(stderr, "  setting config word to %x\n", 
-                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
-       pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
-                               (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
-      }
-
+//     fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
 
-       debugLog(" %d\n", __LINE__);
-
-      /* 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;
-
-    }
-  }
        debugLog(" %d - actuall processing\n", __LINE__ );
 
   if (!IS_ITEMP (IC_RESULT (ic))) {
@@ -2771,16 +3056,11 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
     debugLog ("  %d - result is not temp\n", __LINE__);
   }
 
-#if 0
-  if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
-    debugLog ("  %d - left is not temp, allocating\n", __LINE__);
-    pic16_allocDirReg(IC_LEFT (ic));
-  }
-#endif
+//  if(IS_VALOP(IC_RIGHT(ic)))return 0;
 
 /* See BUGLOG0001 - VR */
 #if 1
-  if (!IS_ITEMP (IC_RIGHT (ic))) {
+  if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
     pic16_allocDirReg(IC_RIGHT (ic));
     return 0;
@@ -2804,6 +3084,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
        return 0;
 
     }
+
   /* find the definition of iTempNN scanning backwards if we find a 
      a use of the true symbol before we find the definition then 
      we cannot pack */
@@ -2821,26 +3102,12 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
          break;
        }
 
+
       if (SKIP_IC2 (dic))
        continue;
 
        debugLog("%d\tSearching for iTempNN\n", __LINE__);
 
-#if 0
-       if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
-               debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
-               debugAopGet(" result is ", IC_RESULT(dic));
-       }
-       if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
-               debugLog("%d - dic left is a SYMOP\n", __LINE__);
-               debugAopGet("   left is ", IC_LEFT(dic));
-       }
-       if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
-               debugLog("%d - dic right is a SYMOP\n", __LINE__);
-               debugAopGet("  right is ", IC_RIGHT(dic));
-       }
-#endif
-
       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
          IS_OP_VOLATILE (IC_RESULT (dic)))
        {
@@ -2849,21 +3116,11 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
          break;
        }
 
-#if 0
-      if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
-               IS_OP_VOLATILE (IC_RIGHT(dic)))
-       {
-         debugLog ("  %d - dic right is VOLATILE\n", __LINE__);
-         dic = NULL;
-         break;
-       }
-#endif
+#if 1
+      if( IS_SYMOP( IC_RESULT(dic)) &&
+       IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
 
-#if 0
-      if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
-               IS_OP_VOLATILE (IC_LEFT(dic)))
-       {
-         debugLog ("  %d - dic left is VOLATILE\n", __LINE__);
+         debugLog (" %d - result is bitfield\n", __LINE__);
          dic = NULL;
          break;
        }
@@ -2912,12 +3169,30 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
   if (!dic)
     return 0;                  /* did not find */
 
+#if 1
+       /* This code is taken from the hc08 port. Do not know
+        * if it fits for pic16, but I leave it here just in case */
+
+       /* if assignment then check that right is not a bit */
+       if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
+         sym_link *etype = operandType (IC_RESULT (dic));
+
+               if (IS_BITFIELD (etype)) {
+                       /* if result is a bit too then it's ok */
+                       etype = operandType (IC_RESULT (ic));
+                       if (!IS_BITFIELD (etype)) {
+                               debugLog(" %d bitfields\n");
+                         return 0;
+                       }
+               }
+       }
+#endif
+
   /* if the result is on stack or iaccess then it must be
      the same atleast one of the operands */
   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
       OP_SYMBOL (IC_RESULT (ic))->iaccess)
     {
-
       /* the operation has only one symbol
          operator then we can pack */
       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
@@ -2936,34 +3211,46 @@ pack:
   /* 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)
-    {
-      OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
-    }
-  /* delete from liverange table also 
-     delete from all the points inbetween and the new
-     one */
-  for (sic = dic; sic != ic; sic = sic->next)
-    {
-      bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
-      if (IS_ITEMP (IC_RESULT (dic)))
-       bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
-    }
 
-  remiCodeFromeBBlock (ebp, ic);
-  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+  
+    bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+    IC_RESULT (dic) = IC_RESULT (ic);
 
-       debugLog("  %d\n", __LINE__ );
-  hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-  OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-  return 1;
+    if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
+      {
+        OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
+      }
+    /* delete from liverange table also 
+       delete from all the points inbetween and the new
+       one */
+    for (sic = dic; sic != ic; sic = sic->next)
+      {
+        bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
+        if (IS_ITEMP (IC_RESULT (dic)))
+          bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
+      }
 
+    remiCodeFromeBBlock (ebp, ic);
+    bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
 
+    debugLog("  %d\n", __LINE__ );
+    hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+    OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+    return 1;
 }
 
+
+#if 1
+
+#define NO_packRegsForAccUse
+#define NO_packRegsForSupport
+#define NO_packRegsForOneuse
+#define NO_cast_peep
+
+#endif
+
+
+#ifndef NO_packRegsForSupport
 /*-----------------------------------------------------------------*/
 /* findAssignToSym : scanning backwards looks for first assig found */
 /*-----------------------------------------------------------------*/
@@ -3003,7 +3290,6 @@ findAssignToSym (operand * op, iCode * ic)
          if ((ic->op == '+' || ic->op == '-') &&
              OP_SYMBOL (IC_RIGHT (dic))->onStack)
            {
-
              if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
                  IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
                  IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
@@ -3041,7 +3327,10 @@ findAssignToSym (operand * op, iCode * ic)
 
 
 }
+#endif
 
+
+#ifndef NO_packRegsForSupport
 /*-----------------------------------------------------------------*/
 /* packRegsForSupport :- reduce some registers for support calls   */
 /*-----------------------------------------------------------------*/
@@ -3119,10 +3408,12 @@ right:
 
   return change;
 }
+#endif
 
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
 
+#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
 
+#ifndef NO_packRegsForOneuse
 /*-----------------------------------------------------------------*/
 /* packRegsForOneuse : - will reduce some registers for single Use */
 /*-----------------------------------------------------------------*/
@@ -3132,16 +3423,24 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   bitVect *uses;
   iCode *dic, *sic;
 
+  return NULL;
+
   debugLog ("%s\n", __FUNCTION__);
   /* if returning a literal then do nothing */
   if (!IS_SYMOP (op))
     return NULL;
 
+  if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
+    return NULL;
+
   /* only upto 2 bytes since we cannot predict
      the usage of b, & acc */
-  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
-      ic->op != RETURN &&
-      ic->op != SEND)
+  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
+      && ic->op != RETURN
+      && ic->op != SEND
+      && !POINTER_SET(ic)
+      && !POINTER_GET(ic)
+      )
     return NULL;
 
   /* this routine will mark the a symbol as used in one 
@@ -3150,10 +3449,18 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
      that definition is either a return value from a 
      function or does not contain any variables in
      far space */
+
+#if 0
   uses = bitVectCopy (OP_USES (op));
   bitVectUnSetBit (uses, ic->key);     /* take away this iCode */
   if (!bitVectIsZero (uses))   /* has other uses */
     return NULL;
+#endif
+
+#if 1
+  if (bitVectnBitsOn (OP_USES (op)) > 1)
+    return NULL;
+#endif
 
   /* if it has only one defintion */
   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
@@ -3182,6 +3489,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
        }
       dic = dic->next;
     }
+  else
+    {
 
 
   /* otherwise check that the definition does
@@ -3203,6 +3512,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   if (POINTER_GET (dic) &&
       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
     return NULL;
+    }
 
   sic = dic;
 
@@ -3233,7 +3543,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
          operation is a '*','/' or '%' then 'b' may
          cause a problem */
       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
-         getSize (operandType (op)) >= 3)
+         getSize (operandType (op)) >= 2)
        return NULL;
 
       /* if left or right or result is in far space */
@@ -3252,6 +3562,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   return sic;
 
 }
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
@@ -3283,6 +3595,9 @@ isBitwiseOptimizable (iCode * ic)
     return FALSE;
 }
 
+
+#ifndef NO_packRegsForAccUse
+
 /*-----------------------------------------------------------------*/
 /* packRegsForAccUse - pack registers for acc use                  */
 /*-----------------------------------------------------------------*/
@@ -3405,6 +3720,7 @@ packRegsForAccUse (iCode * ic)
       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
     return;
 
+#if 1
   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))) ||
@@ -3414,6 +3730,7 @@ packRegsForAccUse (iCode * ic)
       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
       return;
     }
+#endif
 
   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* if the other one is not on stack then we can */
@@ -3437,6 +3754,8 @@ accuse:
 
 
 }
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* packForPush - hueristics to reduce iCode for pushing            */
@@ -3456,20 +3775,16 @@ packForReceive (iCode * ic, eBBlock * ebp)
 
   for (dic = ic->next; dic; dic = dic->next)
     {
-
-
-
       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
-       debugLog ("    used on left\n");
+        debugLog ("    used on left\n");
       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
-       debugLog ("    used on right\n");
+        debugLog ("    used on right\n");
       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
-       debugLog ("    used on result\n");
+        debugLog ("    used on result\n");
 
       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
-         (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
+        (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
        return;
-
     }
 
   debugLog ("  hey we can remove this unnecessary assign\n");
@@ -3481,11 +3796,26 @@ static void
 packForPush (iCode * ic, eBBlock * ebp)
 {
   iCode *dic;
-
+  char *iLine;
+  
   debugLog ("%s\n", __FUNCTION__);
   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
     return;
 
+#if 0
+  {
+    int n1, n2;
+    char *iLine;
+
+      n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
+      n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
+      iLine = printILine(ic);
+      debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
+      dbuf_free(iLine);
+      debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
+  }
+#endif
+
   /* must have only definition & one usage */
   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
@@ -3496,12 +3826,28 @@ packForPush (iCode * ic, eBBlock * ebp)
                               bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
     return;
 
+  /* if definition is not assignment,
+   * or is not pointer (because pointer might have changed) */
   if (dic->op != '=' || POINTER_SET (dic))
     return;
 
+  /* we must ensure that we can use the delete the assignment,
+   * because the source might have been modified in between.
+   * Until I know how to fix this, I'll use the adhoc fix
+   * to check the liveranges */
+  if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
+    return;
+//  debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
+  
+
+
   /* we now we know that it has one & only one def & use
      and the that the definition is an assignment */
   IC_LEFT (ic) = IC_RIGHT (dic);
+  
+  iLine = printILine(dic);
+  debugf("remiCodeFromeBBlock: %s\n", iLine);
+  dbuf_free(iLine);
 
   remiCodeFromeBBlock (ebp, dic);
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
@@ -3510,10 +3856,11 @@ packForPush (iCode * ic, eBBlock * ebp)
 
 static void printSymType(char * str, sym_link *sl)
 {
-  debugLog ("    %s Symbol type: ",str);
-  printTypeChain( sl, debugF);
-  debugLog ("\n");
-
+       if(!pic16_ralloc_debug)return;
+       
+       debugLog ("    %s Symbol type: ",str);
+       printTypeChain (sl, debugF);
+       debugLog ("\n");
 }
 
 /*-----------------------------------------------------------------*/
@@ -3525,37 +3872,35 @@ static 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;
+    if(!pic16_ralloc_debug)return;
+    
+    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;
+        }
       }
-
     }
-
-  }
-    
 }
 
+
 /*--------------------------------------------------------------------*/
 /* pic16_packRegisters - does some transformations to reduce          */
 /*                   register pressure                                */
@@ -3581,8 +3926,7 @@ pic16_packRegisters (eBBlock * ebp)
       {
 //             debugLog("%d\n", __LINE__);
        /* find assignment of the form TrueSym := iTempNN:1 */
-       /* see BUGLOG0001 for workaround with the CAST - VR */
-       if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
+       if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
          change += packRegsForAssign (ic, ebp);
        /* debug stuff */
        if (ic->op == '=')
@@ -3606,7 +3950,7 @@ pic16_packRegisters (eBBlock * ebp)
       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
 
       debugAopGet ("x  left:", IC_LEFT (ic));
-#if 1
+#if 0
       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
 #else
       if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
@@ -3639,10 +3983,59 @@ pic16_packRegisters (eBBlock * ebp)
       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
     }
 
-    if (POINTER_SET (ic))
-       debugLog ("  %d - Pointer set\n", __LINE__);
+    if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
+      debugAopGet ("  right:", IC_RIGHT (ic));
+      printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
+//      pic16_allocDirReg(IC_RIGHT(ic));
+    }
+
+    if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
+      debugAopGet ("  result:", IC_RESULT (ic));
+      printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
+//      pic16_allocDirReg(IC_RESULT(ic));
+    }
 
 
+    if (POINTER_SET (ic))
+      debugLog ("  %d - Pointer set\n", __LINE__);
+      
+      /* Look for two subsequent iCodes with */
+      /*   iTemp := _c;         */
+      /*   _c = iTemp & op;     */
+      /* and replace them by    */
+      /*   iTemp := _c;         */
+      /*   _c = _c & op;        */
+      if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
+        && ic->prev
+        && ic->prev->op == '='
+        && IS_ITEMP (IC_LEFT (ic))
+        && IC_LEFT (ic) == IC_RESULT (ic->prev)
+        && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
+        {
+          iCode* ic_prev = ic->prev;
+          symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
+                       
+          ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
+          if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
+            bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
+            if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
+              prev_result_sym->liveTo == ic->seq)
+            {
+              prev_result_sym->liveTo = ic_prev->seq;
+            }
+          }
+          bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+          
+          bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
+
+          if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
+            bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
+            bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
+            remiCodeFromeBBlock (ebp, ic_prev);
+            hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
+          }
+        }
+               
     /* if this is an itemp & result of a address of a true sym 
        then mark this as rematerialisable   */
     if (ic->op == ADDRESS_OF &&
@@ -3693,18 +4086,64 @@ pic16_packRegisters (eBBlock * ebp)
        OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
       }
 
+
+#if 0
+    /* try to optimize FSR0 usage when reading data memory pointers */
+     
+    if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
+         static int fsr0usage=0;
+         static iCode *usic;
+
+               if(POINTER_GET(ic)                              /* this is a memory read */
+                       && ic->loop                                     /* this is in a loop */
+               ) {
+                       fprintf(stderr, "might optimize FSR0 usage\n");
+               }
+    }
+#endif
+          
     /* 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));
+        if(IS_SYMOP(IC_LEFT(ic))) {
+          OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+          debugLog ("  marking as a pointer (get) =>");
+          debugAopGet ("  left:", IC_LEFT (ic));
+        }
+        
+        if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
+          if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
+            iCode *dic = ic->prev;
+
+            fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
+          
+            if(dic && dic->op == '='
+              && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
+              
+                fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
+
+
+                /* replace prev->left with ic->left */
+                IC_LEFT(ic) = IC_RIGHT(dic);
+                IC_RIGHT(ic->prev) = NULL;
+                
+                /* remove ic->prev iCode (assignment) */
+                remiCodeFromeBBlock (ebp, dic);
+                bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
+
+
+                hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+            }
+          }
+        }
       }
 
        //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);
@@ -3759,22 +4198,27 @@ pic16_packRegisters (eBBlock * ebp)
 
        debugLog(" %d\n", __LINE__);
 
+#ifndef NO_packRegsForSupport
     /* reduce for support function calls */
     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
       packRegsForSupport (ic, ebp);
+#endif
 
     /* 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);
 
+#ifndef NO_packRegsForOneuse
     /* 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);
+#endif
 
+#ifndef NO_packRegsForOneuse
     /* if pointer set & left has a size more than
        one and right is not in far space */
     if (POINTER_SET (ic) &&
@@ -3784,7 +4228,9 @@ pic16_packRegisters (eBBlock * ebp)
        getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
 
       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+#endif
 
+#ifndef NO_packRegsForOneuse
     /* if pointer get */
     if (POINTER_GET (ic) &&
        !isOperandInFarSpace (IC_RESULT (ic)) &&
@@ -3794,7 +4240,9 @@ pic16_packRegisters (eBBlock * ebp)
 
       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
       debugLog("%d - return from packRegsForOneuse\n", __LINE__);
+#endif
 
+#ifndef NO_cast_peep
     /* if this is cast for intergral promotion then
        check if only use of  the definition of the 
        operand being casted/ if yes then replace
@@ -3851,7 +4299,13 @@ pic16_packRegisters (eBBlock * ebp)
        }
       }
     }
+#endif
 
+#if 1
+    /* there are some problems with packing variables
+     * it seems that the live range estimator doesn't
+     * estimate correctly the liveranges of some symbols */
+     
     /* pack for PUSH 
        iTempNN := (some variable in farspace) V1
        push iTempNN ;
@@ -3862,8 +4316,9 @@ pic16_packRegisters (eBBlock * ebp)
       {
        packForPush (ic, ebp);
       }
+#endif
 
-
+#ifndef NO_packRegsForAccUse
     /* pack registers for accumulator use, when the
        result of an arithmetic or bit wise operation
        has only one use, that use is immediately following
@@ -3880,9 +4335,10 @@ pic16_packRegisters (eBBlock * ebp)
 
         ) &&
        IS_ITEMP (IC_RESULT (ic)) &&
-       getSize (operandType (IC_RESULT (ic))) <= 2)
+       getSize (operandType (IC_RESULT (ic))) <= 1)
 
       packRegsForAccUse (ic);
+#endif
 
   }
 }
@@ -3892,7 +4348,7 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count)
 {
   int i;
 
-  if (!debug || !debugF)
+  if (!pic16_ralloc_debug || !debugF)
     return;
 
   for (i = 0; i < count; i++)
@@ -3930,12 +4386,17 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count)
       printiCChain (ebbs[i]->sch, debugF);
     }
 }
+
+void dbg_dumpregusage(void);
+
 /*-----------------------------------------------------------------*/
 /* pic16_assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
 void
-pic16_assignRegisters (eBBlock ** ebbs, int count)
+pic16_assignRegisters (ebbIndex * ebbi)
 {
+  eBBlock ** ebbs = ebbi->bbOrder;
+  int count = ebbi->count;
   iCode *ic;
   int i;
 
@@ -3943,6 +4404,26 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   debugLog ("\nebbs before optimizing:\n");
   dumpEbbsToDebug (ebbs, count);
 
+  _inRegAllocator = 1;
+
+  pic16_freeAllRegs();
+#if 0
+       dbg_dumpregusage();
+       /* clear whats left over from peephole parser */
+       pic16_dynAllocRegs= newSet();   //NULL;
+//     pic16_dynStackRegs= newSet();   //NULL;
+//     pic16_dynProcessorRegs=newSet();        //NULL;
+//     pic16_dynDirectRegs=newSet();           //NULL;
+//     pic16_dynDirectBitRegs=newSet();        //NULL;
+//     pic16_dynInternalRegs=newSet();         //NULL;
+//     pic16_dynAccessRegs=newSet();           //NULL;
+
+//     dynDirectRegNames=NULL;
+       dynAllocRegNames=NULL;
+//     dynProcRegNames=NULL;
+//     dynAccessRegNames=NULL;
+#endif
+
   setToNull ((void *) &_G.funcrUsed);
   pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
 
@@ -3952,19 +4433,21 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   for (i = 0; i < count; i++)
     pic16_packRegisters (ebbs[i]);
 
+
   {
     regs *reg;
     int hkey;
-    int i=0;
 
     debugLog("dir registers allocated so far:\n");
     reg = hTabFirstItem(dynDirectRegNames, &hkey);
 
+#if 0
     while(reg) {
       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
 //      fprintf(stderr, "  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
       reg = hTabNextItem(dynDirectRegNames, &hkey);
     }
+#endif
 
   }
 
@@ -3973,15 +4456,27 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   recomputeLiveRanges (ebbs, count);
 
   if (options.dump_pack)
-    dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+    dumpEbbsToFileExt (DUMP_PACK, ebbi);
 
   /* first determine for each live range the number of 
      registers & the type of registers required for each */
   regTypeNum ();
 
+  /* start counting function temporary registers from zero */
+  /* XXX: Resetting dynrIdx breaks register allocation,
+   *      see #1489055, #1483693 (?), and #1445850! */
+  //dynrIdx = 0;
+
   /* and serially allocate registers */
   serialRegAssign (ebbs, count);
 
+#if 0
+  debugLog ("ebbs after serialRegAssign:\n");
+  dumpEbbsToDebug (ebbs, count);
+#endif
+
+  //pic16_freeAllRegs();
+
   /* if stack was extended then tell the user */
   if (_G.stackExtend)
     {
@@ -4005,7 +4500,9 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   redoStackOffsets ();
 
   if (options.dump_rassgn)
-    dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+    dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
+
+//  dumpLR(ebbs, count);
 
   /* now get back the chain */
   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
@@ -4014,6 +4511,8 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   dumpEbbsToDebug (ebbs, count);
 
 
+  _inRegAllocator = 0;
+
   genpic16Code (ic);
 
   /* free up any _G.stackSpil locations allocated */
@@ -4022,7 +4521,8 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   setToNull ((void *) &_G.stackSpil);
   setToNull ((void *) &_G.spiltSet);
   /* mark all registers as free */
-  //pic16_freeAllRegs ();
+  pic16_freeAllRegs ();
+
 
   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
   debugLogClose ();