* src/pic16/glue.c,
[fw/sdcc] / src / pic16 / ralloc.c
index 03849b7d83365b9bed22f66eb237ae2f5fbf2cba..52932b0ce7887d263c12b9b1e41af1d29c0f2263 100644 (file)
@@ -29,6 +29,7 @@
 #include "ralloc.h"
 #include "pcode.h"
 #include "gen.h"
+#include "device.h"
 
 #if defined(__BORLANDC__) || defined(_MSC_VER)
 #define STRCASECMP stricmp
@@ -45,7 +46,7 @@
 /* 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);
 
@@ -77,7 +78,14 @@ set *pic16_dynInternalRegs=NULL;
 static hTab  *dynDirectRegNames= NULL;
 //static hTab  *regHash = NULL;    /* a hash table containing ALL registers */
 
-static int dynrIdx=0x20;
+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_builtin_functions=NULL;
+
+static int dynrIdx=0x10;               //0x20;         // starting temporary register rIdx
 static int rDirectIdx=0;
 
 int pic16_nRegs = 128;   // = sizeof (regspic16) / sizeof (regs);
@@ -89,7 +97,7 @@ int pic16_Gstack_base_addr=0; /* The starting address of registers that
 
 
 static void spillThis (symbol *);
-static int debug = 1;
+int pic16_ralloc_debug = 0;
 static FILE *debugF = NULL;
 /*-----------------------------------------------------------------*/
 /* debugLog - open a file for debugging information                */
@@ -104,7 +112,7 @@ debugLog (char *fmt,...)
   //char *bufferP=buffer;
   va_list ap;
 
-  if (!debug || !dstFileName)
+  if (!pic16_ralloc_debug || !dstFileName)
     return;
 
 
@@ -145,8 +153,10 @@ debugLog (char *fmt,...)
 static void
 debugNewLine (void)
 {
-  if (debugF)
-    fputc ('\n', debugF);
+       if(!pic16_ralloc_debug)return;
+       
+       if (debugF)
+               fputc ('\n', debugF);
 }
 /*-----------------------------------------------------------------*/
 /* debugLogClose - closes the debug log file (if opened)           */
@@ -154,244 +164,142 @@ 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)
 {
+       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 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);
 
-  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;
 }
 /*-----------------------------------------------------------------*/
@@ -399,18 +307,14 @@ decodeOp (unsigned int op)
 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;
 }
 
@@ -436,41 +340,50 @@ 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)
+regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
 {
 
   regs *dReg;
 
-  dReg = Safe_calloc(1,sizeof(regs));
-  dReg->type = type;
-  dReg->pc_type = pc_type;
-  dReg->rIdx = rIdx;
-  if(name) 
-    dReg->name = Safe_strdup(name);
-  else {
-    sprintf(buffer,"r0x%02X", dReg->rIdx);
-    if(type == REG_STK)
-      *buffer = 's';
-    dReg->name = Safe_strdup(buffer);
-  }
-  //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
-  dReg->isFree = 0;
-  dReg->wasUsed = 1;
-  if(type == REG_SFR)
-    dReg->isFixed = 1;
-  else
-    dReg->isFixed = 0;
+       dReg = Safe_calloc(1,sizeof(regs));
+       dReg->type = type;
+       dReg->pc_type = pc_type;
+       dReg->rIdx = rIdx;
+       if(name) 
+               dReg->name = Safe_strdup(name);
+       else {
+               sprintf(buffer,"r0x%02X", dReg->rIdx);
+               if(type == REG_STK)
+                       *buffer = 's';
+                       dReg->name = Safe_strdup(buffer);
+       }
+
 
-  dReg->isMapped = 0;
-  dReg->isEmitted = 0;
-  dReg->address = 0;
-  dReg->size = size;
-  dReg->alias = alias;
-  dReg->reg_alias = NULL;
-  dReg->reglives.usedpFlows = newSet();
-  dReg->reglives.assignedpFlows = newSet();
+       dReg->isFree = 0;
+       dReg->wasUsed = 1;
+       dReg->isEmitted = 0;
 
-  hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+       if(type == REG_SFR) {
+               dReg->isFixed = 1;
+               dReg->address = rIdx;
+               dReg->accessBank = 1;
+       } else {
+               dReg->isFixed = 0;
+               dReg->address = 0;
+               dReg->accessBank = 0;
+       }
+
+//     fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
+       
+       dReg->size = size;
+       dReg->alias = alias;
+       dReg->reg_alias = NULL;
+       dReg->reglives.usedpFlows = newSet();
+       dReg->reglives.assignedpFlows = newSet();
+       dReg->regop = refop;
+  
+       if(!(type == REG_SFR && alias == 0x80))
+               hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
 
   return dReg;
 }
@@ -505,8 +418,12 @@ 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) {
       return dReg;
+    }
   }
 
   return NULL;
@@ -523,7 +440,7 @@ void pic16_initStack(int base_address, int size)
   //fprintf(stderr,"initStack");
 
   for(i = 0; i<size; i++)
-    addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
+    addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
 }
 
 /*-----------------------------------------------------------------*
@@ -531,9 +448,14 @@ void pic16_initStack(int base_address, int size)
 regs *
 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
 {
+  regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
+
+//     fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
 
-  //fprintf(stderr,"pic16_allocProcessorRegister %s addr =0x%x\n",name,rIdx);
-  return addSet(&pic16_dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
+       reg->wasUsed = 0;               // we do not know if they are going to be used at all
+       reg->accessBank = 1;            // implicit add access Bank
+
+  return addSet(&pic16_dynProcessorRegs, reg);
 }
 
 /*-----------------------------------------------------------------*
@@ -542,13 +464,14 @@ pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
 regs *
 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 {
-  regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
+  regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
 
-  //fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
-  if(reg) {
-    reg->wasUsed = 0;
-    return addSet(&pic16_dynInternalRegs,reg);
-  }
+//  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);
+    }
 
   return NULL;
 }
@@ -558,12 +481,45 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 static regs *
 allocReg (short type)
 {
+  regs * reg=NULL;
+  
+#if 0
+  if(dynrIdx > pic16_nRegs)
+       return NULL;
+#endif
+
+       /* try to reuse some unused registers */
+       reg = regFindFree( pic16_dynAllocRegs );
+
+       if(reg) {
+//             fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
+       }
+
+       if(!reg) {
+               reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
+//             addSet(&pic16_dynAllocRegs, reg);
+       }
+
+       addSet(&pic16_dynAllocRegs, reg);
 
-  debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
-  //fprintf(stderr,"allocReg\n");
+       reg->isFree=0;
 
+//     debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
 
-  return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,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);
+
+       if(reg) {
+               reg->accessBank = 1;    /* this is a temporary register alloc in accessBank */
+               reg->isLocal = 1;       /* this is a local frame register */
+       }
+       
+       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);
 
 }
 
@@ -601,7 +557,7 @@ pic16_dirregWithName (char *name)
   return NULL; // name wasn't found in the hash table
 }
 
-static int IS_CONFIG_ADDRESS(int address)
+int PIC16_IS_CONFIG_ADDRESS(int address)
 {
 
   return address >= 0x300000 && address <= 0x300000d;
@@ -613,108 +569,165 @@ static int IS_CONFIG_ADDRESS(int address)
 regs *
 pic16_allocDirReg (operand *op )
 {
-
   regs *reg;
   char *name;
 
-  if(!IS_SYMOP(op)) {
-    debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
-    return NULL;
-  }
+       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;
+       name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
 
-  /* If the symbol is at a fixed address, then remove the leading underscore
-   * from the name. This is hack to allow the .asm include file named registers
-   * to match the .c declared register names */
+       if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {                                                                     // patch 13
+               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);                                                             //
+               }                                                                                               //
+               return NULL;                                                                                    //
+       }                                                                                                       // patch 13
 
-  //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
-  //name++;
+       debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
+//     fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
 
-  debugLog ("%s symbol name %s\n", __FUNCTION__,name);
-  {
-    if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
-      debugLog(" %d  const char\n",__LINE__);
-      debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
-    }
-
-    debugLog("  %d  storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
-    if (IS_CODE ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  code space\n",__LINE__);
-
-    if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  integral\n",__LINE__);
-    if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  literal\n",__LINE__);
-    if (IS_SPEC ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  specifier\n",__LINE__);
-    debugAopGet(NULL, op);
-  }
+       {
+               if(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)));
+               }
 
-  if (IS_CODE ( OP_SYM_ETYPE(op)) )
-    return NULL;
+       
+               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__);
 
-  /* 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);
+               if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  integral\n",__LINE__);
 
-#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)));
-#endif
-  } else {
-//     fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
-    
-    reg = pic16_dirregWithName(name);
-  }
+               if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  literal\n",__LINE__);
 
-  if(!reg) {
-    int address = 0;
+               if (IS_SPEC ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  specifier\n",__LINE__);
 
-    /* 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);
-    }
+               debugAopGet(NULL, op);
+       }
 
-    /* Register wasn't found in hash, so let's create
-     * a new one and put it in the hash table AND in the 
-     * dynDirectRegNames set */
-    if(!IS_CONFIG_ADDRESS(address)) {
-      //fprintf(stderr,"allocating new reg %s\n",name);
+       if (IS_CODE ( OP_SYM_ETYPE(op)) )
+               return NULL;
 
-      reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
-      debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
+       /* 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=NULL;
+//             reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
 
-      //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+#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)));
+#endif
+       } else {
+//             fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
+    
+               reg = pic16_dirregWithName(name);
+       }
 
-      if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+       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);
+               }
 
-       //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
-       reg->type = REG_SFR;
-      }
+               /* 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(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+                       if(pic16_debug_verbose)
+                               fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
+                                       OP_SYMBOL(op)->name);
+                       debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
+                 return NULL;
+               }
 
-      if (IS_BITVAR (OP_SYM_ETYPE(op))) {
-       addSet(&pic16_dynDirectBitRegs, reg);
-       reg->isBitField = 1;
-      } else
-       addSet(&pic16_dynDirectRegs, reg);
+               if(!PIC16_IS_CONFIG_ADDRESS(address)) {
+//                     fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
 
-    } else {
-      debugLog ("  -- %s is declared at address 0x30000x\n",name);
+                       /* this is an error, why added? -- VR */
+//                     if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
 
-    }
-  }
+                       if(OP_SYMBOL(op)->onStack) {
+//                             fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
+                               OP_SYMBOL(op)->onStack = 0;
+                               SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
+                               regtype = REG_GPR;
+                       }
 
-  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);
-  }
+                       if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {                                               // patch 13
+                               if(pic16_debug_verbose)                                                                 //
+                               {                                                                                       //
+                                       fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%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)));
+
+                                       fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,        //
+                                               OP_SYMBOL(op)->name);                                                   //
+                               }                                                                                       //
+//                             return NULL;                                                                            //
+                       }                                                                                               // patch 13
+
+                       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);
+
+//                     hTabAddItem(&dynDirectRegNames, regname2key(name), reg);        /* commented out */
+
+//                     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);
+                               checkAddReg(&pic16_dynDirectRegs, reg);
+                       }
+       
+               } else {
+                       debugLog ("  -- %s is declared at address 0x30000x\n",name);
+//                     fprintf(stderr, "  -- %s is declared at address 0x30000x\n",name);
+       
+                 return NULL;
+               }
+       }
+
+       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 < 0x80)
+                       || (reg->address >= 0xf80 && reg->address <= 0xfff))
+                       reg->accessBank = 1;
+               
+               debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
+       }
 
   return reg;
 }
@@ -742,11 +755,12 @@ pic16_allocRegByName (char *name, int size)
      * 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 );
+    reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
 
-    debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
+    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);
 
-    //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+    //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
     addSet(&pic16_dynDirectRegs, reg);
   }
 
@@ -756,13 +770,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\n", __FUNCTION__, idx);
 
   switch (type) {
 
@@ -808,13 +822,13 @@ 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( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
     return dReg;
 
   return NULL;
@@ -830,6 +844,7 @@ pic16_allocWithIdx (int idx)
   regs *dReg;
 
   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) {
 
@@ -838,6 +853,7 @@ pic16_allocWithIdx (int idx)
     debugLog ("Found a Stack Register!\n");
   } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != 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 ) {
     debugLog ("Found an Internal Register!\n");
   } else {
@@ -869,7 +885,7 @@ 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));
+    return allocReg( REG_GPR );                //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
 
   case REG_STK:
 
@@ -891,8 +907,9 @@ pic16_findFreeReg(short type)
 static void
 freeReg (regs * reg)
 {
-  debugLog ("%s\n", __FUNCTION__);
-  reg->isFree = 1;
+       debugLog ("%s\n", __FUNCTION__);
+//     fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
+       reg->isFree = 1;
 }
 
 
@@ -902,20 +919,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
 }
 
 /*-----------------------------------------------------------------*/
@@ -950,11 +974,13 @@ static void writeSetUsedRegs(FILE *of, set *dRegs)
 }
 #endif
 
-extern void pic16_assignFixedRegisters(set *regset);
-extern void pic16_assignRelocatableRegisters(set *regset,int used);
-extern void pic16_dump_map(void);
-extern void pic16_dump_cblock(FILE *of);
+extern void pic16_groupRegistersInSection(set *regset);
 
+extern void pic16_dump_equates(FILE *of, set *equs);
+//extern void pic16_dump_map(void);
+extern void pic16_dump_section(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);
 
 static void packBits(set *bregs)
 {
@@ -977,14 +1003,14 @@ 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;
 
       if(!bitfield) {
        sprintf (buffer, "fbitfield%02x", breg->address);
        //fprintf(stderr,"new bit field\n");
-       bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
+       bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
        bitfield->isBitField = 1;
        bitfield->isFixed = 1;
        bitfield->address = breg->address;
@@ -1003,7 +1029,7 @@ static void packBits(set *bregs)
        bit_no=0;
        sprintf (buffer, "bitfield%d", byte_no);
        //fprintf(stderr,"new relocatable bit field\n");
-       relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
+       relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
        relocbitfield->isBitField = 1;
        addSet(&pic16_dynDirectRegs,relocbitfield);
        //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
@@ -1080,30 +1106,45 @@ static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
 
 void pic16_writeUsedRegs(FILE *of) 
 {
-  packBits(pic16_dynDirectBitRegs);
-
-
-  pic16_assignFixedRegisters(pic16_dynAllocRegs);
-  pic16_assignFixedRegisters(pic16_dynStackRegs);
-  pic16_assignFixedRegisters(pic16_dynDirectRegs);
-
-  pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
-  pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
-  pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
-  pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
+       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_map();
+//     pic16_dump_cblock(of);
 
-  pic16_dump_cblock(of);
+       /* dump equates */
+       pic16_dump_equates(of, pic16_equ_data);
 
-#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
+       /* dump initialised data */
+       pic16_dump_idata(of, idataSymSet);
 
+       /* dump internal registers */
+       pic16_dump_int_registers(of, pic16_int_regs);
+       
+       /* dump other variables */
+       pic16_dump_section(of, pic16_rel_udata, 0);
+       pic16_dump_section(of, pic16_fix_udata, 1);
+       
 }
 
 #if 0
@@ -1304,7 +1345,7 @@ leastUsedLR (set * sset)
 
     }
 
-  setToNull ((void **) &sset);
+  setToNull ((void *) &sset);
   sym->blockSpil = 0;
   return sym;
 }
@@ -1743,6 +1784,7 @@ static regs *
 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
   debugLog ("%s\n", __FUNCTION__);
 tryAgain:
@@ -1758,6 +1800,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;
@@ -1770,6 +1817,7 @@ static regs *
 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
   debugLog ("%s\n", __FUNCTION__);
 tryAgain:
@@ -1785,6 +1833,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;
@@ -2010,6 +2063,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  */
 /*-----------------------------------------------------------------*/
@@ -2179,6 +2257,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);
+          }
+      }    
+    
 }
 
 /*-----------------------------------------------------------------*/
@@ -2435,6 +2547,7 @@ regTypeNum ()
        sym = hTabNextItem (liveRanges, &k)) {
 
     debugLog ("  %d - %s\n", __LINE__, sym->rname);
+    //fprintf(stderr,"  %d - %s\n", __LINE__, sym->rname);
 
     /* if used zero times then no registers needed */
     if ((sym->liveTo - sym->liveFrom) == 0)
@@ -2469,21 +2582,21 @@ 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)) {
 
+       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;
@@ -2501,9 +2614,14 @@ regTypeNum ()
                    getSize (sym->type));
 
 
+#if 0
     if(IS_PTR_CONST (sym->type)) {
-      debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
-      sym->nRegs = 2;
+#else
+    if(IS_CODEPTR (sym->type)) {
+#endif
+      // 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) {
@@ -2553,17 +2671,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;
-*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -2571,20 +2682,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;
-    }
-  }
-*/
 }
 
 
@@ -2678,23 +2778,30 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
 
   iCode *dic, *sic;
 
-  debugLog ("%s\n", __FUNCTION__);
-
+  debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
+  debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
   debugAopGet ("  result:", IC_RESULT (ic));
   debugAopGet ("  left:", IC_LEFT (ic));
   debugAopGet ("  right:", IC_RIGHT (ic));
 
+//     fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
+
   /* 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))))) {
+    if(PIC16_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));
       }
 
+
+       debugLog(" %d\n", __LINE__);
+
       /* remove the assignment from the iCode chain. */
 
       remiCodeFromeBBlock (ebp, ic);
@@ -2705,23 +2812,28 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
 
     }
   }
+       debugLog(" %d - actuall processing\n", __LINE__ );
 
   if (!IS_ITEMP (IC_RESULT (ic))) {
     pic16_allocDirReg(IC_RESULT (ic));
     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
 
+/* See BUGLOG0001 - VR */
+#if 1
   if (!IS_ITEMP (IC_RIGHT (ic))) {
     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
     pic16_allocDirReg(IC_RIGHT (ic));
     return 0;
   }
+#endif
 
   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
@@ -2740,6 +2852,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 */
@@ -2757,9 +2870,27 @@ 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)))
        {
@@ -2768,6 +2899,37 @@ 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 0
+      if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
+               IS_OP_VOLATILE (IC_LEFT(dic)))
+       {
+         debugLog ("  %d - dic left is VOLATILE\n", __LINE__);
+         dic = NULL;
+         break;
+       }
+#endif
+
+
+#if 1
+      if( IS_SYMOP( IC_RESULT(dic)) &&
+       IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
+
+         debugLog (" %d - result is bitfield\n", __LINE__);
+         dic = NULL;
+         break;
+       }
+#endif
+
       if (IS_SYMOP (IC_RESULT (dic)) &&
          IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
        {
@@ -2811,12 +2973,38 @@ 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 (dic) && !POINTER_SET (dic)) {
+         sym_link *etype = operandType (IC_RIGHT (dic));
+
+               if (IS_BITFIELD (etype)) {
+                       /* if result is a bit too then it's ok */
+                       etype = operandType (IC_RESULT (dic));
+                       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)
     {
 
+#if 0
+       /* clear the onStack flag, the port doesn't support it yet! FIXME */
+       if(OP_SYMBOL(IC_RESULT(ic))->onStack)
+               OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
+#endif
+       
+
       /* the operation has only one symbol
          operator then we can pack */
       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
@@ -2854,6 +3042,8 @@ pack:
 
   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;
@@ -2861,6 +3051,17 @@ pack:
 
 }
 
+#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 */
 /*-----------------------------------------------------------------*/
@@ -2901,6 +3102,11 @@ findAssignToSym (operand * op, iCode * ic)
              OP_SYMBOL (IC_RIGHT (dic))->onStack)
            {
 
+#if 0
+               if(OP_SYMBOL(IC_RESULT(ic))->onStack)
+                       OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
+#endif
+
              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)
@@ -2938,7 +3144,10 @@ findAssignToSym (operand * op, iCode * ic)
 
 
 }
+#endif
+
 
+#ifndef NO_packRegsForSupport
 /*-----------------------------------------------------------------*/
 /* packRegsForSupport :- reduce some registers for support calls   */
 /*-----------------------------------------------------------------*/
@@ -3016,10 +3225,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 */
 /*-----------------------------------------------------------------*/
@@ -3036,7 +3247,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 
   /* only upto 2 bytes since we cannot predict
      the usage of b, & acc */
-  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
+  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) &&       /* was 2, changed to 3 -- VR */
       ic->op != RETURN &&
       ic->op != SEND)
     return NULL;
@@ -3149,6 +3360,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   return sic;
 
 }
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
@@ -3180,6 +3393,9 @@ isBitwiseOptimizable (iCode * ic)
     return FALSE;
 }
 
+
+#ifndef NO_packRegsForAccUse
+
 /*-----------------------------------------------------------------*/
 /* packRegsForAccUse - pack registers for acc use                  */
 /*-----------------------------------------------------------------*/
@@ -3208,24 +3424,29 @@ packRegsForAccUse (iCode * ic)
        getSize (operandType (IC_RESULT (ic))) > 1))
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   if (ic->op == LEFT_OP &&
       (isOperandLiteral (IC_RIGHT (ic)) ||
        getSize (operandType (IC_RESULT (ic))) > 1))
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   if (IS_BITWISE_OP (ic) &&
       getSize (operandType (IC_RESULT (ic))) > 1)
     return;
 
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* has only one use */
   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* and the usage immediately follows this iCode */
   if (!(uic = hTabItemWithKey (iCodehTab,
                               bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
@@ -3297,6 +3518,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))) ||
@@ -3306,6 +3528,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 */
@@ -3329,6 +3552,8 @@ accuse:
 
 
 }
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* packForPush - hueristics to reduce iCode for pushing            */
@@ -3402,10 +3627,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");
 }
 
 /*-----------------------------------------------------------------*/
@@ -3417,42 +3643,43 @@ 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)) {
+       if(!pic16_ralloc_debug)return;
        
-      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(!sl)return;
+
+       if(debugF)
+               of = debugF;
+
+       for ( ; sl; sl=sl->next) {
+               if(!IS_DECL(sl) ) {
+                       switch (SPEC_SCLS(sl)) {
+                               case S_DATA: fprintf (of, "data "); break;
+                               case S_XDATA: fprintf (of, "xdata "); break;
+                               case S_SFR: fprintf (of, "sfr "); break;
+                               case S_SBIT: fprintf (of, "sbit "); break;
+                               case S_CODE: fprintf (of, "code "); break;
+                               case S_IDATA: fprintf (of, "idata "); break;
+                               case S_PDATA: fprintf (of, "pdata "); break;
+                               case S_LITERAL: fprintf (of, "literal "); break;
+                               case S_STACK: fprintf (of, "stack "); break;
+                               case S_XSTACK: fprintf (of, "xstack "); break;
+                               case S_BIT: fprintf (of, "bit "); break;
+                               case S_EEPROM: fprintf (of, "eeprom "); break;
+                               default: break;
+                       }
 
-  }
-    
+               }
+       }
 }
-/*-----------------------------------------------------------------*/
-/* packRegisters - does some transformations to reduce register    */
-/*                   pressure                                      */
-/*-----------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------*/
+/* pic16_packRegisters - does some transformations to reduce          */
+/*                   register pressure                                */
+/*                                                                    */
+/*--------------------------------------------------------------------*/
 static void
-packRegisters (eBBlock * ebp)
+pic16_packRegisters (eBBlock * ebp)
 {
   iCode *ic;
   int change = 0;
@@ -3469,9 +3696,11 @@ packRegisters (eBBlock * ebp)
     /* TrueSym := iTempNN:1             */
     for (ic = ebp->sch; ic; ic = ic->next)
       {
-
+//             debugLog("%d\n", __LINE__);
        /* find assignment of the form TrueSym := iTempNN:1 */
-       if (ic->op == '=' && !POINTER_SET (ic))
+       /* see BUGLOG0001 for workaround with the CAST - VR */
+//     if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
+       if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
          change += packRegsForAssign (ic, ebp);
        /* debug stuff */
        if (ic->op == '=')
@@ -3494,16 +3723,28 @@ packRegisters (eBBlock * ebp)
     if(IS_SYMOP ( IC_LEFT(ic))) {
       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
 
-      debugAopGet ("  left:", IC_LEFT (ic));
+      debugAopGet ("x  left:", IC_LEFT (ic));
+#if 0
       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
+#else
+      if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
+#endif
        debugLog ("    is a pointer\n");
 
+      if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
+        debugLog ("    is a ptr\n");
+
       if(IS_OP_VOLATILE(IC_LEFT(ic)))
        debugLog ("    is volatile\n");
 
       isData(etype);
 
-      printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
+       if(IS_OP_VOLATILE(IC_LEFT(ic))) {
+           debugLog ("  %d - left is not temp, allocating\n", __LINE__);
+           pic16_allocDirReg(IC_LEFT (ic));
+       }
+
+      printSymType("c  ", OP_SYMBOL(IC_LEFT(ic))->type);
     }
 
     if(IS_SYMOP ( IC_RIGHT(ic))) {
@@ -3516,6 +3757,19 @@ packRegisters (eBBlock * ebp)
       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
     }
 
+    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__);
 
@@ -3584,8 +3838,11 @@ packRegisters (eBBlock * ebp)
        debugAopGet ("  left:", IC_LEFT (ic));
       }
 
+       //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);
+
     if (!SKIP_IC2 (ic))
       {
+       //debugLog("  %d   %s\n", __LINE__, __FUNCTION__ );
        /* if we are using a symbol on the stack
           then we should say pic16_ptrRegReq */
        if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
@@ -3596,6 +3853,8 @@ packRegisters (eBBlock * ebp)
                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
        else
          {
+
+               //debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
            if (IS_SYMOP (IC_LEFT (ic)))
              pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
                                   OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
@@ -3629,22 +3888,29 @@ packRegisters (eBBlock * ebp)
        continue;
       }
 
+       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) &&
@@ -3654,7 +3920,9 @@ 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)) &&
@@ -3663,8 +3931,10 @@ packRegisters (eBBlock * ebp)
        getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
 
       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
@@ -3685,6 +3955,7 @@ packRegisters (eBBlock * ebp)
        if (dic) {
                
          if (IS_ARITHMETIC_OP (dic)) {
+                   debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
                    
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
            IC_RESULT (dic) = IC_RESULT (ic);
@@ -3706,7 +3977,9 @@ packRegisters (eBBlock * ebp)
                
          iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
          if (dic) {
-                   
+
+                  debugLog(" %d\n", __LINE__);
+
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
            IC_RESULT (dic) = IC_RESULT (ic);
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
@@ -3718,7 +3991,7 @@ packRegisters (eBBlock * ebp)
        }
       }
     }
-
+#endif
     /* pack for PUSH 
        iTempNN := (some variable in farspace) V1
        push iTempNN ;
@@ -3731,6 +4004,7 @@ packRegisters (eBBlock * ebp)
       }
 
 
+#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
@@ -3747,9 +4021,10 @@ packRegisters (eBBlock * ebp)
 
         ) &&
        IS_ITEMP (IC_RESULT (ic)) &&
-       getSize (operandType (IC_RESULT (ic))) <= 2)
+       getSize (operandType (IC_RESULT (ic))) <= 1)
 
       packRegsForAccUse (ic);
+#endif
 
   }
 }
@@ -3759,7 +4034,7 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count)
 {
   int i;
 
-  if (!debug || !debugF)
+  if (!pic16_ralloc_debug || !debugF)
     return;
 
   for (i = 0; i < count; i++)
@@ -3817,7 +4092,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   /* change assignments this will remove some
      live ranges reducing some register pressure */
   for (i = 0; i < count; i++)
-    packRegisters (ebbs[i]);
+    pic16_packRegisters (ebbs[i]);
 
   {
     regs *reg;
@@ -3829,11 +4104,16 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
 
     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);
     }
 
   }
 
+  /* liveranges probably changed by register packing
+     so we compute them again */
+  recomputeLiveRanges (ebbs, count);
+
   if (options.dump_pack)
     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
 
@@ -3844,6 +4124,12 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   /* and serially allocate registers */
   serialRegAssign (ebbs, count);
 
+//  debugLog ("ebbs after serialRegAssign:\n");
+//  dumpEbbsToDebug (ebbs, count);
+
+
+  //pic16_freeAllRegs();
+
   /* if stack was extended then tell the user */
   if (_G.stackExtend)
     {
@@ -3881,10 +4167,10 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   /* free up any _G.stackSpil locations allocated */
   applyToSet (_G.stackSpil, deallocStackSpil);
   _G.slocNum = 0;
-  setToNull ((void **) &_G.stackSpil);
-  setToNull ((void **) &_G.spiltSet);
+  setToNull ((void *) &_G.stackSpil);
+  setToNull ((void *) &_G.spiltSet);
   /* mark all registers as free */
-  //pic16_freeAllRegs ();
+  pic16_freeAllRegs ();
 
   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
   debugLogClose ();