* src/pic16/gen.c (pic16_derefPtr): NEW, single place
[fw/sdcc] / src / pic16 / gen.c
index fee949adc1061d4711364416fb0a9a83e080c8d4..b3fd810568a562041fd30adaa7cf35fb97a3d7e4 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,19 +678,25 @@ 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);
@@ -722,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]));
+            }
          }
        }
        
@@ -1233,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;
@@ -1263,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);
 
@@ -1376,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;
           }
@@ -1550,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];
@@ -1656,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__);
 
@@ -1675,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;
@@ -1703,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) );
   }
 }
@@ -1728,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);
 
@@ -2317,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));
@@ -2341,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 ));
   
@@ -2349,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);
   }
 
@@ -2380,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();
 }
@@ -2395,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)
@@ -2724,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++;
     }
     
@@ -3311,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();
               }
             }
 
@@ -3588,43 +3659,31 @@ static void genFunction (iCode *ic)
 
 //        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;
@@ -3638,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;
             }
 
@@ -3657,7 +3717,6 @@ static void genFunction (iCode *ic)
     pic16_emitcode("","%s:",sym->rname);
     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
 
-
     {
       absSym *ab;
 
@@ -3669,7 +3728,6 @@ static void genFunction (iCode *ic)
         }
     }
 
-
     if(IFFUNC_ISNAKED(ftype)) {
       DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
       return;
@@ -3680,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 */
@@ -3705,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(0 || !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));
@@ -3802,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;
 
@@ -3815,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) {
@@ -3836,7 +3913,12 @@ static void genEndFunction (iCode *ic)
     }
 
     if(strcmp(sym->name, "main")) {
-      if(0 || !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 ));
@@ -3899,36 +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)
 {
   unsigned long lit=1;
-  // 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;
+  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;
+        /* 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(lit == 0) {
+    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));
@@ -3956,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 */
@@ -4773,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;
@@ -4878,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    */
@@ -4901,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
@@ -4937,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! *
    **********************************************************************/
@@ -4963,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
@@ -4979,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
@@ -5001,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;
@@ -5011,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;
@@ -5087,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) {
@@ -5113,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,
@@ -5755,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));
@@ -5845,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,
@@ -5955,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)
 {
@@ -6097,84 +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;
-
-        if(AOP_SIZE(result)) {
-          pic16_emitpLabel(tlbl->key);
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitOp( result, pct2 );
-        } else {
-          pic16_emitpLabel(tlbl->key);
-        }
-      } else {
-
-
-        /* unsigned compare */      
-        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-    
-        compareAopfirstpass=1;
-        while(size--) {
-          
-          pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, 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 {
-      /* compare registers */
-      DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__);
-
-
-      if(sign) {
-        pCodeOp *pct, *pct2;
-        
-        /* signed compare */
-        DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
-
-        pct = pic16_popCopyReg(&pic16_pc_prodl);       /* first temporary register */
-        pct2 = pic16_popCopyReg(&pic16_pc_prodh);      /* second temporary register */
-        tlbl = newiTempLabel( NULL );
-        
-        compareAopfirstpass=1;
-
-        size--;
-        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-        pic16_emitpcode(POC_MOVWF, pct);
-
-        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
-        /* WREG already holds left + 0x80 */
-        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-        
-        while( size-- ) {
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-          pic16_emitpcode(POC_MOVWF, pct);
-                
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
-          /* WREG already holds left + 0x80 */
-          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;
 
@@ -6182,489 +6165,106 @@ static void genCmp (operand *left, operand *right,
           pic16_emitpLabel(tlbl->key);
           pic16_emitpLabel(falselbl->key);
           pic16_outBitOp( result, pct2 );
-        } else {
-          pic16_emitpLabel(tlbl->key);
-        }
-
-      } else {
-        /* unsigned compare */      
-        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-
-        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));
+        } else {
+          pic16_emitpLabel(tlbl->key);
+        }
+      } else {
 
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       genSkipc(&rFalseIfx);
-         
-       if(ifx) ifx->generated = 1;
-       return;
-      }
+        /* unsigned compare */      
+        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
+    
+        compareAopfirstpass=1;
+        while(size--) {
+          
+          pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
+          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
 
-    } else {
+        }
+        if(ifx)ifx->generated = 1;
 
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-    }
+        if(AOP_SIZE(result)) {
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitC( result );
+        }
 
+      }
+    } else {
+      /* compare registers */
+      DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__);
 
-    /* The rest of the bytes of a multi-byte compare */
-    while (size) {
 
-      emitSKPZ;
-      pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
-      size--;
+      if(sign) {
+        pCodeOp *pct, *pct2;
+        
+        /* signed compare */
+        DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
 
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+        pct = pic16_popCopyReg(&pic16_pc_prodl);       /* first temporary register */
+        pct2 = pic16_popCopyReg(&pic16_pc_prodh);      /* second temporary register */
+        tlbl = newiTempLabel( NULL );
+        
+        compareAopfirstpass=1;
 
+        size--;
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
+//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
+        pic16_emitpcode(POC_MOVWF, pct);
 
-    }
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
+//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
 
-    pic16_emitpLabel(lbl->key);
+        /* WREG already holds left + 0x80 */
+        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
+        
+        while( size-- ) {
+          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
+//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
+          pic16_emitpcode(POC_MOVWF, pct);
+                
+          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
+//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
 
-    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;
+          /* WREG already holds left + 0x80 */
+          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;
 
-    return;
+        if(AOP_SIZE(result)) {
+          pic16_emitpLabel(tlbl->key);
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitOp( result, pct2 );
+        } else {
+          pic16_emitpLabel(tlbl->key);
+        }
 
-  }
+      } else {
+        /* unsigned compare */      
+        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
 
-check_carry:
-  if ((AOP_TYPE(result) != AOP_CRY) 
-       && AOP_SIZE(result)) {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        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)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 */
-  }
+        if(ifx)ifx->generated = 1;
+        if(AOP_SIZE(result)) {
 
-}
-#endif /* } */
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitC( result );
+        }
 
+      }
+    }
+}
 
 #endif /* } */
 
@@ -8636,14 +8236,70 @@ 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;
-        
+
+#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) {
                if (*bp == '\n') {
@@ -9041,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));
     }
@@ -9056,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:
@@ -9896,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++;
     }
@@ -9928,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
 
@@ -10079,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++;
     }
@@ -10108,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));
@@ -10234,7 +9890,7 @@ static void genrshTwo (operand *result,operand *left,
 
     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_emitpcode(POC_SETF, pic16_popGet(AOP(result),MSB16));
     }
   }
 
@@ -10395,7 +10051,7 @@ static void genRightShiftLiteral (operand *left,
   if(shCount == 0){
     assert (res_size <= lsize);
     while (res_size--) {
-      mov2f (AOP(result), AOP(left), res_size);
+      pic16_mov2f (AOP(result), AOP(left), res_size);
     } // for
   }
 
@@ -10405,7 +10061,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 {
 
@@ -10774,7 +10430,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)
@@ -10869,26 +10525,74 @@ static void genRightShift (iCode *ic) {
 /* load FSR0 with address of/from op according to is_LitOp() or if lit is 1 */
 void pic16_loadFSR0(operand *op, int lit)
 {
-  if(is_LitOp( op ) || 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)
+{
+  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;
+  }
+}
+
 /*-----------------------------------------------------------------*/
 /* genUnpackBits - generates code for unpacking bits               */
 /*-----------------------------------------------------------------*/
 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));
@@ -10908,11 +10612,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));
       }
@@ -10928,23 +10634,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, 1 );
-       /* 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 */
@@ -10975,55 +10671,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 ;
 }
 
@@ -11037,6 +10684,8 @@ static void genDataPointerGet(operand *left,
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        pic16_aopOp(result, ic, TRUE);
 
+       FENTRY;
+
        size = AOP_SIZE(result);
 //     fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
 
@@ -11087,8 +10736,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 {
@@ -11117,12 +10766,14 @@ static void genNearPointerGet (operand *left,
 //  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);
 
@@ -11170,6 +10821,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 */
@@ -11188,18 +10840,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__);
-               
-      ;
-    }
-
     /* 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 */
@@ -11508,8 +11150,7 @@ 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);
@@ -11517,6 +11158,12 @@ static void genGenPointerGet (operand *left,
     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!)
 
@@ -11545,38 +11192,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 );
-          sym->used++;
-          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);
@@ -11753,7 +11375,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,
@@ -11763,7 +11385,7 @@ static void genPackBits (sym_link    *etype , operand *result,
                                                pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
                                }
                        } else {
-                                pic16_loadFSR0(result, 1);
+                                pic16_loadFSR0(result, 0);
                                if(lit) {
                                        pic16_emitpcode(POC_BSF,
                                                pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
@@ -11830,45 +11452,12 @@ static void genPackBits (sym_link    *etype , operand *result,
                  /* using PRODH as a temporary register here */
                  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
 
-                 /* get old value */
-                 switch (p_type) {
-                       case FPOINTER:
-                       case POINTER:
-                               pic16_loadFSR0( result, 1 );
-                               fsr0_setup = 1;
-                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-//                             pic16_emitcode ("mov","b,a");
-//                             pic16_emitcode("mov","a,@%s",rname);
-                               break;
-
-                       case GPOINTER:
-                               if (AOP(result)->aopu.aop_reg[2]) {
-                                 // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?)
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl)));
-                                 pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2));
-                                 pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrget1"));
-                                 {
-                                   symbol *sym;
-                                   sym = newSymbol( "__gptrget1", 0 );
-                                   strcpy(sym->rname, "__gptrget1");
-                                   checkAddSym(&externs, sym);
-                                 }
-                               } else {
-                                 // data pointer (just 2 byte given)
-                                 pic16_loadFSR0( result, 1 );
-                                 fsr0_setup = 1;
-                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-                               }
-                               
-                               // warnings will be emitted below
-                               //pic16_emitpcomment ("; =?= genPackBits, GPOINTER...");
-                                //werror(W_POSSBUG2, __FILE__, __LINE__);
-                               break;
-
-                       default:
-                               assert (0 && "invalid pointer type specified");
-                               break;
+                 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(
@@ -11878,42 +11467,11 @@ static void genPackBits (sym_link    *etype , operand *result,
                } // if (blen != 8 || bstr != 0)
 
                /* write new value back */
-               switch (p_type) {
-                       case FPOINTER:
-                       case POINTER:
-                               if (!fsr0_setup) pic16_loadFSR0( result, 1 );
-                               pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
-                               break;
-
-                       case GPOINTER:
-                               if (AOP(result)->aopu.aop_reg[2]) {
-                                 // prepare call to __gptrset1, this is actually genGenPointerSet(WREG, result, ?ic?)
-                                 pic16_emitpcode (POC_MOVWF, pic16_popCopyReg (pic16_stack_postdec/*pic16_pc_postdec1*/));
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl)));
-                                 pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2));
-                                 pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrput1"));
-                                 {
-                                   symbol *sym;
-                                   sym = newSymbol( "__gptrput1", 0 );
-                                   strcpy(sym->rname, "__gptrput1");
-                                   checkAddSym(&externs, sym);
-                                 }
-                               } else {
-                                 // data pointer (just 2 byte given)
-                                 if (!fsr0_setup) pic16_loadFSR0( result, 1 );
-                                 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
-                               }
-                               
-                               // this should work in all cases (as soon as gptrget/gptrput work on EEPROM and PROGRAM MEMORY)
-                               //pic16_emitpcomment ("; =?= genPackBits, GPOINTER access");
-                                werror(W_POSSBUG2, __FILE__, __LINE__);
-                               break;
-
-                       default:
-                               assert (0 && "invalid pointer type specified");
-                               break;
-               }
+               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;
@@ -11927,7 +11485,7 @@ static void genPackBits (sym_link    *etype , operand *result,
 #endif
 
 
-    pic16_loadFSR0(result, 1);                 // load FSR0 with address of result
+    pic16_loadFSR0(result, 0);                 // load FSR0 with address of result
     rLen = SPEC_BLEN(etype)-8;
     
     /* now generate for lengths greater than one byte */
@@ -12121,17 +11679,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__);
-
-         ;
-        }
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
        /* if bitfield then unpack the bits */
        if (IS_BITFIELD(resetype)) {
                genPackBits (resetype, result, right, NULL, POINTER);
@@ -12460,8 +12007,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__);
 
@@ -12484,7 +12030,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
@@ -12504,28 +12049,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 );
-        sym->used++;
-        strcpy(sym->rname, fgptrput);
-        checkAddSym(&externs, sym);
-    }
+    pic16_callGenericPointerRW(1, size);
 
 release:
     pic16_freeAsmop(right,NULL,ic,TRUE);
@@ -12550,6 +12074,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);
@@ -12658,8 +12183,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
@@ -12852,16 +12377,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);
 
@@ -12884,7 +12414,8 @@ static void genAssign (iCode *ic)
                                pic16_popCopyReg(&pic16_pc_tblptru)));
        }
 
-       size = min(getSize(OP_SYM_ETYPE(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),
@@ -12892,7 +12423,9 @@ static void genAssign (iCode *ic)
                offset++;
        }
 
-       size = getSize(OP_SYM_ETYPE(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--) {
@@ -13035,9 +12568,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 */
@@ -13201,8 +12735,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);
 
@@ -13389,7 +12923,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) {
@@ -13448,6 +12982,8 @@ static void genCast (iCode *ic)
            goto release ;
        }
        
+       
+       assert( 0 );
        /* just copy the pointers */
        size = AOP_SIZE(result);
        offset = 0 ;
@@ -13475,8 +13011,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++;
     }
 
@@ -13493,7 +13031,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));