]
[fw/sdcc] / src / pic16 / ralloc.c
index 848702fe658937c38aed87c0f057e00b62c8ea52..6b8550fb0ab33bcea76866dbeb9a7ebb9413c409 100644 (file)
@@ -46,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);
 
@@ -78,9 +78,10 @@ set *pic16_dynInternalRegs=NULL;
 static hTab  *dynDirectRegNames= NULL;
 //static hTab  *regHash = NULL;    /* a hash table containing ALL registers */
 
-set *pic16_rel_udata=NULL;
-set *pic16_fix_udata=NULL;
-set *pic16_equ_data=NULL;
+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;
 
@@ -339,7 +340,7 @@ static int regname2key(char const *name)
 /*-----------------------------------------------------------------*/
 /* newReg - allocate and init memory for a new register            */
 /*-----------------------------------------------------------------*/
-static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
+regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
 {
 
   regs *dReg;
@@ -357,22 +358,24 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
                        dReg->name = Safe_strdup(buffer);
        }
 
-//     fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
 
        dReg->isFree = 0;
        dReg->wasUsed = 1;
 
 //     dReg->isMapped = 0;
        dReg->isEmitted = 0;
-       dReg->accessBank = 0;
 
        if(type == REG_SFR) {
                dReg->isFixed = 1;
                dReg->address = rIdx;
+               dReg->accessBank = 1;
        } else {
                dReg->isFixed = 0;
                dReg->address = 0;
+               dReg->accessBank = 0;
        }
+
+//     fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
        
        dReg->size = size;
        dReg->alias = alias;
@@ -381,7 +384,8 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
        dReg->reglives.assignedpFlows = newSet();
        dReg->regop = refop;
   
-       hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+       if(!(type == REG_SFR && alias == 0x80))
+               hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
 
   return dReg;
 }
@@ -486,12 +490,8 @@ allocReg (short type)
        return NULL;
 #endif
 
-#if STACK_SUPPORT
-       if(USE_STACK) {
-               /* try to reuse some unused registers */
-               reg = regFindFree( pic16_dynAllocRegs );
-       }
-#endif
+       /* try to reuse some unused registers */
+       reg = regFindFree( pic16_dynAllocRegs );
 
        if(!reg) {
                reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
@@ -499,7 +499,7 @@ allocReg (short type)
        }
        reg->isFree=0;
 
-       debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
+//     debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
 
 //     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);
@@ -509,10 +509,10 @@ allocReg (short type)
                reg->isLocal = 1;       /* this is a local frame register */
        }
        
-#if STACK_SUPPORT
-       if (currFunc)
+       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);
-#endif
+       }
  
   return (reg);                // addSet(&pic16_dynAllocRegs,reg);
 
@@ -564,122 +564,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 symbol name %s\n", __FUNCTION__,name);
+//     fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
 
-  /* The above hack is not necessery anymore, since .asm include files are not
-   * used by current implementation of the port -- VR 03-Jan-04 */
+       {
+               if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
+                       debugLog(" %d  const char\n",__LINE__);
+                       debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+//                     fprintf(stderr, " %d  const char\n",__LINE__);
+//                     fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+               }
 
-  debugLog ("%s symbol name %s\n", __FUNCTION__,name);
-//  fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
-  {
-    if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
-      debugLog(" %d  const char\n",__LINE__);
-      debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
-//      fprintf(stderr, " %d  const char\n",__LINE__);
-//      fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
-    }
-
-    debugLog("  %d  storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
-    if (IS_CODE ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  code space\n",__LINE__);
-
-    if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  integral\n",__LINE__);
-    if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  literal\n",__LINE__);
-    if (IS_SPEC ( OP_SYM_ETYPE(op)) )
-      debugLog(" %d  specifier\n",__LINE__);
-    debugAopGet(NULL, op);
-  }
+       
+               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_CODE ( OP_SYM_ETYPE(op)) )
-    return NULL;
+               if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  integral\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_LITERAL ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  literal\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_SPEC ( OP_SYM_ETYPE(op)) )
+                       debugLog(" %d  specifier\n",__LINE__);
 
-  if(!reg) {
-    int address = 0;
+               debugAopGet(NULL, op);
+       }
 
-    /* if this is at an absolute address, then get the address. */
-    if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
-      address = SPEC_ADDR ( OP_SYM_ETYPE(op));
-      //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
-    }
+       if (IS_CODE ( OP_SYM_ETYPE(op)) )
+               return NULL;
 
-    /* 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);
-       return NULL;
-    }
-    if(!IS_CONFIG_ADDRESS(address)) {
-      //fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
+       /* 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);
 
-      reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
-      debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
+#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);
+       }
 
-      //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);       /* commented out */
+       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);
+               }
 
-      if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+               /* Register wasn't found in hash, so let's create
+                * a new one and put it in the hash table AND in the 
+                * dynDirectRegNames set */
+               if(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;
+               }
 
-       //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
-       reg->type = REG_SFR;
-      }
+               if(!IS_CONFIG_ADDRESS(address)) {
+//                     fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
 
-      if (IS_BITVAR (OP_SYM_ETYPE(op))) {
-       addSet(&pic16_dynDirectBitRegs, reg);
-       reg->isBitField = 1;
-      } else
-       addSet(&pic16_dynDirectRegs, reg);
+                       /* this is an error, why added? -- VR */
+//                     if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
 
-    } else {
-      debugLog ("  -- %s is declared at address 0x30000x\n",name);
-      fprintf(stderr, "  -- %s is declared at address 0x30000x\n",name);
+                       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;
+                       }
 
-      return NULL;
-    }
-  }
+                       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));
-    debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
-  }
+       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;
 }
@@ -722,13 +765,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) {
 
@@ -774,13 +817,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;
@@ -796,6 +839,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) {
 
@@ -930,7 +974,8 @@ 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)
 {
@@ -953,7 +998,7 @@ static void packBits(set *bregs)
     if(breg->isFixed) {
       //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
 
-      bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
+      bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
       breg->rIdx = breg->address & 7;
       breg->address >>= 3;
 
@@ -1082,19 +1127,19 @@ void pic16_writeUsedRegs(FILE *of)
 //     pic16_dump_map();
 //     pic16_dump_cblock(of);
 
+       /* dump equates */
        pic16_dump_equates(of, pic16_equ_data);
+
+       /* 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
-       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
-
 }
 
 #if 0
@@ -1734,6 +1779,7 @@ static regs *
 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
   debugLog ("%s\n", __FUNCTION__);
 tryAgain:
@@ -1749,6 +1795,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;
@@ -1761,6 +1812,7 @@ static regs *
 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
   debugLog ("%s\n", __FUNCTION__);
 tryAgain:
@@ -1776,6 +1828,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;
@@ -2001,6 +2058,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  */
 /*-----------------------------------------------------------------*/
@@ -2170,6 +2252,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);
+          }
+      }    
+    
 }
 
 /*-----------------------------------------------------------------*/
@@ -2498,8 +2614,9 @@ regTypeNum ()
 #else
     if(IS_CODEPTR (sym->type)) {
 #endif
-      debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
-      sym->nRegs = 2;
+      // what IS this ???? (HJD)
+      debugLog ("  %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
+      sym->nRegs = 3; // patch 14
     }
 
       if (sym->nRegs > 4) {
@@ -2729,14 +2846,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
 
     }
 
-#if 0
-       if(ic->op == CALL || ic->op == PCALL) {
-               addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic)));
-               debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name);
-               return 0;
-       }
-#endif
-
   /* 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 */
@@ -2803,6 +2912,17 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
        }
 #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)
        {
@@ -2846,12 +2966,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))) ||
@@ -2898,6 +3044,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 */
 /*-----------------------------------------------------------------*/
@@ -2938,6 +3095,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)
@@ -2975,7 +3137,10 @@ findAssignToSym (operand * op, iCode * ic)
 
 
 }
+#endif
 
+
+#ifndef NO_packRegsForSupport
 /*-----------------------------------------------------------------*/
 /* packRegsForSupport :- reduce some registers for support calls   */
 /*-----------------------------------------------------------------*/
@@ -3053,10 +3218,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 */
 /*-----------------------------------------------------------------*/
@@ -3073,7 +3240,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;
@@ -3186,6 +3353,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   return sic;
 
 }
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
@@ -3217,6 +3386,9 @@ isBitwiseOptimizable (iCode * ic)
     return FALSE;
 }
 
+
+#ifndef NO_packRegsForAccUse
+
 /*-----------------------------------------------------------------*/
 /* packRegsForAccUse - pack registers for acc use                  */
 /*-----------------------------------------------------------------*/
@@ -3339,6 +3511,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))) ||
@@ -3348,6 +3521,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 */
@@ -3371,6 +3545,8 @@ accuse:
 
 
 }
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* packForPush - hueristics to reduce iCode for pushing            */
@@ -3489,6 +3665,7 @@ static void isData(sym_link *sl)
        }
 }
 
+
 /*--------------------------------------------------------------------*/
 /* pic16_packRegisters - does some transformations to reduce          */
 /*                   register pressure                                */
@@ -3515,7 +3692,8 @@ pic16_packRegisters (eBBlock * ebp)
 //             debugLog("%d\n", __LINE__);
        /* find assignment of the form TrueSym := iTempNN:1 */
        /* see BUGLOG0001 for workaround with the CAST - VR */
-       if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
+//     if ( (ic->op == '=' || 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 == '=')
@@ -3572,6 +3750,19 @@ pic16_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__);
 
@@ -3692,22 +3883,27 @@ pic16_packRegisters (eBBlock * ebp)
 
        debugLog(" %d\n", __LINE__);
 
+#ifndef NO_packRegsForSupport
     /* reduce for support function calls */
     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
       packRegsForSupport (ic, ebp);
+#endif
 
     /* if a parameter is passed, it's in W, so we may not
        need to place a copy in a register */
     if (ic->op == RECEIVE)
       packForReceive (ic, ebp);
 
+#ifndef NO_packRegsForOneuse
     /* some cases the redundant moves can
        can be eliminated for return statements */
     if ((ic->op == RETURN || ic->op == SEND) &&
        !isOperandInFarSpace (IC_LEFT (ic)) &&
        !options.model)
       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+#endif
 
+#ifndef NO_packRegsForOneuse
     /* if pointer set & left has a size more than
        one and right is not in far space */
     if (POINTER_SET (ic) &&
@@ -3717,7 +3913,9 @@ pic16_packRegisters (eBBlock * ebp)
        getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
 
       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+#endif
 
+#ifndef NO_packRegsForOneuse
     /* if pointer get */
     if (POINTER_GET (ic) &&
        !isOperandInFarSpace (IC_RESULT (ic)) &&
@@ -3727,7 +3925,9 @@ pic16_packRegisters (eBBlock * ebp)
 
       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
       debugLog("%d - return from packRegsForOneuse\n", __LINE__);
+#endif
 
+#ifndef NO_cast_peep
     /* if this is cast for intergral promotion then
        check if only use of  the definition of the 
        operand being casted/ if yes then replace
@@ -3784,7 +3984,7 @@ pic16_packRegisters (eBBlock * ebp)
        }
       }
     }
-
+#endif
     /* pack for PUSH 
        iTempNN := (some variable in farspace) V1
        push iTempNN ;
@@ -3797,6 +3997,7 @@ pic16_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
@@ -3813,9 +4014,10 @@ pic16_packRegisters (eBBlock * ebp)
 
         ) &&
        IS_ITEMP (IC_RESULT (ic)) &&
-       getSize (operandType (IC_RESULT (ic))) <= 2)
+       getSize (operandType (IC_RESULT (ic))) <= 1)
 
       packRegsForAccUse (ic);
+#endif
 
   }
 }
@@ -3915,6 +4117,10 @@ 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 */