* sim/ucsim/cmd.src/cmdutil.cc: NUL device is detected as CG_FILE type
[fw/sdcc] / src / pic / ralloc.c
index 3be54b56bbf0d5e48f1b3afc8797324543b290b6..d51dca63908cc3bbd70662d61bd533b44c9ae55c 100644 (file)
@@ -5,35 +5,33 @@
        Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
        Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
        
-         This program is free software; you can redistribute it and/or modify it
-         under the terms of the GNU General Public License as published by the
-         Free Software Foundation; either version 2, or (at your option) any
-         later version.
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
          
-               This program is distributed in the hope that it will be useful,
-               but WITHOUT ANY WARRANTY; without even the implied warranty of
-               MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-               GNU General Public License for more details.
-               
-                 You should have received a copy of the GNU General Public License
-                 along with this program; if not, write to the Free Software
-                 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+               
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
                  
-                       In other words, you are welcome to use, share and improve this program.
-                       You are forbidden to forbid anyone else to use, share and improve
-                       what you give them.   Help stamp out software-hoarding!  
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!  
 -------------------------------------------------------------------------*/
 
 #include "common.h"
 #include "ralloc.h"
+#include "device.h"
 #include "pcode.h"
 #include "gen.h"
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
+
+#define FENTRY2                        1 ? (void)0 : printf 
 
 /* this should go in SDCCicode.h, but it doesn't. */
 #define IS_REF(op)       (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
@@ -48,7 +46,7 @@
 /*-----------------------------------------------------------------*/
 
 extern void genpic14Code (iCode *);
-extern void assignConfigWordValue(int address, int value);
+extern void pic14_assignConfigWordValue(int address, int value);
 
 /* Global data */
 static struct
@@ -78,13 +76,13 @@ set *dynInternalRegs=NULL;
 static hTab  *dynDirectRegNames= NULL;
 // static hTab  *regHash = NULL;    /* a hash table containing ALL registers */
 
-static int dynrIdx=0x20;
-static int rDirectIdx=0;
+static int dynrIdx = 0x1000;
 
 int pic14_nRegs = 128;   // = sizeof (regspic14) / sizeof (regs);
 
 int Gstack_base_addr=0; /* The starting address of registers that
-* are used to pass and return parameters */
+                        * are used to pass and return parameters */
+int Gstack_size = 0;
 
 
 
@@ -129,8 +127,9 @@ static void
        vsprintf (buffer, fmt, ap);
 
        fprintf (debugF, "%s", buffer);
+       //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
        /*
-       while (isspace(*bufferP)) bufferP++;
+       while (isspace((unsigned char)*bufferP)) bufferP++;
 
        if (bufferP && *bufferP) 
                lineCurr = (lineCurr ?
@@ -166,7 +165,7 @@ static void
 static char *
        debugAopGet (char *str, operand * op)
 {
-       if (str)
+        if (str)
                debugLog (str);
 
        printOperand (op, debugF);
@@ -189,208 +188,106 @@ static char *
 
        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";
+       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 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, "unknown op %d %c", op, op & 0xff);
        return buffer;
@@ -403,12 +300,9 @@ debugLogRegType (short type)
        
        switch (type)
        {
-       case REG_GPR:
-               return "REG_GPR";
-       case REG_PTR:
-               return "REG_PTR";
-       case REG_CND:
-               return "REG_CND";
+       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);
@@ -434,14 +328,27 @@ static int regname2key(char const *name)
        
 }
 
+static regs *regWithIdx (set *dRegs, int idx, int fixed);
 /*-----------------------------------------------------------------*/
 /* 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)
+static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
 {
        
-       regs *dReg;
+       regs *dReg, *reg_alias;
+
+       /* check whether a matching register already exists */
+       dReg = dirregWithName( name );
+       if (dReg) {
+               //printf( "%s: already present: %s\n", __FUNCTION__, name );
+               return (dReg);
+       }
+       
+       // check whether a register at that location exists
+       reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
+       if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
        
+       // create a new register
        dReg = Safe_calloc(1,sizeof(regs));
        dReg->type = type;
        dReg->pc_type = pc_type;
@@ -452,9 +359,8 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
                sprintf(buffer,"r0x%02X", dReg->rIdx);
                dReg->name = Safe_strdup(buffer);
        }
-       //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
        dReg->isFree = 0;
-       dReg->wasUsed = 1;
+       dReg->wasUsed = 0;
        if (type == REG_SFR)
                dReg->isFixed = 1;
        else
@@ -467,11 +373,11 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
        dReg->address = 0;
        dReg->size = size;
        dReg->alias = alias;
-       dReg->reg_alias = NULL;
+       dReg->reg_alias = reg_alias;
        dReg->reglives.usedpFlows = newSet();
        dReg->reglives.assignedpFlows = newSet();
-       
-       hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+       if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
+       debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
        
        return dReg;
 }
@@ -488,6 +394,7 @@ regWithIdx (set *dRegs, int idx, int fixed)
        dReg = setNextItem(dRegs)) {
                
                if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
+                       while (dReg->reg_alias) dReg = dReg->reg_alias;
                        return dReg;
                }
        }
@@ -571,24 +478,30 @@ regFindFree (set *dRegs)
        return NULL;
 }
 /*-----------------------------------------------------------------*/
-/* initStack - allocate registers for a psuedo stack               */
+/* initStack - allocate registers for a pseudo stack               */
 /*-----------------------------------------------------------------*/
-void initStack(int base_address, int size)
+void initStack(int base_address, int size, int shared)
 {
        
        int i;
-       
+       PIC_device *pic;
+
+       pic = pic14_getPIC();
        Gstack_base_addr = base_address;
-       //fprintf(stderr,"initStack");
+       Gstack_size = size;
+       //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
        
        for(i = 0; i<size; i++) {
-               regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,NULL,1,0);
-               r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
+               char buffer[16];
+               regs *r;
+               SNPRINTF(&buffer[0], 16, "STK%02d", i);
+               // multi-bank device, sharebank prohibited by user
+               r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
                r->isFixed = 1;
-               r->name[0] = 's';
-               r->alias = 0x180; // Using shared memory for pseudo stack
+               r->isPublic = 1;
+               r->isEmitted = 1;
+               //r->name[0] = 's';
                addSet(&dynStackRegs,r);
-               base_address--;
        }
 }
 
@@ -606,7 +519,7 @@ allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
 *-----------------------------------------------------------------*/
 
 regs *
-allocInternalRegister(int rIdx, char * name, short po_type, int alias)
+allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
 {
        regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
        
@@ -624,12 +537,20 @@ allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 static regs *
 allocReg (short type)
 {
+       regs *reg;
        
        debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
        //fprintf(stderr,"allocReg\n");
        
+       reg = pic14_findFreeReg (type);
+
+       reg->isFree = 0;
+       reg->wasUsed = 1;
+
+       return reg;
+       
        
-       return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+       //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
        
 }
 
@@ -655,6 +576,8 @@ dirregWithName (char *name)
        while(reg) {
                
                if(STRCASECMP(reg->name, name) == 0) {
+                       // handle registers with multiple names
+                       while (reg->reg_alias) reg = reg->reg_alias;
                        return(reg);
                }
                
@@ -668,7 +591,7 @@ dirregWithName (char *name)
 int IS_CONFIG_ADDRESS(int address)
 {
        
-       return address == 0x2007;
+       return ((address == 0x2007) || (address == 0x2008));
 }
 
 /*-----------------------------------------------------------------*/
@@ -679,10 +602,11 @@ allocNewDirReg (sym_link *symlnk,const char *name)
 {
        regs *reg;
        int address = 0;
+       sym_link *spec = getSpec (symlnk);
        
        /* if this is at an absolute address, then get the address. */
-       if (SPEC_ABSA (symlnk) ) {
-               address = SPEC_ADDR (symlnk);
+       if (SPEC_ABSA (spec) ) {
+               address = SPEC_ADDR (spec);
                //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
        }
        
@@ -695,30 +619,30 @@ allocNewDirReg (sym_link *symlnk,const char *name)
        } else {
                int idx;
                if (address) {
-                       if (IS_BITVAR (symlnk))
+                       if (IS_BITVAR (spec))
                                idx = address >> 3;
                        else
                                idx = address;
                } else {
-                       idx = rDirectIdx++;
+                       idx = dynrIdx++;
                }
                reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
                debugLog ("  -- added %s to hash, size = %d\n", (char*)name,reg->size);
                
-               if (SPEC_ABSA (symlnk) ) {
+               if (SPEC_ABSA (spec) ) {
                        reg->type = REG_SFR;
                }
                
-               if (IS_BITVAR (symlnk)) {
+               if (IS_BITVAR (spec)) {
                        addSet(&dynDirectBitRegs, reg);
                        reg->isBitField = 1;
                } else
                        addSet(&dynDirectRegs, reg);
                
-               if (!IS_STATIC (symlnk)) {
+               if (!IS_STATIC (spec)) {
                        reg->isPublic = 1;
                }
-               if (IS_EXTERN (symlnk)) {
+               if (IS_EXTERN (spec)) {
                        reg->isExtern = 1;
                }
                
@@ -813,7 +737,7 @@ allocDirReg (operand *op )
                if(!IS_CONFIG_ADDRESS(address)) {
                        //fprintf(stderr,"allocating new reg %s\n",name);
                        
-                       reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
+                       reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
                        debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
                        
                        //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
@@ -858,7 +782,7 @@ allocDirReg (operand *op )
                        debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
                }
        } else {
-               allocNewDirReg (OP_SYM_ETYPE(op),name);
+               allocNewDirReg (OP_SYM_TYPE(op),name);
        }
        
        return reg;
@@ -889,8 +813,8 @@ 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 );
+               //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
+               reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
                for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
                        if (strcmp(reg->name+1,sym->name)==0) {
                                unsigned a = SPEC_ADDR(sym->etype);
@@ -966,10 +890,19 @@ typeRegWithIdx (int idx, int type, int fixed)
                
                break;
        case REG_STK:
-               if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
+               if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
+                       debugLog ("Found a Stack Register!\n");
+                       return dReg;
+               } else
+               if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
                        debugLog ("Found a Stack Register!\n");
                        return dReg;
                }
+               else {
+                 werror (E_STACK_OUT, "Register");
+                  /* return an existing register just to avoid the SDCC crash */
+                 return regWithIdx ( dynStackRegs, 0x7f, 0);
+                }
                break;
        case REG_SFR:
                if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
@@ -1134,10 +1067,7 @@ void writeSetUsedRegs(FILE *of, set *dRegs)
        }
        
 }
-extern void assignFixedRegisters(set *regset);
-extern void assignRelocatableRegisters(set *regset,int used);
 extern void dump_map(void);
-extern void dump_sfr(FILE *of);
 
 void packBits(set *bregs)
 {
@@ -1188,7 +1118,7 @@ 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,dynrIdx++,buffer,1,0);
                                relocbitfield->isBitField = 1;
                                //addSet(&dynDirectRegs,relocbitfield);
                                addSet(&dynInternalRegs,relocbitfield);
@@ -1197,7 +1127,7 @@ void packBits(set *bregs)
                        }
                        
                        breg->reg_alias = relocbitfield;
-                       breg->address = rDirectIdx;   /* byte_no; */
+                       breg->address = dynrIdx;   /* byte_no; */
                        breg->rIdx = bit_no++;
                }
        }
@@ -1236,6 +1166,7 @@ void bitEQUs(FILE *of, set *bregs)
        }
        
 }
+
 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
 {
        regs *reg;
@@ -1261,61 +1192,13 @@ void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
 
 void writeUsedRegs(FILE *of) 
 {
-       packBits(dynDirectBitRegs);
-       
-       assignFixedRegisters(dynInternalRegs);
-       assignFixedRegisters(dynAllocRegs);
-       assignFixedRegisters(dynStackRegs);
-       assignFixedRegisters(dynDirectRegs);
        
-       assignRelocatableRegisters(dynInternalRegs,0);
-       assignRelocatableRegisters(dynAllocRegs,0);
-       assignRelocatableRegisters(dynStackRegs,0);
+       packBits(dynDirectBitRegs);
        
-       /*
-       assignRelocatableRegisters(dynDirectRegs,0);
-       printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
-       */
        //dump_map();
        
-       dump_sfr(of);
        bitEQUs(of,dynDirectBitRegs);
-       /*
-       aliasEQUs(of,dynAllocRegs,0);
-       aliasEQUs(of,dynDirectRegs,0);
-       aliasEQUs(of,dynStackRegs,0);
-       aliasEQUs(of,dynProcessorRegs,1);
-       */
-}
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* allDefsOutOfRange - all definitions are out of a range          */
-/*-----------------------------------------------------------------*/
-static bool
-allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
-{
-       int i;
-       
-       debugLog ("%s\n", __FUNCTION__);
-       if (!defs)
-               return TRUE;
-       
-       for (i = 0; i < defs->size; i++)
-       {
-               iCode *ic;
-               
-               if (bitVectBitValue (defs, i) &&
-                       (ic = hTabItemWithKey (iCodehTab, i)) &&
-                       (ic->seq >= fseq && ic->seq <= toseq))
-                       
-                       return FALSE;
-               
-       }
-       
-       return TRUE;
 }
-#endif
 
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
@@ -1440,7 +1323,7 @@ liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
                if (!bitVectBitValue (lrs, i))
                        continue;
                
-                       /* if we don't find it in the live range 
+               /* if we don't find it in the live range 
                hash table we are in serious trouble */
                if (!(sym = hTabItemWithKey (liveRanges, i)))
                {
@@ -1599,6 +1482,8 @@ createStackSpil (symbol * sym)
        
        char slocBuffer[30];
        debugLog ("%s\n", __FUNCTION__);
+
+       FENTRY2("called.");
        
        /* first go try and find a free one that is already 
        existing on the stack */
@@ -1682,6 +1567,8 @@ isSpiltOnStack (symbol * sym)
        sym_link *etype;
        
        debugLog ("%s\n", __FUNCTION__);
+       FENTRY2("called.");
+       
        if (!sym)
                return FALSE;
        
@@ -1709,6 +1596,7 @@ spillThis (symbol * sym)
 {
        int i;
        debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
+       FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
        
        /* if this is rematerializable or has a spillLocation
        we are okay, else we need to create a spillLocation
@@ -1724,25 +1612,27 @@ spillThis (symbol * sym)
        bitVectUnSetBit (_G.regAssigned, sym->key);
        
        for (i = 0; i < sym->nRegs; i++)
-               
+       {
                if (sym->regs[i])
                {
                        freeReg (sym->regs[i]);
                        sym->regs[i] = NULL;
                }
+       }
                
-               /* if spilt on stack then free up r0 & r1 
-               if they could have been assigned to some
-               LIVE ranges */
-               if (!pic14_ptrRegReq && isSpiltOnStack (sym))
-               {
-                       pic14_ptrRegReq++;
-                       spillLRWithPtrReg (sym);
-               }
+       /* if spilt on stack then free up r0 & r1 
+       if they could have been assigned to some
+       LIVE ranges */
+       if (!pic14_ptrRegReq && isSpiltOnStack (sym))
+       {
+               pic14_ptrRegReq++;
+               spillLRWithPtrReg (sym);
+       }
                
-               if (sym->usl.spillLoc && !sym->remat)
-                       sym->usl.spillLoc->allocreq = 1;
-               return;
+       if (sym->usl.spillLoc && !sym->remat)
+               sym->usl.spillLoc->allocreq = 1;
+       
+       return;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1756,13 +1646,14 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
        symbol *sym;
        
        debugLog ("%s\n", __FUNCTION__);
+       FENTRY2("called.");
        /* get the spillable live ranges */
        lrcs = computeSpillable (ic);
-       
+
+
        /* get all live ranges that are rematerizable */
        if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
        {
-               
                /* return the least used of these */
                return leastUsedLR (selectS);
        }
@@ -1800,7 +1691,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)
@@ -1830,7 +1723,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
                sym->usl.spillLoc->allocreq = 1;
                return sym;
        }
-       
+
        /* couldn't find then we need to create a spil
        location on the stack , for which one? the least
        used ofcourse */
@@ -1979,7 +1872,7 @@ tryAgain:
                        if (sym->regs[j])
                                sym->regs[j]->isFree = 0;
                        
-                               /* this looks like an infinite loop but 
+                       /* this looks like an infinite loop but 
                        in really selectSpil will abort  */
                        goto tryAgain;
 }
@@ -2020,7 +1913,36 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                /* if it does not end here */
                if (sym->liveTo > ic->seq)
                        continue;
-               
+
+               /* Prevent the result from being assigned the same registers as (one)
+                * operand as many genXXX-functions fail otherwise.
+                * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
+                * are known to fail. */
+               if (sym->liveTo == ic->seq && IC_RESULT(ic))
+               {
+                       switch (ic->op)
+                       {
+                       case '=':       /* assignment */
+                       case BITWISEAND: /* bitwise AND */
+                       case '|':       /* bitwise OR */
+                       case '^':       /* bitwise XOR */
+                       case '~':       /* bitwise negate */
+                       case RLC:       /* rotate through carry */
+                       case RRC:
+                       case UNARYMINUS:
+                       case '+':       /* addition */
+                       case '-':       /* subtraction */
+                         /* go ahead, these are safe to use with
+                          * non-disjoint register sets */
+                         break;
+
+                       default:
+                               /* do not release operand registers */
+                               //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
+                               continue;
+                       } // switch
+               }
+       
                /* if it was spilt on stack then we can 
                mark the stack spil location as free */
                if (sym->isspilt)
@@ -2035,7 +1957,6 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                
                if (!bitVectBitValue (_G.regAssigned, sym->key))
                        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
@@ -2043,6 +1964,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                if (ic->op == IFX && ic->prev &&
                        ic->prev->op == IPOP &&
                        !ic->prev->parmPush &&
+                       IS_SYMOP(IC_LEFT (ic->prev)) &&
                        !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
                        psym = OP_SYMBOL (IC_LEFT (ic->prev));
                
@@ -2063,9 +1985,12 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                                ic->op == IPOP ||
                                ic->op == RETURN ||
                                POINTER_SET (ic)) &&
+                               IS_SYMOP (IC_RESULT (ic)) &&
                                (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->regType == sym->regType &&      /* same register types */
                                result->nRegs &&        /* which needs registers */
                                !result->isspilt &&     /* and does not already have them */
@@ -2087,7 +2012,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                                        _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
                                        
                        }
-                       
+
                        /* free the remaining */
                        for (; i < sym->nRegs; i++)
                        {
@@ -2252,7 +2177,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
                /* of all instructions do */
                for (ic = ebbs[i]->sch; ic; ic = ic->next)
                {
-                       
                        debugLog ("  op: %s\n", decodeOp (ic->op));
                        
                        /* if this is an ipop that means some live
@@ -2278,16 +2202,23 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                (IC_RESULT (ic) && POINTER_SET (ic)))
                                continue;
                        
-                               /* now we need to allocate registers
+                       /* now we need to allocate registers
                        only for the result */
-                       if (IC_RESULT (ic))
+                       if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
                        {
                                symbol *sym = OP_SYMBOL (IC_RESULT (ic));
                                bitVect *spillable;
                                int willCS;
                                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 */
@@ -2297,8 +2228,8 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                        sym->liveTo <= ic->seq)
                                        continue;
                                
-                                       /* if some liverange has been spilt at the block level
-                                       and this one live beyond this block then spil this
+                               /* if some liverange has been spilt at the block level
+                               and this one live beyond this block then spil this
                                to be safe */
                                if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
                                {
@@ -2342,7 +2273,7 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                                        continue;
                                                }
                                        } else {
-                                       /* if none of the liveRanges have a spillLocation then better
+                                               /* if none of the liveRanges have a spillLocation then better
                                                to spill this one than anything else already assigned to registers */
                                                if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
                                                        /* if this is local to this block then we might find a block spil */
@@ -2357,10 +2288,12 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                if (ic->op == RECEIVE)
                                        debugLog ("When I get clever, I'll optimize the receive logic\n");
                                
-                                       /* if we need ptr regs for the right side
+                               /* if we need ptr regs for the right side
                                then mark it */
-                               if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
-                                       <= (unsigned) PTRSIZE)
+                               if (POINTER_GET (ic)
+                                       && IS_SYMOP(IC_LEFT(ic))
+                                       && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
+                                               <= (unsigned) PTRSIZE)
                                {
                                        pic14_ptrRegReq++;
                                        ptrRegSet = 1;
@@ -2378,7 +2311,7 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                        else
                                                sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
                                        
-                                               /* if the allocation failed which means
+                                       /* if the allocation failed which means
                                        this was spilt then break */
                                        if (!sym->regs[j])
                                                break;
@@ -2388,11 +2321,13 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                /* if it shares registers with operands make sure
                                that they are in the same position */
                                if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+                                       IS_SYMOP(IC_RESULT(ic)) &&
                                        OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
                                        positionRegs (OP_SYMBOL (IC_RESULT (ic)),
                                        OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
                                /* do the same for the right operand */
                                if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+                                       IS_SYMOP(IC_RESULT(ic)) &&
                                        OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
                                        positionRegs (OP_SYMBOL (IC_RESULT (ic)),
                                        OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
@@ -2409,39 +2344,39 @@ serialRegAssign (eBBlock ** ebbs, int count)
                }
        }
 
-       /* Check for and fix any problems with uninitialized operands */
+    /* 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))
+                        ebbs[i]->entryLabel != returnLabel))
                        continue;
-               
+
                for (ic = ebbs[i]->sch; ic; ic = ic->next)
                {
                        if (SKIP_IC2 (ic))
-                               continue;
-                       
+                         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);
                }
        }
-       
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -2590,7 +2525,8 @@ createRegMask (eBBlock ** ebbs, int count)
                }
        }
 }
-
+#if 0
+/* This was the active version */
 /*-----------------------------------------------------------------*/
 /* rematStr - returns the rematerialized string for a remat var    */
 /*-----------------------------------------------------------------*/
@@ -2631,8 +2567,10 @@ rematStr (symbol * sym)
        //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
        return psym;
 }
+#endif
 
 #if 0
+/* deprecated version */
 /*-----------------------------------------------------------------*/
 /* rematStr - returns the rematerialized string for a remat var    */
 /*-----------------------------------------------------------------*/
@@ -2690,20 +2628,20 @@ regTypeNum ()
 {
        symbol *sym;
        int k;
-       iCode *ic;
+       //iCode *ic;
        
        debugLog ("%s\n", __FUNCTION__);
        /* for each live range do */
        for (sym = hTabFirstItem (liveRanges, &k); sym;
        sym = hTabNextItem (liveRanges, &k)) {
-               
+
                debugLog ("  %d - %s\n", __LINE__, sym->rname);
                
                /* if used zero times then no registers needed */
                if ((sym->liveTo - sym->liveFrom) == 0)
                        continue;
-               
-               
+
+
                /* if the live range is a temporary */
                if (sym->isitmp) {
                        
@@ -2713,7 +2651,7 @@ regTypeNum ()
                        if (sym->regType == REG_CND)
                                continue;
                        
-                               /* if used in return only then we don't 
+                       /* if used in return only then we don't 
                        need registers */
                        if (sym->accuse) {
                                if (IS_AGGREGATE (sym->type) || sym->isptr)
@@ -2736,6 +2674,7 @@ regTypeNum ()
                        pointer we are getting is rematerializable and
                        in "data" space */
                        
+#if 0
                        if (bitVectnBitsOn (sym->defs) == 1 &&
                            (ic = hTabItemWithKey (iCodehTab,
                                                   bitVectFirstBit (sym->defs))) &&
@@ -2749,7 +2688,7 @@ regTypeNum ()
                                        
                                        debugLog ("  %d - \n", __LINE__);
                                
-                                       /* create a psuedo symbol & force a spil */
+                                       /* create a pseudo symbol & force a spil */
                                        //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
                                        psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
                                        psym->type = sym->type;
@@ -2765,6 +2704,7 @@ regTypeNum ()
                                allocate pointer register */
                                
                        }
+#endif
                        
                        /* if not then we require registers */
                        sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
@@ -2800,7 +2740,7 @@ regTypeNum ()
                        /* registers for true symbols we will */
                        /* see how things go                  */
                        sym->nRegs = 0;
-  }
+       }
   
 }
 DEFSETFUNC (markRegFree)
@@ -2962,7 +2902,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
                        if(IS_VALOP(IC_RIGHT(ic))) {
                                debugLog ("  setting config word to %x\n", 
                                        (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
-                               assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
+                               pic14_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
                                        (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
                        }
                        
@@ -3020,7 +2960,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
        for (dic = ic->prev; dic; dic = dic->prev)
        {
                
-       /* if there is a function call and this is
+               /* if there is a function call and this is
                a parameter & not my parameter then don't pack it */
                if ((dic->op == CALL || dic->op == PCALL) &&
                        (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
@@ -3085,8 +3025,21 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
        if (!dic)
                return 0;                       /* did not find */
        
-                                                       /* if the result is on stack or iaccess then it must be
-       the same atleast one of the operands */
+       /* 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))
+                               return 0;
+               }
+       }
+
+       /* if the result is on stack or iaccess then it must be
+       the same at least one of the operands */
        if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
                OP_SYMBOL (IC_RESULT (ic))->iaccess)
        {
@@ -3308,18 +3261,18 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
        if (!IS_SYMOP (op))
                return NULL;
        
-               /* only upto 2 bytes since we cannot predict
+       /* only upto 2 bytes since we cannot predict
        the usage of b, & acc */
        if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
                ic->op != RETURN &&
                ic->op != SEND)
                return NULL;
        
-               /* this routine will mark the a symbol as used in one 
-               instruction use only && if the definition is local 
-               (ie. within the basic block) && has only one definition &&
-               that definition is either a return value from a 
-               function or does not contain any variables in
+       /* this routine will mark the a symbol as used in one 
+       instruction use only && if the definition is local 
+       (ie. within the basic block) && has only one definition &&
+       that definition is either a return value from a 
+       function or does not contain any variables in
        far space */
        uses = bitVectCopy (OP_USES (op));
        bitVectUnSetBit (uses, ic->key);        /* take away this iCode */
@@ -3460,10 +3413,22 @@ isBitwiseOptimizable (iCode * ic)
 static void
 packRegsForAccUse (iCode * ic)
 {
-       iCode *uic;
+       //iCode *uic;
        
        debugLog ("%s\n", __FUNCTION__);
-       
+
+       /* result too large for WREG? */
+       if (getSize (operandType (IC_RESULT (ic))) > 1)
+         return;
+       
+       /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
+        * is never used as an operand to an instruction that
+        * cannot have WREG as an operand (e.g. BTFSx cannot
+        * operate on WREG...
+        * For now, store all results into proper registers. */
+       return;
+
+#if 0
        /* if this is an aggregate, e.g. a one byte char array */
        if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
                return;
@@ -3600,8 +3565,7 @@ packRegsForAccUse (iCode * ic)
 accuse:
        debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
        OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
-       
-       
+#endif 
 }
 
 /*-----------------------------------------------------------------*/
@@ -3721,6 +3685,7 @@ void isData(sym_link *sl)
        }
        
 }
+
 /*-----------------------------------------------------------------*/
 /* packRegisters - does some transformations to reduce register    */
 /*                   pressure                                      */
@@ -3743,7 +3708,7 @@ packRegisters (eBBlock * ebp)
                /* TrueSym := iTempNN:1             */
                for (ic = ebp->sch; ic; ic = ic->next)
                {
-                       
+
                        /* find assignment of the form TrueSym := iTempNN:1 */
                        if (ic->op == '=' && !POINTER_SET (ic))
                                change += packRegsForAssign (ic, ebp);
@@ -3794,7 +3759,46 @@ packRegisters (eBBlock * ebp)
                        debugLog ("  %d - Pointer set\n", __LINE__);
                
                
-                       /* if this is an itemp & result of a address of a true sym 
+               /* 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 &&
                        IS_ITEMP (IC_RESULT (ic)) &&
@@ -3845,13 +3849,13 @@ packRegisters (eBBlock * ebp)
                }
                
                /* mark the pointer usages */
-               if (POINTER_SET (ic))
+               if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
                {
                        OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
                        debugLog ("  marking as a pointer (set) =>");
                        debugAopGet ("  result:", IC_RESULT (ic));
                }
-               if (POINTER_GET (ic))
+               if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
                {
                        OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
                        debugLog ("  marking as a pointer (get) =>");
@@ -3860,7 +3864,7 @@ packRegisters (eBBlock * ebp)
                
                if (!SKIP_IC2 (ic))
                {
-               /* if we are using a symbol on the stack
+                       /* if we are using a symbol on the stack
                        then we should say pic14_ptrRegReq */
                        if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
                                pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
@@ -3923,6 +3927,7 @@ packRegisters (eBBlock * ebp)
                one and right is not in far space */
                if (POINTER_SET (ic) &&
                        !isOperandInFarSpace (IC_RIGHT (ic)) &&
+                       IS_SYMOP(IC_RESULT(ic)) &&
                        !OP_SYMBOL (IC_RESULT (ic))->remat &&
                        !IS_OP_RUONLY (IC_RIGHT (ic)) &&
                        getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
@@ -3932,6 +3937,7 @@ packRegisters (eBBlock * ebp)
                /* if pointer get */
                if (POINTER_GET (ic) &&
                        !isOperandInFarSpace (IC_RESULT (ic)) &&
+                       IS_SYMOP(IC_LEFT(ic)) &&
                        !OP_SYMBOL (IC_LEFT (ic))->remat &&
                        !IS_OP_RUONLY (IC_RESULT (ic)) &&
                        getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
@@ -3939,10 +3945,10 @@ packRegisters (eBBlock * ebp)
                        packRegsForOneuse (ic, IC_LEFT (ic), ebp);
                
                
-                       /* if this is cast for intergral promotion then
-                       check if only use of  the definition of the 
-                       operand being casted/ if yes then replace
-                       the result of that arithmetic operation with 
+               /* if this is cast for intergral promotion then
+               check if only use of  the definition of the 
+               operand being casted/ if yes then replace
+               the result of that arithmetic operation with 
                this result and get rid of the cast */
                if (ic->op == CAST) {
                        
@@ -3973,7 +3979,7 @@ packRegisters (eBBlock * ebp)
                                }
                        } else {
                                
-                       /* if the type from and type to are the same
+                               /* if the type from and type to are the same
                                then if this is the only use then packit */
                                if (compareType (operandType (IC_RIGHT (ic)),
                                        operandType (IC_LEFT (ic))) == 1) {
@@ -4025,7 +4031,7 @@ packRegisters (eBBlock * ebp)
                        
                        packRegsForAccUse (ic);
                
-  }
+       }
 }
 
 static void
@@ -4075,13 +4081,15 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count)
 /* assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
 void
-pic14_assignRegisters (eBBlock ** ebbs, int count)
+pic14_assignRegisters (ebbIndex * ebbi)
 {
+       eBBlock ** ebbs = ebbi->bbOrder;
+       int count = ebbi->count;
        iCode *ic;
        int i;
        
-       debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
-       debugLog ("\nebbs before optimizing:\n");
+       debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
+       debugLog ("ebbs before optimizing:\n");
        dumpEbbsToDebug (ebbs, count);
        
        setToNull ((void *) &_G.funcrUsed);
@@ -4109,7 +4117,7 @@ pic14_assignRegisters (eBBlock ** ebbs, int 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 */
@@ -4141,7 +4149,7 @@ pic14_assignRegisters (eBBlock ** ebbs, int count)
        redoStackOffsets ();
        
        if (options.dump_rassgn)
-               dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+               dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
        
        /* now get back the chain */
        ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));