* src/pic16/gen.c (genrshTwo): fixed sign extension
[fw/sdcc] / src / pic16 / gen.c
index 2604eeac64a0e6ebc530154fc798da47ea19c94f..570188af1303f578b0dbfa6be7505939c870f9d2 100644 (file)
@@ -1,4 +1,4 @@
-/*-------------------------------------------------------------------------
+ /*-------------------------------------------------------------------------
  gen.c - source file for code generation for pic16
 
   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
@@ -7,6 +7,7 @@
   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
   PIC16 port -  Martin Dubuc m.dubuc@rogers.com (2002)
              -  Vangelis Rokas vrokas@otenet.gr (2003,2004,2005)
+  Bug Fixes  -  Raphael Neider rneider@web.de (2004,2005)
   
   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
@@ -68,7 +69,6 @@ extern void pic16_printpBlock(FILE *of, pBlock *pb);
 static asmop *newAsmop (short type);
 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
-static void mov2f(asmop *dst, asmop *src, int offset);
 static void mov2fp(pCodeOp *dst, asmop *src, int offset);
 static pCodeOp *pic16_popRegFromIdx(int rIdx);
 
@@ -135,6 +135,7 @@ static char *one  = "#0x01";
  
 
 char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" };
+int fReturnIdx[] = {IDX_WREG, IDX_PRODL, IDX_PRODH, IDX_FSR0L };
 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
 static char **fReturn = fReturnpic16;
 
@@ -154,22 +155,14 @@ static struct {
     set *sendSet;
     set *stackRegSet;
     int usefastretfie;
-    bitVect *fregsUsed;
+    bitVect *fregsUsed;                        /* registers used in function */
+    bitVect *sregsAlloc;
+    set *sregsAllocSet;                        /* registers used to store stack variables */
     int stack_lat;                     /* stack offset latency */
     int resDirect;
     int useWreg;                       /* flag when WREG is used to pass function parameter */
 } _G;
 
-/* Resolved ifx structure. This structure stores information
-   about an iCode ifx that makes it easier to generate code.
-*/
-typedef struct resolvedIfx {
-  symbol *lbl;     /* pointer to a label */
-  int condition;   /* true or false ifx */
-  int generated;   /* set true when the code associated with the ifx
-                   * is generated */
-} resolvedIfx;
-
 extern int pic16_ptrRegReq ;
 extern int pic16_nRegs;
 extern FILE *codeOutFile;
@@ -310,7 +303,9 @@ void pic16_emitpLabelFORCE(int key)
   pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset));
 }
 
-void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+/* gen.h defines a macro pic16_emitpcode that allows for debug information to be inserted on demand
+ * NEVER call pic16_emitpcode_real directly, please... */
+void pic16_emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
 {
 
   if(pcop)
@@ -683,26 +678,35 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
         aop->size = getSize(sym->type);
 
 
-        DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__);
-        if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
-          && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) {
-          pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
+        DEBUGpic16_emitcode("; +++ ", "%s:%d\top = %s", __FILE__, __LINE__, pic16_decodeOp(ic->op));
+        if((ic->op == '=' /*|| ic->op == CAST*/) && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
+          && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG)) {
+//          pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
           
           for(i=0;i<aop->size;i++)
             aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
             _G.resDirect = 1;  /* notify that result will be loaded directly from aopForSym */
         } else
+        if(1 && ic->op == SEND) {
+
+          /* if SEND do the send here */
+          _G.resDirect = 1;
+        } else {
           for(i=0;i<aop->size;i++) {
-            aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
-            _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
+            aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond(_G.fregsUsed, _G.sregsAlloc, 0 );
+            _G.sregsAlloc = bitVectSetBit(_G.sregsAlloc, PCOR(pcop[i])->r->rIdx);
           }
+        }
 
 
 //        fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
 
 #if 1
        DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack);
-       
+
+       // we do not need to load the value if it is to be defined...
+       if (result) return aop;
+
        if(_G.accInUse) {
                pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
        }
@@ -719,9 +723,17 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
              assert (soffs < 0);
              soffs++;
            } // if
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
-           pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                           pic16_popCopyReg( pic16_frame_plusw ), pcop[i]));
+
+            if(1 && ic->op == SEND) {
+              pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + aop->size - i - 1 /*+ _G.stack_lat*/));
+              pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                    pic16_popCopyReg( pic16_frame_plusw ),
+                    pic16_popCopyReg(pic16_stack_postdec )));
+            } else {
+              pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
+              pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                 pic16_popCopyReg( pic16_frame_plusw ), pcop[i]));
+            }
          }
        }
        
@@ -797,7 +809,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     }
 #endif
 
-#if 0
+#if 1
     /* special case for a function */
     if (IS_FUNC(sym->type)) {   
         sym->aop = aop = newAsmop(AOP_PCODE);
@@ -869,8 +881,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
                aop->size = PTRSIZE;
        else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
                aop->size = FPTRSIZE;
-       else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
-       else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
+       else if(IC_LEFT(ic) && AOP(IC_LEFT(ic))) aop->size = AOP_SIZE( IC_LEFT(ic) );
+       else if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic))) aop->size = AOP_SIZE( IC_RIGHT(ic) );
        else if(sym->onStack) {
                aop->size = PTRSIZE;
         } else {
@@ -1193,7 +1205,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
     b) has a spill location */
     if (sym->isspilt || sym->nRegs == 0) {
 
-//      debugf2("%s:%d symbol %s\tisspilt: %d\tnRegs: %d\n", sym->isspilt, sym->nRegs);
+//      debugf3("symbol %s\tisspilt: %d\tnRegs: %d\n", sym->rname, sym->isspilt, sym->nRegs);
       DEBUGpic16_emitcode(";","%d",__LINE__);
         /* rematerialize it NOW */
         if (sym->remat) {
@@ -1220,7 +1232,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
 #endif
 
 #if 1
-        if (sym->ruonly ) {
+        if (sym->ruonly) {
          /*
          sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
          aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
@@ -1230,10 +1242,10 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
 
          unsigned i;
 
-         aop = op->aop = sym->aop = newAsmop(AOP_STR);
+         aop = op->aop = sym->aop = newAsmop(AOP_REG);
          aop->size = getSize(sym->type);
          for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
-           aop->aopu.aop_str[i] = fReturn[i];
+           aop->aopu.aop_reg[i] = PCOR(pic16_popRegFromIdx( fReturnIdx[i] ))->r;
 
          DEBUGpic16_emitcode(";","%d",__LINE__);
          return;
@@ -1260,9 +1272,9 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
                                                  sym->usl.spillLoc->offset, op);
        } else {
          fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK!\n", __FUNCTION__, __LINE__);
-         DEBUGpic16_emitcode (";","%s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
+         pic16_emitpcomment (";!!! %s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
          assert (getSize(sym->type) <= 1);
-         aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);//pic16_popRegFromString("_WREG", getSize(sym->type), 0, op);
+         aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);
        }
         aop->size = getSize(sym->type);
 
@@ -1373,8 +1385,13 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
               }
 
               if(!_G.resDirect) {
-                for(i=0;i<aop->size;i++)
+                for(i=0;i<aop->size;i++) {
                   PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
+
+                  if(bitVectBitValue(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx))
+                      bitVectUnSetBit(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx);
+                }
+                  
               }
               _G.resDirect = 0;
           }
@@ -1547,9 +1564,14 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
        
     case AOP_STR:
        aop->coff = offset ;
-       if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
-           dname)
-           return "acc";
+
+//     if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
+//         dname)
+//         return "acc";
+        if(!strcmp(aop->aopu.aop_str[offset], "WREG")) {
+          aop->type = AOP_ACC;
+          return Safe_strdup("WREG");
+        }
         DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
        
        return aop->aopu.aop_str[offset];
@@ -1562,9 +1584,9 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
          DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
          //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
          if (offset) {
-           sprintf(s,"(%s + %d)", pcop->name, offset);
+           sprintf(s,"(%s + %d)", pic16_get_op (pcop, NULL, 0), offset);
          } else {
-           sprintf(s,"%s", pcop->name);
+           sprintf(s,"%s", pic16_get_op (pcop, NULL, 0));
          }
        } else
          sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
@@ -1653,13 +1675,15 @@ pCodeOp *pic16_popGetTempReg(int lock)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic16_popGetTempRegCond - create a new temporary pCodeOp, but   */
-/*                            don't save if inside v               */
+/* pic16_popGetTempRegCond - create a new temporary pCodeOp which  */
+/*                           is not part of f, but don't save if   */
+/*                           inside v                              */
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
+pCodeOp *pic16_popGetTempRegCond(bitVect *f, bitVect *v, int lock)
 {
-  pCodeOp *pcop;
+  pCodeOp *pcop=NULL;
   symbol *cfunc;
+  int i;
 
 //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -1672,15 +1696,58 @@ pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
     cfunc = currFunc;
     currFunc = NULL;
 
-    pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
-    if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
-      PCOR(pcop)->r->wasUsed=1;
-      PCOR(pcop)->r->isFree=0;
+    i = bitVectFirstBit(f);
+    while(i < 128) {
 
-      if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) {
-      /* push value on stack */
-        pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+      /* bypass registers that are used by function */
+      if(!bitVectBitValue(f, i)) {
+      
+        /* bypass registers that are already allocated for stack access */
+        if(!bitVectBitValue(v, i))  {
+        
+//          debugf("getting register rIdx = %d\n", i);
+          /* ok, get the operand */
+          pcop = pic16_newpCodeOpReg( i );
+    
+          /* should never by NULL */
+          assert( pcop != NULL );
+
+          
+          /* sanity check */
+          if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
+            int found=0;
+            
+              PCOR(pcop)->r->wasUsed=1;
+              PCOR(pcop)->r->isFree=0;
+
+
+              {
+                regs *sr;
+              
+                  for(sr=setFirstItem(_G.sregsAllocSet);sr;sr=setNextItem(_G.sregsAllocSet)) {
+
+                    if(sr->rIdx == PCOR(pcop)->r->rIdx) {
+                      /* already used in previous steps, break */
+                      found=1;          
+                      break;
+                    }
+                  }
+              }
+
+              /* caller takes care of the following */
+//              bitVectSetBit(v, i);
+
+              if(!found) {
+                /* push value on stack */
+                pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+                addSet(&_G.sregsAllocSet, PCOR(pcop)->r);
+              }
+          
+            break;
+          }
+        }
       }
+      i++;
     }
 
     currFunc = cfunc;
@@ -1700,6 +1767,7 @@ void pic16_popReleaseTempReg(pCodeOp *pcop, int lock)
 
   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
     PCOR(pcop)->r->isFree = 1;
+
     pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
   }
 }
@@ -1725,17 +1793,20 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
   pCodeOpReg *pcor;
 
   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
-  pcor->pcop.type = pc->pcop.type;
+  memcpy (pcor, pc, sizeof (pCodeOpReg));
+  pcor->r->wasUsed = 1;
+  
+  //pcor->pcop.type = pc->pcop.type;
   if(pc->pcop.name) {
     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
   } else
     pcor->pcop.name = NULL;
 
-  pcor->r = pc->r;
-  pcor->rIdx = pc->rIdx;
-  pcor->r->wasUsed=1;
-  pcor->instance = pc->instance;
+  //pcor->r = pc->r;
+  //pcor->rIdx = pc->rIdx;
+  //pcor->r->wasUsed=1;
+  //pcor->instance = pc->instance;
 
 //  DEBUGpic16_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
 
@@ -2011,7 +2082,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        PCOR(pcop)->instance = offset;
        pcop->type = PCOR(pcop)->r->pc_type;
        
-       DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s\n", __LINE__, dumpPicOptype(pcop->type));
+       DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s", __LINE__, dumpPicOptype(pcop->type));
        rs = aop->aopu.aop_reg[offset]->name;
        DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs);
        return pcop;
@@ -2053,7 +2124,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
       switch( aop->aopu.pcop->type ) {
         case PO_DIR: PCOR(pcop)->instance += offset; break;
         case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
-        case PO_WREG: assert (offset==0); break;
+        case PO_WREG:
+            assert (offset==0);
+            break;
         default:
          fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type);
           assert( 0 ); /* should never reach here */;
@@ -2312,7 +2385,7 @@ void pic16_mov2w (asmop *aop, int offset)
     pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
 }
 
-static void mov2f(asmop *dst, asmop *src, int offset)
+void pic16_mov2f(asmop *dst, asmop *src, int offset)
 {
   if(is_LitAOp(src)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
@@ -2336,7 +2409,7 @@ static void mov2fp(pCodeOp *dst, asmop *src, int offset)
 
 void pic16_testStackOverflow(void)
 {
-#define        GSTACK_TEST_NAME        "__gstack_test"
+#define        GSTACK_TEST_NAME        "_gstack_test"
 
   pic16_emitpcode(POC_CALL, pic16_popGetWithString( GSTACK_TEST_NAME ));
   
@@ -2344,7 +2417,8 @@ void pic16_testStackOverflow(void)
     symbol *sym;
 
       sym = newSymbol( GSTACK_TEST_NAME , 0 );
-      strcpy(sym->rname, GSTACK_TEST_NAME);
+      sprintf(sym->rname, "%s%s", port->fun_prefix, GSTACK_TEST_NAME);
+//      strcpy(sym->rname, GSTACK_TEST_NAME);
       checkAddSym(&externs, sym);
   }
 
@@ -2375,7 +2449,7 @@ void pic16_poppCodeOp(pCodeOp *pcop)
 void pushw(void)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1));
+  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
 }
@@ -2390,10 +2464,10 @@ void pushaop(asmop *aop, int offset)
 
   if(is_LitAOp(aop)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
-    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));       //&pic16_pc_postdec1));
+    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
   } else {
     pic16_emitpcode(POC_MOVFF,
-      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec )));     //&pic16_pc_postdec1)));
+      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec )));
   }
 
   if(pic16_options.gstack)
@@ -2719,7 +2793,7 @@ static void genUminusFloat(operand *op,operand *result)
     size = AOP_SIZE(op);
 
     while(size--) {
-      mov2f(AOP(result), AOP(op), offset);
+      pic16_mov2f(AOP(result), AOP(op), offset);
       offset++;
     }
     
@@ -3306,7 +3380,9 @@ static void genCall (iCode *ic)
 
 //                pushaop(AOP(IC_LEFT(sic)), size);
                 pic16_mov2w (AOP(IC_LEFT(sic)), size);
-                pushw();
+
+                if(!_G.resDirect)
+                  pushw();
               }
             }
 
@@ -3581,46 +3657,33 @@ static void genFunction (iCode *ic)
       char asymname[128];
       pBlock *apb;
 
-
 //        debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type));
 
-#if 0
-        {
-          int i, found=-1;
-
-            sym = OP_SYMBOL( IC_LEFT(ic));
-            for(i=0;i<=2;i++) {
-              if(interrupts[i]->name
-                    && !STRCASECMP(interrupts[i]->name, sym->name)) {
-                  found = i;
-                  break;
-              }
-            }
-                       
-            if(found == -1) {
-              fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
-                            __FILE__, __LINE__, sym->name);
-//              assert( 0 );
-            }
-            _G.interruptvector = found;
-        }
-#endif
-
-        if(FUNC_INTNO(sym->type) == 256)
+        if(FUNC_INTNO(sym->type) == INTNO_UNSPEC)
           sprintf(asymname, "ivec_%s", sym->name);
         else
           sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name);
-        asym = newSymbol(asymname, 0);
-
-        apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
-        pic16_addpBlock( apb );
-
-        pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
-        pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
-        pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+  
+        /* when an interrupt is declared as naked, do not emit the special
+         * wrapper segment at vector address. The user should take care for
+         * this instead. -- VR */
+
+        if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) != INTNO_UNSPEC)) {
+          asym = newSymbol(asymname, 0);
+          apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
+          pic16_addpBlock( apb );
+
+          pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
+          pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
+          //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+          //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_newpCodeOpLabel (sym->rname, 0)));
+         pic16_addpCode2pBlock(apb, pic16_newpCodeAsmDir ("GOTO", "%s", sym->rname)); /* this suppresses a warning in LinkFlow */
                
-        /* mark the end of this tiny function */
-        pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
+          /* mark the end of this tiny function */
+          pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
+        } else {
+          sprintf(asymname, "%s", sym->rname);
+        }
 
        {
          absSym *abSym;
@@ -3634,6 +3697,7 @@ static void genFunction (iCode *ic)
               case 2: abSym->address = 0x000018; break;
               
               default:
+//                fprintf(stderr, "no interrupt number is given\n");
                 abSym->address = -1; break;
             }
 
@@ -3653,7 +3717,6 @@ static void genFunction (iCode *ic)
     pic16_emitcode("","%s:",sym->rname);
     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
 
-
     {
       absSym *ab;
 
@@ -3665,7 +3728,6 @@ static void genFunction (iCode *ic)
         }
     }
 
-
     if(IFFUNC_ISNAKED(ftype)) {
       DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
       return;
@@ -3676,7 +3738,10 @@ static void genFunction (iCode *ic)
       //pic16_emitcode("clr","ea");
     }
 
+    currFunc = sym;            /* update the currFunc symbol */
     _G.fregsUsed = sym->regsUsed;
+    _G.sregsAlloc = newBitVect(128);
+    
 
     /* if this is an interrupt service routine then
      * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
@@ -3701,15 +3766,19 @@ static void genFunction (iCode *ic)
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
         
 //        pic16_pBlockConvert2ISR(pb);
-                
     }
 
     /* emit code to setup stack frame if user enabled,
      * and function is not main() */
-        
-    //fprintf(stderr, "function name: %s\n", sym->name);
+    
+//    debugf(stderr, "function name: %s ARGS=%p\n", sym->name, FUNC_ARGS(sym->type));
     if(strcmp(sym->name, "main")) {
-      if(1  /*!options.ommitFramePtr || sym->regsUsed*/) {
+      if(0 
+        || !options.ommitFramePtr 
+//        || sym->regsUsed
+        || IFFUNC_ARGS(sym->type)
+        || FUNC_HASSTACKPARM(sym->etype)
+        ) {
         /* setup the stack frame */
         if(STACK_MODEL_LARGE)
           pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_hi));
@@ -3798,6 +3867,17 @@ static void genEndFunction (iCode *ic)
     
     /* now we need to restore the registers */
     /* if any registers used */
+
+    /* first restore registers that might be used for stack access */
+    if(_G.sregsAllocSet) {
+    regs *sr;
+    
+      _G.sregsAllocSet = reverseSet( _G.sregsAllocSet );
+      for(sr=setFirstItem(_G.sregsAllocSet) ; sr; sr=setNextItem(_G.sregsAllocSet)) {
+        pic16_poppCodeOp( pic16_popRegFromIdx( sr->rIdx ) );
+      }
+    }
+
     if (sym->regsUsed) {
       int i;
 
@@ -3811,9 +3891,10 @@ static void genEndFunction (iCode *ic)
           }
         }
         pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
-
     }
 
+      
+
     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
           && sym->stack) {
       if (sym->stack == 1) {
@@ -3832,7 +3913,12 @@ static void genEndFunction (iCode *ic)
     }
 
     if(strcmp(sym->name, "main")) {
-      if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
+      if(0
+        || !options.ommitFramePtr
+//        || sym->regsUsed
+        || IFFUNC_ARGS(sym->type)
+        || FUNC_HASSTACKPARM(sym->etype)
+        ) {
         /* restore stack frame */
         if(STACK_MODEL_LARGE)
           pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_hi ));
@@ -3895,19 +3981,39 @@ static void genEndFunction (iCode *ic)
 }
 
 
-void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
+void pic16_storeForReturn(iCode *ic, /*operand *op,*/ int offset, pCodeOp *dest)
 {
-  if(is_LitOp(op)) {
-    unsigned long lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit);
-      if(lit == 0) {
+  unsigned long lit=1;
+  operand *op;
+
+    op = IC_LEFT(ic);
+  
+    // this fails for is_LitOp(op) (if op is an AOP_PCODE)
+    if(AOP_TYPE(op) == AOP_LIT) {
+      if(!IS_FLOAT(operandType( op ))) {
+        lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit);
+      } else {
+        union {
+          unsigned long lit_int;
+          float lit_float;
+        } info;
+       
+        /* take care if literal is a float */
+        info.lit_float = floatFromVal(AOP(op)->aopu.aop_lit);
+        lit = info.lit_int;
+      }
+    }
+
+    if(is_LitOp(op)) {
+      if(/*(OP_LIVETO(op) <= ic->seq) &&*/ (lit == 0)) {
         pic16_emitpcode(POC_CLRF, dest);
       } else {
         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
         if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
       }
-  } else {
-    if(dest->type == PO_WREG && (offset == 0)) {
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
+    } else {
+      if(dest->type == PO_WREG && (offset == 0)) {
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
       return;
     }
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
@@ -3935,27 +4041,16 @@ static void genRet (iCode *ic)
        size = AOP_SIZE(IC_LEFT(ic));
 
        if(size <= 4) {
-               if(size>3) {
-                       pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
-//                     pic16_emitpcode(POC_MOVFF,
-//                             pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
-               }
-               if(size>2) {
-                       pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
-//                     pic16_emitpcode(POC_MOVFF,
-//                             pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
-               }
-               if(size>1) {
-                       pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
-//                     pic16_emitpcode(POC_MOVFF,
-//                             pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
-               }
-
-//             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0));  // patch 12
+         if(size>3)
+           pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 3, pic16_popCopyReg(&pic16_pc_fsr0l));
+          
+          if(size>2)
+            pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 2, pic16_popCopyReg(&pic16_pc_prodh));
 
-               pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg));  // patch 12
-//             pic16_emitpcode(POC_MOVFF,
-//                     pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
+          if(size>1)
+            pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 1, pic16_popCopyReg(&pic16_pc_prodl));
+          
+          pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 0, pic16_popCopyReg(&pic16_pc_wreg));
 
        } else {
                /* >32-bits, setup stack and FSR0 */
@@ -4752,9 +4847,9 @@ static void genSkipc(resolvedIfx *rifx)
     return;
 
   if(rifx->condition)
-    emitSKPC;
-  else
     emitSKPNC;
+  else
+    emitSKPC;
 
   pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
   rifx->generated = 1;
@@ -4857,11 +4952,6 @@ static int genChkZeroes(operand *op, int lit,  int size)
 }
 #endif
 
-#if !defined(__BORLANDC__) && !defined(_MSC_VER)
-#define DEBUGpc(fmt,...)  DEBUGpic16_emitcode("; =:=", "%s:%s:%d: " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#endif
-#define isAOP_LIT(x)      (AOP_TYPE(x) == AOP_LIT)
-#define isAOP_REGlike(x)  (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE || AOP_TYPE(x) == AOP_STA)
 
 /*-----------------------------------------------------------------*/
 /* mov2w_regOrLit :- move to WREG either the offset's byte from    */
@@ -4880,7 +4970,7 @@ void mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) {
 /* genCmp :- greater or less than comparison                       */
 /*-----------------------------------------------------------------*/
 
-#if USE_SIMPLE_GENCMP
+#if USE_SIMPLE_GENCMP          /* { */
 
 /* genCmp performs a left < right comparison, stores
  * the outcome in result (if != NULL) and generates
@@ -4916,6 +5006,10 @@ static void genCmp (operand *left,operand *right,
   
   resolveIfx (&rIfx, ifx);
 
+  /* handle for special cases */
+  if(pic16_genCmp_special(left, right, result, ifx, &rIfx, sign))
+      return;
+
   /**********************************************************************
    * handle bits - bit compares are promoted to int compares seemingly! *
    **********************************************************************/
@@ -4942,9 +5036,7 @@ static void genCmp (operand *left,operand *right,
    * make sure that left is register (or the like) *
    *************************************************/
   if (!isAOP_REGlike(left)) {
-    #if !defined(__BORLANDC__) && !defined(_MSC_VER)
     DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right));
-    #endif
     assert (isAOP_LIT(left));
     assert (isAOP_REGlike(right));
     // swap left and right
@@ -4958,14 +5050,14 @@ static void genCmp (operand *left,operand *right,
     } // if
 
     // This fails for lit = 0xFF (unsigned) AND lit = 0x7F (signed),
-    // that's we handled it above.
+    // that's why we handled it above.
     lit++;
 
     dummy = left;
     left = right;
     right = dummy;
 
-    performedLt ^= 1; // instead of "left < right" we check for "right >= left+1"
+    performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
   } else if (isAOP_LIT(right)) {
     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
   } // if
@@ -4980,9 +5072,7 @@ static void genCmp (operand *left,operand *right,
   if (isAOP_LIT(right)) {
     if (!sign) {
       // unsigned comparison to a literal
-      #if !defined(__BORLANDC__) && !defined(_MSC_VER)
       DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1);
-      #endif
       if (lit == 0) {
        // unsigned left < 0? always false
        if (performedLt) emitCLRC; else emitSETC;
@@ -4990,9 +5080,7 @@ static void genCmp (operand *left,operand *right,
       }
     } else {
       // signed comparison to a literal
-      #if !defined(__BORLANDC__) && !defined(_MSC_VER)
       DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask);
-      #endif
       if ((lit & mask) == ((0x80 << (size*8)) & mask)) {
        // signed left < 0x80000000? always false
        if (performedLt) emitCLRC; else emitSETC;
@@ -5066,7 +5154,7 @@ result_in_carry:
    * now CARRY contains the result of the comparison: *
    * SUBWF sets CARRY iff                             *
    * F-W >= 0 <==> F >= W <==> !(F < W)               *
-   * (F=left, W=right)
+   * (F=left, W=right)                                *
    ****************************************************/
 
   if (performedLt) {
@@ -5092,16 +5180,14 @@ correct_result_in_carry:
   } // if (result)
 
   // perform conditional jump
-  // genSkipc branches to rifx->label if (rifx->condition != CARRY)
   if (ifx) {
     //DEBUGpc ("generate control flow");
-    rIfx.condition ^= 1;
     genSkipc (&rIfx);
     ifx->generated = 1;
   } // if
 }
 
-#elif 1
+#elif 1                /* } */
                /* { */
       /* original code */
 static void genCmp (operand *left,operand *right,
@@ -5734,7 +5820,7 @@ static void genCmp (operand *left,operand *right,
        
        pctemp = pic16_popGetTempReg(1);
        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-       pic16_emitpcode(POC_MOVWF, pctemp);             //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
+       pic16_emitpcode(POC_MOVWF, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
        pic16_emitpcode(POC_XORWF, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
        pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
@@ -5824,7 +5910,7 @@ check_carry:
 
 }
 
-#else  /* old version of genCmp() */   /* } else { */
+#elif 0        /* VR version of genCmp() */    /* } else { */
 
 /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
 static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
@@ -5934,10 +6020,6 @@ static void compareAop(resolvedIfx *resIfx, iCode *ifx, symbol *falselbl,
   }
 }
 
-
-  
-
-#if 1  /* { */
 static void genCmp (operand *left, operand *right,
                     operand *result, iCode *ifx, int sign)
 {
@@ -6076,7 +6158,6 @@ static void genCmp (operand *left, operand *right,
 //            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
 //            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
           }
-//        }
         
         if(ifx)ifx->generated = 1;
 
@@ -6089,7 +6170,6 @@ static void genCmp (operand *left, operand *right,
         }
       } else {
 
-
         /* unsigned compare */      
         DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
     
@@ -6100,10 +6180,8 @@ static void genCmp (operand *left, operand *right,
           compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
 
         }
-
         if(ifx)ifx->generated = 1;
 
-
         if(AOP_SIZE(result)) {
           pic16_emitpLabel(falselbl->key);
           pic16_outBitC( result );
@@ -6172,478 +6250,21 @@ static void genCmp (operand *left, operand *right,
         compareAopfirstpass=1;
         while(size--) {
           
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
-
-        }
-
-        if(ifx)ifx->generated = 1;
-        if(AOP_SIZE(result)) {
-
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitC( result );
-        }
-
-      }
-    }
-}
-
-#else    /* } else { */
-
-/* new version of genCmp -- VR 20041012 */
-static void genCmp (operand *left,operand *right,
-                    operand *result, iCode *ifx, int sign)
-{
-  int size; //, offset = 0 ;
-  unsigned long lit = 0L,i = 0;
-  resolvedIfx rFalseIfx;
-  int willCheckCarry=0;
-  //  resolvedIfx rTrueIfx;
-  symbol *truelbl;
-
-    FENTRY;
-  
-  /* General concept:
-   * subtract right from left if at the end the carry flag is set then we
-   * know that left is greater than right */
-            
-  resolveIfx(&rFalseIfx,ifx);
-  truelbl  = newiTempLabel(NULL);
-  size = max(AOP_SIZE(left),AOP_SIZE(right));
-
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
-  /* POC_CPFSGT        compare f, wreg, skip if f greater than wreg
-   * POC_CPFSLT compare f, wreg, skip if f less then wreg */
-  
-
-  /* if literal is on the right then swap with left */
-  if ((AOP_TYPE(right) == AOP_LIT)) {
-    operand *tmp = right ;
-    unsigned long mask = (0x100 << (8*(size-1))) - 1;
-
-      lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
-//      lit = (lit - 1) & mask;
-      right = left;
-      left = tmp;
-      rFalseIfx.condition ^= 1;                /* reverse compare */
-  } else
-  if ((AOP_TYPE(left) == AOP_LIT)) {
-    /* float compares are handled by support functions */
-    lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
-  }
-
-
-  //if(IC_TRUE(ifx) == NULL)
-  /* if left & right are bit variables */
-  if (AOP_TYPE(left) == AOP_CRY &&
-      AOP_TYPE(right) == AOP_CRY ) {
-
-    pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-    pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-
-  } else {
-    symbol *lbl  = newiTempLabel(NULL);
-
-    if(AOP_TYPE(left) == AOP_LIT) {
-      DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
-
-      if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-        willCheckCarry = 1;
-      else willCheckCarry = 0;
-
-      /* Special cases */
-      if((lit == 0) && (sign == 0)) {
-        /* unsigned compare to 0 */
-        DEBUGpic16_emitcode("; unsigned compare to 0","lit = 0x%x, sign=%d",lit,sign);
-        
-       size--;
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-       while(size) 
-         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
-
-       genSkipz2(&rFalseIfx,0);
-       if(ifx)ifx->generated = 1;
-       return;
-      }
-
-      if(size==1) {
-       /* Special cases */
-       lit &= 0xff;
-       if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
-         /* degenerate compare can never be true */
-         if(rFalseIfx.condition == 0)
-           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
-
-         if(ifx) ifx->generated = 1;
-         return;
-       }
-
-       if(sign) {
-         /* signed comparisons to a literal byte */
-          DEBUGpic16_emitcode(";signed compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
-         int lp1 = (lit+1) & 0xff;
-
-         DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d lp1 = %i",__LINE__,lit, rFalseIfx.condition, lp1);
-         switch (lp1) {
-         case 0:
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,0,7);
-           break;
-         case 0x7f:
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
-           genSkipz2(&rFalseIfx,1);
-           break;
-         default:
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
-           
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
-            else
-              pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
-
-           if(willCheckCarry) {
-              if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
-              else { emitSETC; emitCLRC; }
-              
-            } else {
-              pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
-            }              
-                     
-/*         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
-           rFalseIfx.condition ^= 1;
-           genSkipc(&rFalseIfx);
-*/
-           break;
-         }
-       } else {
-         /* unsigned comparisons to a literal byte */
-          DEBUGpic16_emitcode("; unsigned compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
-         switch(lit & 0xff ) {
-                         /* special cases */
-         case 0:
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           genSkipz2(&rFalseIfx,0);
-           break;
-         case 0x7f:
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,0,7);
-           break;
-         default:
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
-           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-           DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-           rFalseIfx.condition ^= 1;
-           if (AOP_TYPE(result) == AOP_CRY)
-             genSkipc(&rFalseIfx);
-           else {
-             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
-             pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
-           }         
-           break;
-         }
-       }
-
-       if(ifx) ifx->generated = 1;
-       if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-               goto check_carry;
-       return;
-
-      } else {
-
-       /* Size is greater than 1 */
-
-       if(sign) {
-         int lp1 = lit+1;
-
-         size--;
-
-         if(lp1 == 0) {
-           /* this means lit = 0xffffffff, or -1 */
-
-
-           DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,size,7);
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if(lit == 0) {
-           int s = size;
-
-           if(rFalseIfx.condition) {
-             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-           }
-
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-           while(size--)
-             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-
-           emitSKPZ;
-           if(rFalseIfx.condition) {
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-             pic16_emitpLabel(truelbl->key);
-           }else {
-             rFalseIfx.condition ^= 1;
-             genSkipCond(&rFalseIfx,right,s,7);
-           }
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if((size == 1) &&  (0 == (lp1&0xff))) {
-           /* lower byte of signed word is zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
-           i = ((lp1 >> 8) & 0xff) ^0x80;
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-           rFalseIfx.condition ^= 1;
-           genSkipc(&rFalseIfx);
-
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if(lit & (0x80 << (size*8))) {
-           /* Lit is less than zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
-           //rFalseIfx.condition ^= 1;
-           //genSkipCond(&rFalseIfx,left,size,7);
-           //rFalseIfx.condition ^= 1;
-           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-           //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-           else
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-
-         } else {
-           /* Lit is greater than or equal to zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
-           //rFalseIfx.condition ^= 1;
-           //genSkipCond(&rFalseIfx,right,size,7);
-           //rFalseIfx.condition ^= 1;
-
-           //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
-           //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-
-           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-           else
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-
-         }
-
-
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
-         while(size--) {
-
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
-           emitSKPNZ;
-           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-         }
-         rFalseIfx.condition ^= 1;
-         //rFalseIfx.condition = 1;
-         genSkipc(&rFalseIfx);
-
-         pic16_emitpLabel(truelbl->key);
-
-         if(ifx) ifx->generated = 1;
-         return;
-         // end of if (sign)
-       } else {
-
-         /* compare word or long to an unsigned literal on the right.*/
-
-
-         size--;
-         if(lit < 0xff) {
-           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
-           switch (lit) {
-           case 0:
-             break; /* handled above */
-/*
-           case 0xff:
-             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-             while(size--)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-             genSkipz2(&rFalseIfx,0);
-             break;
-*/
-           default:
-             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-             while(--size)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-             emitSKPZ;
-             if(rFalseIfx.condition)
-               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-             else
-               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-
-             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
-             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-
-             rFalseIfx.condition ^= 1;
-             genSkipc(&rFalseIfx);
-           }
-
-           pic16_emitpLabel(truelbl->key);
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-
-         lit++;
-         DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
-         i = (lit >> (size*8)) & 0xff;
-
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
-         while(size--) {
-           i = (lit >> (size*8)) & 0xff;
-
-           if(i) {
-             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-             emitSKPNZ;
-             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-           } else {
-             /* this byte of the lit is zero, 
-              * if it's not the last then OR in the variable */
-             if(size)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-           }
-         }
-
-
-         pic16_emitpLabel(lbl->key);
-
-         rFalseIfx.condition ^= 1;
-
-         genSkipc(&rFalseIfx);
-       }
-
-       if(sign)
-         pic16_emitpLabel(truelbl->key);
-       if(ifx) ifx->generated = 1;
-       return;
-      }
-    }
-    /* Compare two variables */
-
-    DEBUGpic16_emitcode(";sign","%d",sign);
-
-    size--;
-    if(sign) {
-      /* Sigh. thus sucks... */
-      if(size) {
-       pCodeOp *pctemp;
-       
-       pctemp = pic16_popGetTempReg(1);
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-       pic16_emitpcode(POC_MOVWF, pctemp);             //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-       pic16_emitpcode(POC_XORWF, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
-       pic16_emitpcode(POC_SUBFW, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_popReleaseTempReg(pctemp, 1);
-      } else {
-       /* Signed char comparison */
-       /* Special thanks to Nikolai Golovchenko for this snippet */
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
-       pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       genSkipc(&rFalseIfx);
-         
-       if(ifx) ifx->generated = 1;
-       return;
-      }
-
-    } else {
-
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-    }
-
-
-    /* The rest of the bytes of a multi-byte compare */
-    while (size) {
-
-      emitSKPZ;
-      pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
-      size--;
-
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-
-
-    }
-
-    pic16_emitpLabel(lbl->key);
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
-       (AOP_TYPE(result) == AOP_REG)) {
-      pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
-    } else {
-      genSkipc(&rFalseIfx);
-    }        
-    //genSkipc(&rFalseIfx);
-    if(ifx) ifx->generated = 1;
-
-    return;
-
-  }
-
-check_carry:
-  if ((AOP_TYPE(result) != AOP_CRY) 
-       && AOP_SIZE(result)) {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
-
-    pic16_outBitC(result);
-  } else {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if the result is used in the next
-       ifx conditional branch then generate
-       code a little differently */
-    if (ifx )
-      genIfxJump (ifx,"c");
-    else
-      pic16_outBitC(result);
-    /* leave the result in acc */
-  }
+          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
+          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
 
-}
-#endif /* } */
+        }
+
+        if(ifx)ifx->generated = 1;
+        if(AOP_SIZE(result)) {
 
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitC( result );
+        }
+
+      }
+    }
+}
 
 #endif /* } */
 
@@ -7057,6 +6678,7 @@ static void genCmpEq (iCode *ic, iCode *ifx)
   int preserve_result = 0;
   int generate_result = 0;
   int i=0;
+  unsigned long lit = -1;
 
   FENTRY;
   
@@ -7081,6 +6703,10 @@ static void genCmpEq (iCode *ic, iCode *ifx)
       left = tmp;
     }
 
+  if (AOP_TYPE(right) == AOP_LIT) {
+    lit = (unsigned long) floatFromVal (AOP(right)->aopu.aop_lit);
+  }
+
   if ( regsInCommon(left, result) || regsInCommon(right, result) )
     preserve_result = 1;
 
@@ -7102,9 +6728,11 @@ static void genCmpEq (iCode *ic, iCode *ifx)
           else
             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
         }
-      if(is_LitOp(right))
-        pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i)); 
-      else
+      if(is_LitOp(right)) {
+        if (is_LitOp(left) || (0 != ((lit >> (8*i))&0x00FF))) {
+          pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i)); 
+        }
+      } else
         pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i)); 
 
       pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
@@ -7571,7 +7199,7 @@ static void genAndOp (iCode *ic)
     only those used in arthmetic operations remain */
     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-    pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
+    pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
 
@@ -7620,7 +7248,7 @@ static void genOrOp (iCode *ic)
     only those used in arthmetic operations remain */
     pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
     pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-    pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
+    pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
 
@@ -7843,7 +7471,7 @@ static void genAnd (iCode *ic, iCode *ifx)
              bp -= 8;
              ofs++;
            }
-       
+
          pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
                    pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
 
@@ -8608,8 +8236,69 @@ static void genInline (iCode *ic)
 
        buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
        strcpy(buffer,IC_INLINE(ic));
+       
+       while((bp1=strstr(bp, "\\n"))) {
+         *bp1++ = '\n';
+         *bp1++ = ' ';
+         bp = bp1;
+        }
+        bp = bp1 = buffer;
 
-//     fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
+#if 0
+  /* This is an experimental code for #pragma inline
+     and is temporarily disabled for 2.5.0 release */
+        if(asmInlineMap)
+        {
+          symbol *sym;
+          char *s;
+          char *cbuf;
+          int cblen;
+
+            cbuf = Safe_strdup(buffer);
+            cblen = strlen(buffer)+1;
+            memset(cbuf, 0, cblen);
+
+            bp = buffer;
+            bp1 = cbuf;
+            while(*bp) {
+              if(*bp != '%')*bp1++ = *bp++;
+              else {
+                int i;
+
+                  bp++;
+                  i = *bp - '0';
+                  if(i>elementsInSet(asmInlineMap))break;
+                  
+                  bp++;
+                  s = indexSet(asmInlineMap, i);
+                  DEBUGpc("searching symbol s = `%s'", s);
+                  sym = findSym(SymbolTab, NULL, s);
+
+                  if(sym->reqv) {
+                    strcat(bp1, sym->reqv->operand.symOperand->regs[0]->name);
+                  } else {
+                    strcat(bp1, sym->rname);
+                  }
+                  
+                  while(*bp1)bp1++;
+              }
+              
+              if(strlen(bp1) > cblen - 16) {
+                int i = strlen(cbuf);
+                cblen += 50;
+                cbuf = realloc(cbuf, cblen);
+                memset(cbuf+i, 0, 50);
+                bp1 = cbuf + i;
+              }
+            }
+            
+            free(buffer);
+            buffer = Safe_strdup( cbuf );
+            free(cbuf);
+            
+            bp = bp1 = buffer;
+        }
+#endif  /* 0 */
 
        /* emit each line as a code */
        while (*bp) {
@@ -8657,7 +8346,7 @@ static void genRRC (iCode *ic)
   left = IC_LEFT(ic);
   result=IC_RESULT(ic);
   pic16_aopOp (left,ic,FALSE);
-  pic16_aopOp (result,ic,FALSE);
+  pic16_aopOp (result,ic,TRUE);
 
   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
 
@@ -8702,7 +8391,7 @@ static void genRLC (iCode *ic)
   left = IC_LEFT(ic);
   result=IC_RESULT(ic);
   pic16_aopOp (left,ic,FALSE);
-  pic16_aopOp (result,ic,FALSE);
+  pic16_aopOp (result,ic,TRUE);
 
   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
 
@@ -9008,7 +8697,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl,
     } else {
       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_SETF,  pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
       pic16_emitpcode(POC_BCF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
     }
@@ -9023,7 +8712,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl,
     } else {
       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_SETF,  pic16_popGet(AOP(result),offr));
     }
 
   default:
@@ -9737,7 +9426,7 @@ void pic16_genLeftShiftLiteral (operand *left,
     pic16_freeAsmop(right,NULL,ic,TRUE);
 
     pic16_aopOp(left,ic,FALSE);
-    pic16_aopOp(result,ic,FALSE);
+    pic16_aopOp(result,ic,TRUE);
 
     size = getSize(operandType(result));
 
@@ -9863,7 +9552,7 @@ static void genLeftShift (iCode *ic)
 #endif
       {
         /* we don't know if left is a literal or a register, take care -- VR */
-        mov2f(AOP(result), AOP(left), offset);
+        pic16_mov2f(AOP(result), AOP(left), offset);
       }
       offset++;
     }
@@ -9895,7 +9584,7 @@ static void genLeftShift (iCode *ic)
 #if 1
       /* this is already done, why change it? */
       if (!pic16_sameRegs(AOP(left),AOP(result))) {
-                mov2f(AOP(result), AOP(left), 0);
+                pic16_mov2f(AOP(result), AOP(left), 0);
       }
 #endif
 
@@ -10046,7 +9735,7 @@ static void genLeftShift (iCode *ic)
       } else {
 
         /* we don't know if left is a literal or a register, take care -- VR */
-        mov2f(AOP(result), AOP(left), offset);
+        pic16_mov2f(AOP(result), AOP(left), offset);
       }
       offset++;
     }
@@ -10075,7 +9764,7 @@ static void genLeftShift (iCode *ic)
 
       tlbl = newiTempLabel(NULL);
       if (!pic16_sameRegs(AOP(left),AOP(result))) {
-                mov2f(AOP(result), AOP(left), 0);
+                pic16_mov2f(AOP(result), AOP(left), 0);
                 
 //             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
 //             pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
@@ -10197,12 +9886,7 @@ static void genrshTwo (operand *result,operand *left,
     else
       movLeft2Result(left, MSB16, result, LSB);
 
-    pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
-
-    if(sign) {
-      pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
-    }
+    pic16_addSign (result, 1, sign);
   }
 
   /*  1 <= shCount <= 7 */
@@ -10345,7 +10029,7 @@ static void genRightShiftLiteral (operand *left,
   pic16_freeAsmop(right,NULL,ic,TRUE);
 
   pic16_aopOp(left,ic,FALSE);
-  pic16_aopOp(result,ic,FALSE);
+  pic16_aopOp(result,ic,TRUE);
 
   DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
 
@@ -10360,8 +10044,10 @@ static void genRightShiftLiteral (operand *left,
 
   /* I suppose that the left size >= result size */
   if(shCount == 0){
-    while(res_size--)
-      movLeft2Result(left, lsize, result, res_size);
+    assert (res_size <= lsize);
+    while (res_size--) {
+      pic16_mov2f (AOP(result), AOP(left), res_size);
+    } // for
   }
 
   else if(shCount >= (lsize * 8)){
@@ -10370,7 +10056,7 @@ static void genRightShiftLiteral (operand *left,
       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
       if(sign) {
        pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
+       pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),LSB));
       }
     } else {
 
@@ -10693,7 +10379,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) {
 
   pic16_aopOp(right,ic,FALSE);
   pic16_aopOp(left,ic,FALSE);
-  pic16_aopOp(result,ic,FALSE);
+  pic16_aopOp(result,ic,TRUE);
 
   sign = !SPEC_USIGN(operandType (left));
   signedCount = !SPEC_USIGN(operandType (right));
@@ -10739,7 +10425,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) {
   // (e.g. char c = 0x100 << -3 will become c = 0x00 >> 3 == 0x00 instad of 0x20)
   // This is fine, as it only occurs for left shifting with negative count which is not standardized!
   for (offset=0; offset < min(AOP_SIZE(left), AOP_SIZE(result)); offset++) {
-    mov2f (AOP(result),AOP(left), offset);
+    pic16_mov2f (AOP(result),AOP(left), offset);
   } // for
 
   // if result is longer than left, fill with zeros (or sign)
@@ -10831,9 +10517,66 @@ static void genRightShift (iCode *ic) {
 #endif
 
 
-void pic16_loadFSR0(operand *op)
+/* load FSR0 with address of/from op according to is_LitOp() or if lit is 1 */
+void pic16_loadFSR0(operand *op, int lit)
+{
+  if(OP_SYMBOL(op)->remat || is_LitOp( op )) {
+    pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+  } else {
+    assert (!OP_SYMBOL(op)->remat);
+    // set up FSR0 with address of result
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
+  }
+}
+
+/*----------------------------------------------------------------*/
+/* pic16_derefPtr - move one byte from the location ptr points to */
+/*                  to WREG (doWrite == 0) or one byte from WREG   */
+/*                  to the location ptr points to (doWrite != 0)   */
+/*----------------------------------------------------------------*/
+static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_setup)
 {
-       pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+  switch (p_type) {
+    case FPOINTER:
+    case POINTER:
+      if (!fsr0_setup || !*fsr0_setup)
+      {
+        pic16_loadFSR0( ptr, 0 );
+        if (fsr0_setup) *fsr0_setup = 1;
+      }
+      if (doWrite)
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+      else
+        pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
+      break;
+
+    case GPOINTER:
+      if (AOP(ptr)->aopu.aop_reg[2]) {
+        if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
+       // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?)
+       pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
+       pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),1), pic16_popCopyReg(&pic16_pc_prodl)));
+       pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(ptr),2));
+       pic16_callGenericPointerRW(doWrite, 1);
+      } else {
+       // data pointer (just 2 byte given)
+       if (!fsr0_setup || !*fsr0_setup)
+       {
+         pic16_loadFSR0( ptr, 0 );
+         if (fsr0_setup) *fsr0_setup = 1;
+       }
+       if (doWrite)
+         pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+       else
+         pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
+      }
+      break;
+
+    default:
+      assert (0 && "invalid pointer type specified");
+      break;
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -10842,11 +10585,9 @@ void pic16_loadFSR0(operand *op)
 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
 {    
   int shCnt ;
-  int rlen = 0 ;
   sym_link *etype, *letype;
   int blen=0, bstr=0;
   int lbstr;
-  int offset = 0 ;
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     etype = getSpec(operandType(result));
@@ -10866,11 +10607,13 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
 
       pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
       
-      if((ptype == POINTER) && (result)) {
+      // distinguish (p->bitfield) and p.bitfield, remat seems to work...
+      if(!IS_PTR(operandType(left))/* && OP_SYMBOL(left)->remat && (ptype == POINTER)*/) {
         /* workaround to reduce the extra lfsr instruction */
         pic16_emitpcode(POC_BTFSC,
               pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
       } else {
+       pic16_loadFSR0 (left, 0);
         pic16_emitpcode(POC_BTFSC,
               pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
       }
@@ -10886,23 +10629,13 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
         /* the following call to pic16_loadFSR0 is temporary until
          * optimization to handle single bit assignments is added
          * to the function. Until then use the old safe way! -- VR */
-        pic16_loadFSR0( left );
-       /* read the first byte  */
-       switch (ptype) {
-               case POINTER:
-               case IPOINTER:
-               case PPOINTER:
-               case FPOINTER:
-               case GPOINTER:
-                       pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-                       break;
-               case CPOINTER:
-                       pic16_emitcode("clr","a");
-                       pic16_emitcode("movc","a","@a+dptr");
-                       break;
-       }
-       
+
+    if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) {
+       // access symbol directly
+       pic16_mov2w (AOP(left), 0);
+    } else {
+      pic16_derefPtr (left, ptype, 0, NULL);
+    }
 
        /* if we have bitdisplacement then it fits   */
        /* into this byte completely or if length is */
@@ -10933,55 +10666,6 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
        fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
        exit(-1);
 
-    /* bit field did not fit in a byte  */
-    rlen = SPEC_BLEN(etype) - 8;
-    pic16_aopPut(AOP(result),"a",offset++);
-
-    while (1)  {
-
-       switch (ptype) {
-       case POINTER:
-       case IPOINTER:
-           pic16_emitcode("inc","%s",rname);
-           pic16_emitcode("mov","a,@%s",rname);
-           break;
-           
-       case PPOINTER:
-           pic16_emitcode("inc","%s",rname);
-           pic16_emitcode("movx","a,@%s",rname);
-           break;
-
-       case FPOINTER:
-           pic16_emitcode("inc","dptr");
-           pic16_emitcode("movx","a,@dptr");
-           break;
-           
-       case CPOINTER:
-           pic16_emitcode("clr","a");
-           pic16_emitcode("inc","dptr");
-           pic16_emitcode("movc","a","@a+dptr");
-           break;
-           
-       case GPOINTER:
-           pic16_emitcode("inc","dptr");
-           pic16_emitcode("lcall","__gptrget");
-           break;
-       }
-
-       rlen -= 8;            
-       /* if we are done */
-       if ( rlen <= 0 )
-           break ;
-       
-       pic16_aopPut(AOP(result),"a",offset++);
-                                     
-    }
-    
-    if (rlen) {
-       pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
-       pic16_aopPut(AOP(result),"a",offset);          
-    }
-    
     return ;
 }
 
@@ -10993,7 +10677,9 @@ static void genDataPointerGet(operand *left,
   int size, offset = 0, leoffset=0 ;
 
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       pic16_aopOp(result, ic, FALSE);
+       pic16_aopOp(result, ic, TRUE);
+
+       FENTRY;
 
        size = AOP_SIZE(result);
 //     fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
@@ -11045,8 +10731,8 @@ static void genDataPointerGet(operand *left,
        while (size--) {
                DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
                
-               if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
-                       || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
+//             pic16_DumpOp("(result)",result);
+               if(is_LitAOp(AOP(result))) {
                        pic16_mov2w(AOP(left), offset); // patch 8
                        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
                } else {
@@ -11072,15 +10758,17 @@ static void genNearPointerGet (operand *left,
                               operand *result, 
                               iCode *ic)
 {
-  asmop *aop = NULL;
+//  asmop *aop = NULL;
   //regs *preg = NULL ;
   sym_link *rtype, *retype;
-  sym_link *ltype = operandType(left);    
+  sym_link *ltype, *letype;
 
     FENTRY;
     
     rtype = operandType(result);
     retype= getSpec(rtype);
+    ltype = operandType(left);
+    letype= getSpec(ltype);
     
     pic16_aopOp(left,ic,FALSE);
 
@@ -11102,7 +10790,7 @@ static void genNearPointerGet (operand *left,
     }
     
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    pic16_aopOp (result,ic,FALSE);
+    pic16_aopOp (result,ic,TRUE);
     
     DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result);
 
@@ -11128,6 +10816,7 @@ static void genNearPointerGet (operand *left,
         if((nextic->op == IFX)
           && (result == IC_COND(nextic))
           && (OP_LIVETO(result) == nextic->seq)
+          && (OP_SYMBOL(left)->remat)  // below fails for "if (p->bitfield)"
           ) {
             /* everything is ok then */
             /* find a way to optimize the genIfx iCode */
@@ -11146,29 +10835,8 @@ static void genNearPointerGet (operand *left,
     }
 #endif
 
-
-    /* if the value is already in a pointer register
-     * then don't need anything more */
-    if (1 || !AOP_INPREG(AOP(left))) {  // AOP_INPREG(AOP(left)) is not always correct...
-      /* otherwise get a free pointer register */
-      DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               
-      /* VR -- the whole concept is to load FSR0 with the address of the symbol */
-      /* bitfields will be handled by genUnpackBits */
-      if(!IS_BITFIELD(retype)) {
-
-        if(is_LitAOp( AOP(left) )) {
-          pic16_loadFSR0( left );
-        } else {
-            // set up FSR0 with address from left
-            pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
-            pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
-        }
-      }
-    }
-
     /* if bitfield then unpack the bits */
-    if (IS_BITFIELD(retype)) 
+    if (IS_BITFIELD(letype)) 
       genUnpackBits (result, left, NULL, POINTER);
     else {
       /* we have can just get the values */
@@ -11177,11 +10845,8 @@ static void genNearPointerGet (operand *left,
        
       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-      /* fsr0 is loaded already -- VR */
-//      pic16_loadFSR0( left );
+      pic16_loadFSR0( left, 0 );
 
-//      pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
-//      pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
       while(size--) {
         if(size) {
           pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
@@ -11191,29 +10856,9 @@ static void genNearPointerGet (operand *left,
                 pic16_popGet(AOP(result), offset++)));
         }
       }
-#if 0
-//      pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
-//      pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
-      if(size)
-        pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
-#endif
-/*
-       while (size--) {
-           if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
-
-               pic16_emitcode("mov","a,@%s",rname);
-               pic16_aopPut(AOP(result),"a",offset);
-           } else {
-               sprintf(buffer,"@%s",rname);
-               pic16_aopPut(AOP(result),buffer,offset);
-           }
-           offset++ ;
-           if (size)
-               pic16_emitcode("inc","%s",rname);
-       }
-*/
     }
 
+#if 0
     /* now some housekeeping stuff */
     if (aop) {
       /* we had to allocate for this iCode */
@@ -11235,6 +10880,7 @@ static void genNearPointerGet (operand *left,
 //          pic16_emitcode("dec","%s",rname);
        }
     }
+#endif
 
     /* done */
     pic16_freeAsmop(left,NULL,ic,TRUE);
@@ -11274,7 +10920,7 @@ static void genPagedPointerGet (operand *left,
        rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
     
     pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_aopOp (result,ic,FALSE);
+    pic16_aopOp (result,ic,TRUE);
 
     /* if bitfield then unpack the bits */
     if (IS_BITFIELD(retype)) 
@@ -11352,7 +10998,7 @@ static void genFarPointerGet (operand *left,
     }
     /* so dptr know contains the address */
     pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_aopOp(result,ic,FALSE);
+    pic16_aopOp(result,ic,TRUE);
 
     /* if bit then unpack */
     if (IS_BITFIELD(retype)) 
@@ -11466,7 +11112,7 @@ static void genGenPointerGet (operand *left,
                // set up FSR0 with address from left
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
-
+                
                offset = 0 ;
 
                while(size--) {
@@ -11499,15 +11145,20 @@ static void genGenPointerGet (operand *left,
                               operand *result, iCode *ic)
 {
   int size, offset, lit;
-  sym_link *retype = getSpec(operandType(result));
-  char fgptrget[32];
+  sym_link *letype = getSpec(operandType(left));
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     pic16_aopOp(left,ic,FALSE);
-    pic16_aopOp(result,ic,FALSE);
+    pic16_aopOp(result,ic,TRUE);
     size = AOP_SIZE(result);
 
     DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
+  
+    /* if bit then unpack */
+    if (IS_BITFIELD(letype)) {
+      genUnpackBits(result,left,"BAD",GPOINTER);
+      goto release;
+    }
 
     if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
 
@@ -11536,37 +11187,13 @@ static void genGenPointerGet (operand *left,
       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl)));
       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2));
       
-      switch( size ) {
-        case 1: strcpy(fgptrget, "__gptrget1"); break;
-        case 2: strcpy(fgptrget, "__gptrget2"); break;
-        case 3: strcpy(fgptrget, "__gptrget3"); break;
-        case 4: strcpy(fgptrget, "__gptrget4"); break;
-        default:
-          werror(W_POSSBUG2, __FILE__, __LINE__);
-          abort();
-      }
-      
-      pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget ));
+      pic16_callGenericPointerRW(0, size);
       
       assignResultValue(result, 1);
       
-      {
-        symbol *sym;
-
-          sym = newSymbol( fgptrget, 0 );
-          strcpy(sym->rname, fgptrget);
-          checkAddSym(&externs, sym);
-
-//          fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
-      }
-              
       goto release;
     }
 
-  /* if bit then unpack */
-    if (IS_BITFIELD(retype)) 
-      genUnpackBits(result,left,"BAD",GPOINTER);
-
 release:
   pic16_freeAsmop(left,NULL,ic,TRUE);
   pic16_freeAsmop(result,NULL,ic,TRUE);
@@ -11727,7 +11354,6 @@ static void genPackBits (sym_link    *etype , operand *result,
   int rLen = 0 ;
   int blen, bstr ;   
   sym_link *retype;
-  char *l ;
 
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        blen = SPEC_BLEN(etype);
@@ -11744,7 +11370,7 @@ static void genPackBits (sym_link    *etype , operand *result,
 
                        lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
 //                     pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-                       if((p_type == POINTER) && (result)) {
+                       if(OP_SYMBOL(result)->remat && (p_type == POINTER) && (result)) {
                                /* workaround to reduce the extra lfsr instruction */
                                if(lit) {
                                        pic16_emitpcode(POC_BSF,
@@ -11754,7 +11380,7 @@ static void genPackBits (sym_link    *etype , operand *result,
                                                pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
                                }
                        } else {
-                                pic16_loadFSR0( result );
+                                pic16_loadFSR0(result, 0);
                                if(lit) {
                                        pic16_emitpcode(POC_BSF,
                                                pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
@@ -11766,7 +11392,7 @@ static void genPackBits (sym_link    *etype , operand *result,
        
                  return;
                }
-
+                /* move literal to W */
                pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
                offset++;
        } else
@@ -11797,80 +11423,80 @@ static void genPackBits (sym_link    *etype , operand *result,
             pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0));
             
             return;
-        } else
+        } else {
+          /* move right to W */
           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
+        }
 
-       /* if the bit lenth is less than or    */
+       /* if the bit length is less than or   */
        /* it exactly fits a byte then         */
        if((shCnt=SPEC_BSTR(etype))
                || SPEC_BLEN(etype) <= 8 )  {
-
-               pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
-
-               /* shift left acc */
-               AccLsh(shCnt);
-
-               /* using PRODL as a temporary register here */
-               pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
-
-               switch (p_type) {
-                       case FPOINTER:
-                       case POINTER:
-                               pic16_loadFSR0( result );
-                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-//                             pic16_emitcode ("mov","b,a");
-//                             pic16_emitcode("mov","a,@%s",rname);
-                               break;
-
-                       case GPOINTER:
-                                werror(W_POSSBUG2, __FILE__, __LINE__);
-                               break;
-
-               }
+               int fsr0_setup = 0;
+
+               if (blen != 8 || bstr != 0) {
+                 // we need to combine the value with the old value
+                 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
+
+         DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt,
+               SPEC_BSTR(etype), SPEC_BLEN(etype));
+               
+                 /* shift left acc */
+                 AccLsh(shCnt);
+
+                 /* using PRODH as a temporary register here */
+                 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
+
+                 if (IS_SYMOP(result) && !IS_PTR(operandType (result))/*OP_SYMBOL(result)->remat*/) {
+                   /* access symbol directly */
+                   pic16_mov2w (AOP(result), 0);
+                 } else {
+                   /* get old value */
+                   pic16_derefPtr (result, p_type, 0, &fsr0_setup);
+                 }
 #if 1
-               pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
+                 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
                        (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
                                        (unsigned char)(0xff >> (8-bstr))) ));
-               pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
-               pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+                 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh));
+               } // if (blen != 8 || bstr != 0)
+
+               /* write new value back */
+               if (IS_SYMOP(result) & !IS_PTR(operandType(result))) {
+                 pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0));
+               } else {
+                 pic16_derefPtr (result, p_type, 1, &fsr0_setup);
+              }
 #endif
 
          return;
        }
 
 
+#if 0
        fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
        fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
        exit(-1);
+#endif
 
 
-    /* if we r done */
-    if ( SPEC_BLEN(etype) <= 8 )
-        return ;
-
-    pic16_emitcode("inc","%s",rname);
-    rLen = SPEC_BLEN(etype) ;     
-
-
-
+    pic16_loadFSR0(result, 0);                 // load FSR0 with address of result
+    rLen = SPEC_BLEN(etype)-8;
+    
     /* now generate for lengths greater than one byte */
     while (1) {
-
-        l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
-
         rLen -= 8 ;
-        if (rLen <= 0 )
-            break ;
+        if (rLen <= 0 ) {
+          mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), offset);
+          break ;
+        }
 
         switch (p_type) {
             case POINTER:
-                if (*l == '@') {
-                    MOVA(l);
-                    pic16_emitcode("mov","@%s,a",rname);
-                } else
-                    pic16_emitcode("mov","@%s,%s",rname,l);
+                  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
                 break;
 
+/*
             case FPOINTER:
                 MOVA(l);
                 pic16_emitcode("movx","@dptr,a");
@@ -11880,21 +11506,25 @@ static void genPackBits (sym_link    *etype , operand *result,
                 MOVA(l);
                 DEBUGpic16_emitcode(";lcall","__gptrput");
                 break;  
+*/
+          default:
+            assert(0);
         }   
-        pic16_emitcode ("inc","%s",rname);
-    }
 
-    MOVA(l);
+
+        pic16_mov2w(AOP(right), offset++);
+    }
 
     /* last last was not complete */
     if (rLen)   {
         /* save the byte & read byte */
         switch (p_type) {
             case POINTER:
-                pic16_emitcode ("mov","b,a");
-                pic16_emitcode("mov","a,@%s",rname);
+//                pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
+                pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
                 break;
 
+/*
             case FPOINTER:
                 pic16_emitcode ("mov","b,a");
                 pic16_emitcode("movx","a,@dptr");
@@ -11906,29 +11536,40 @@ static void genPackBits (sym_link    *etype , operand *result,
                 pic16_emitcode ("lcall","__gptrget");
                 pic16_emitcode ("pop","b");
                 break;
+*/
+            default:
+              assert(0);
         }
-
-        pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
-        pic16_emitcode ("orl","a,b");
+        DEBUGpic16_emitcode(";", "rLen = %i", rLen);
+        pic16_emitpcode(POC_ANDLW, pic16_popGetLit((unsigned char)-1 << -rLen));
+        pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh));
+//        pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
+//        pic16_emitcode ("orl","a,b");
     }
 
-    if (p_type == GPOINTER)
-        pic16_emitcode("pop","b");
+//    if (p_type == GPOINTER)
+//        pic16_emitcode("pop","b");
 
     switch (p_type) {
 
-    case POINTER:
-       pic16_emitcode("mov","@%s,a",rname);
+      case POINTER:
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+//     pic16_emitcode("mov","@%s,a",rname);
        break;
-       
-    case FPOINTER:
+/*
+      case FPOINTER:
        pic16_emitcode("movx","@dptr,a");
        break;
        
-    case GPOINTER:
+      case GPOINTER:
        DEBUGpic16_emitcode(";lcall","__gptrput");
        break;                  
+*/
+      default:
+        assert(0);
     }
+    
+//    pic16_freeAsmop(right, NULL, ic, TRUE);
 }
 /*-----------------------------------------------------------------*/
 /* genDataPointerSet - remat pointer to data space                 */
@@ -12004,7 +11645,6 @@ static void genNearPointerSet (operand *right,
                                iCode *ic)
 {
   asmop *aop = NULL;
-  char *l;
   sym_link *retype;
   sym_link *ptype = operandType(result);
   sym_link *resetype;
@@ -12034,35 +11674,6 @@ static void genNearPointerSet (operand *right,
        pic16_aopOp(right,ic,FALSE);
        DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
-       /* if the value is already in a pointer register
-        * then don't need anything more */
-       if (1 || !AOP_INPREG(AOP(result))) {  // AOP_INPREG(AOP(result)) is not always correct...
-               /* otherwise get a free pointer register */
-               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-//             if( (AOP_TYPE(result) == AOP_PCODE) 
-//                     && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
-//                             || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
-                if(is_LitAOp( AOP(result) ))
-               {
-                 if(!IS_BITFIELD(resetype))
-                       pic16_loadFSR0( result );  // patch 10
-               } else {
-                 if(!IS_BITFIELD(resetype)) {
-                       // set up FSR0 with address of result
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
-                  }
-               }
-
-       }
-//     else
-//     rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-//     pic16_loadFSR0( result );
-
        /* if bitfield then unpack the bits */
        if (IS_BITFIELD(resetype)) {
                genPackBits (resetype, result, right, NULL, POINTER);
@@ -12071,15 +11682,10 @@ static void genNearPointerSet (operand *right,
          int size = AOP_SIZE(right);
          int offset = 0 ;    
 
+           pic16_loadFSR0(result, 0);
+           
                DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
                while (size--) {
-                       l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
-                       if (*l == '@' ) {
-                               //MOVA(l);
-                               //pic16_emitcode("mov","@%s,a",rname);
-                               pic16_emitcode("movf","indf0,w ;1");
-                       } else {
-
                                if (AOP_TYPE(right) == AOP_LIT) {
                                        pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
                                        if (size) {
@@ -12098,41 +11704,40 @@ static void genNearPointerSet (operand *right,
                                                                        pic16_popCopyReg(&pic16_pc_indf0)));
                                        }
                                }
-                       }
                        offset++;
                }
-       }
+        }
 
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* now some housekeeping stuff */
        if (aop) {
-               /* we had to allocate for this iCode */
-               pic16_freeAsmop(NULL,aop,ic,TRUE);
+         /* we had to allocate for this iCode */
+          pic16_freeAsmop(NULL,aop,ic,TRUE);
        } else { 
-               /* we did not allocate which means left
-                * already in a pointer register, then
-                * if size > 0 && this could be used again
-                * we have to point it back to where it 
-                * belongs */
-               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               if (AOP_SIZE(right) > 1
-                       && !OP_SYMBOL(result)->remat
-                       && ( OP_SYMBOL(result)->liveTo > ic->seq
-                               || ic->depth )) {
-
-                 int size = AOP_SIZE(right) - 1;
-
-                       while (size--)
-                               pic16_emitcode("decf","fsr0,f");
-                       //pic16_emitcode("dec","%s",rname);
-               }
-       }
+         /* we did not allocate which means left
+          * already in a pointer register, then
+          * if size > 0 && this could be used again
+          * we have to point it back to where it 
+          * belongs */
+         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+         if (AOP_SIZE(right) > 1
+           && !OP_SYMBOL(result)->remat
+           && ( OP_SYMBOL(result)->liveTo > ic->seq
+           || ic->depth )) {
+
+             int size = AOP_SIZE(right) - 1;
+
+               while (size--)
+                 pic16_emitcode("decf","fsr0,f");
+                 //pic16_emitcode("dec","%s",rname);
+            }
+        }
 
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       /* done */
+    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    /* done */
 //release:
-       pic16_freeAsmop(right,NULL,ic,TRUE);
-       pic16_freeAsmop(result,NULL,ic,TRUE);
+    pic16_freeAsmop(right,NULL,ic,TRUE);
+    pic16_freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -12397,8 +12002,7 @@ static void genGenPointerSet (operand *right,
                               operand *result, iCode *ic)
 {
   int size;
-  sym_link *retype = getSpec(operandType(right));
-  char fgptrput[32];
+  sym_link *retype = getSpec(operandType(result));
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -12421,7 +12025,6 @@ static void genGenPointerSet (operand *right,
     DEBUGpic16_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
 
 
-
     /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
 
     /* value of right+0 is placed on stack, which will be retrieved
@@ -12441,27 +12044,7 @@ static void genGenPointerSet (operand *right,
                                 pic16_popCopyReg(&pic16_pc_prodl)));
     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
     
-
-    /* put code here */
-    switch (size) {
-      case 1: strcpy(fgptrput, "__gptrput1"); break;
-      case 2: strcpy(fgptrput, "__gptrput2"); break;
-      case 3: strcpy(fgptrput, "__gptrput3"); break;
-      case 4: strcpy(fgptrput, "__gptrput4"); break;
-      default:
-        werror(W_POSSBUG2, __FILE__, __LINE__);
-        abort();
-    }
-    
-    pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput ));
-    
-    {
-      symbol *sym;
-                  
-        sym = newSymbol( fgptrput, 0 );
-        strcpy(sym->rname, fgptrput);
-        checkAddSym(&externs, sym);
-    }
+    pic16_callGenericPointerRW(1, size);
 
 release:
     pic16_freeAsmop(right,NULL,ic,TRUE);
@@ -12486,6 +12069,7 @@ static void genPointerSet (iCode *ic)
     move it to the correct pointer register */
     type = operandType(result);
     etype = getSpec(type);
+    
     /* if left is of type of pointer then it is simple */
     if (IS_PTR(type) && !IS_FUNC(type->next)) {
         p_type = DCL_TYPE(type);
@@ -12594,8 +12178,8 @@ static void genAddrOf (iCode *ic)
       /* get address of symbol on stack */
       DEBUGpic16_emitcode(";    ", "%s symbol %s on stack", __FUNCTION__, sym->name);
 #if 0
-      fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__,
-                  OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack);
+      fprintf(stderr, "%s:%d symbol %s on stack offset %i\n", __FILE__, __LINE__,
+                  OP_SYMBOL(IC_LEFT(ic))->name, OP_SYMBOL(IC_LEFT(ic))->stack);
 #endif
 
       // operands on stack are accessible via "FSR2 + index" with index
@@ -12788,16 +12372,21 @@ static void genAssign (iCode *ic)
   if (AOP_TYPE(right) == AOP_REG) {
     DEBUGpic16_emitcode(";   ", "%s:%d assign from register\n", __FUNCTION__, __LINE__);
     while (size--) {
-      
       pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++));
     } // while
     goto release;
   }
 
+  /* when do we have to read the program memory?
+   * - if right itself is a symbol in code space
+   *   (we don't care what it points to if it's a pointer)
+   * - AND right is not a function (we would want its address)
+   */
   if(AOP_TYPE(right) != AOP_LIT
-       && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
+       && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right)))
        && !IS_FUNC(OP_SYM_TYPE(right))
-       ) {
+       && !IS_ITEMP(right))
+  {
        DEBUGpic16_emitcode(";   ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
        fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
 
@@ -12820,7 +12409,8 @@ static void genAssign (iCode *ic)
                                pic16_popCopyReg(&pic16_pc_tblptru)));
        }
 
-       size = min(AOP_SIZE(right), AOP_SIZE(result));
+       /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */
+       size = min(getSize(OP_SYM_TYPE(right)), AOP_SIZE(result));
        while(size--) {
                pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
@@ -12828,8 +12418,11 @@ static void genAssign (iCode *ic)
                offset++;
        }
 
-       if(AOP_SIZE(result) > AOP_SIZE(right)) {
-               size = AOP_SIZE(result) - AOP_SIZE(right);
+       /* FIXME: for pointers we need to extend differently (according
+        * to pointer type DATA/CODE/EEPROM/... :*/
+       size = getSize(OP_SYM_TYPE(right));
+       if(AOP_SIZE(result) > size) {
+               size = AOP_SIZE(result) - size;
                while(size--) {
                        pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
                        offset++;
@@ -12970,9 +12563,10 @@ static void genJumpTab (iCode *ic)
     pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pcl));
 
     pic16_emitpLabelFORCE(jtab->key);
-
 #endif
+
     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
+//          pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
 
     pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_BEGIN, ""));
     /* now generate the jump labels */
@@ -13136,8 +12730,8 @@ static void genCast (iCode *ic)
 //     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
 //             return ;
 
-       pic16_aopOp(right,ic,FALSE) ;
        pic16_aopOp(result,ic,FALSE);
+       pic16_aopOp(right,ic,FALSE) ;
 
        DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
@@ -13324,7 +12918,7 @@ static void genCast (iCode *ic)
            while (size--) {
              if(offset < AOP_SIZE(right)) {
                 DEBUGpic16_emitcode("; ***","%s  %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
-                mov2f(AOP(result), AOP(right), offset);
+                pic16_mov2f(AOP(result), AOP(right), offset);
 /*
                if ((AOP_TYPE(right) == AOP_PCODE) && 
                    AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
@@ -13383,6 +12977,8 @@ static void genCast (iCode *ic)
            goto release ;
        }
        
+       
+       assert( 0 );
        /* just copy the pointers */
        size = AOP_SIZE(result);
        offset = 0 ;
@@ -13410,8 +13006,10 @@ static void genCast (iCode *ic)
     /* we move to result for the size of source */
     size = AOP_SIZE(right);
     offset = 0 ;
+
     while (size--) {
-      mov2f(AOP(result), AOP(right), offset);
+      if(!_G.resDirect)
+        pic16_mov2f(AOP(result), AOP(right), offset);
       offset++;
     }
 
@@ -13428,7 +13026,7 @@ static void genCast (iCode *ic)
        /* Save one instruction of casting char to int */
        pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset));
        pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-       pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(result),offset));
+       pic16_emitpcode(POC_SETF,   pic16_popGet(AOP(result),offset));
       } else {
         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
 
@@ -13566,10 +13164,26 @@ static void genReceive (iCode *ic)
 static void
 genDummyRead (iCode * ic)
 {
-  pic16_emitcode ("; genDummyRead","");
-  pic16_emitcode ("; not implemented","");
+  operand *op;
+  int i;
 
-  ic = ic;
+  op = IC_RIGHT(ic);
+  if (op && IS_SYMOP(op)) {
+    if (IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
+      fprintf (stderr, "%s: volatile symbols in codespace?!? -- might go wrong...\n", __FUNCTION__);
+      return;
+    }
+    pic16_aopOp (op, ic, FALSE);
+    for (i=0; i < AOP_SIZE(op); i++) {
+      // may need to protect this from the peepholer -- this is not nice but works...
+      pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir(";", "VOLATILE READ - BEGIN"));
+      pic16_mov2w (AOP(op),i);
+      pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir(";", "VOLATILE READ - END"));
+    } // for i
+    pic16_freeAsmop (op, NULL, ic, TRUE);
+  } else if (op) {
+    fprintf (stderr, "%s: not implemented for non-symbols (volatile operand might not be read)\n", __FUNCTION__);
+  } // if
 }
 
 /*-----------------------------------------------------------------*/