* src/pic16/gen.c (pic16_derefPtr): NEW, single place
[fw/sdcc] / src / pic16 / gen.c
index c0ba6354cb0ad9b23d73e305e4b64e1137def97d..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)
@@ -6,7 +6,8 @@
   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
   PIC16 port -  Martin Dubuc m.dubuc@rogers.com (2002)
-             -  Vangelis Rokas vrokas@otenet.gr (2003,2004)
+             -  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;
 
@@ -153,24 +154,15 @@ static struct {
     short ipushRegs;
     set *sendSet;
     set *stackRegSet;
-    int interruptvector;
     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;
@@ -311,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)
@@ -648,11 +642,29 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     }
 #endif
 
+
+#if 0
+    if(sym->iaccess) {
+      if(space->paged) {
+        fprintf(stderr, "%s:%d symbol %s points to paged data\n", __FILE__, __LINE__, sym->name);
+
+        sym->aop = aop = newAsmop (AOP_PAGED);
+        aop->aopu.aop_dir = sym->rname ;
+        aop->size = getSize(sym->type);
+       DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+       pic16_allocDirReg( IC_LEFT(ic) );
+        return aop;
+      }
+      assert( 0 );
+    }
+#endif
+    
 #if 1
     /* assign depending on the storage class */
     /* if it is on the stack or indirectly addressable */
     /* space we need to assign either r0 or r1 to it   */    
-    if (sym->onStack || sym->iaccess) {
+    if (sym->onStack)  // || sym->iaccess)
+    {
       pCodeOp *pcop[4];
       int i;
       
@@ -666,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) );
        }
@@ -702,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_pc_plusw2), 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]));
+            }
          }
        }
        
@@ -780,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);
@@ -852,11 +881,15 @@ 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 {
+          if(SPEC_SCLS(sym->etype) == S_PDATA) {
+            fprintf(stderr, "%s: %d symbol in PDATA space\n", __FILE__, __LINE__);
+            aop->size = FPTRSIZE;
+          } else
                assert( 0 );
        }
 
@@ -1069,10 +1102,12 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
         aop2->type != AOP_REG )
         return FALSE ;
 
+    /* This is a bit too restrictive if one is a subset of the other...
     if (aop1->size != aop2->size )
         return FALSE ;
+    */
 
-    for (i = 0 ; i < aop1->size ; i++ ) {
+    for (i = 0 ; i < min(aop1->size, aop2->size) ; i++ ) {
 //        if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE;
 
 //        if(aop1->aopu.aop_reg[i]->type == AOP_REG)
@@ -1170,6 +1205,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
     b) has a spill location */
     if (sym->isspilt || sym->nRegs == 0) {
 
+//      debugf3("symbol %s\tisspilt: %d\tnRegs: %d\n", sym->rname, sym->isspilt, sym->nRegs);
       DEBUGpic16_emitcode(";","%d",__LINE__);
         /* rematerialize it NOW */
         if (sym->remat) {
@@ -1196,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);
@@ -1206,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;
@@ -1230,9 +1266,16 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
 
        sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
        //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
-       aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname, 
-                                         getSize(sym->type), 
-                                         sym->usl.spillLoc->offset, op);
+       if (sym->usl.spillLoc && sym->usl.spillLoc->rname) {
+         aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname, 
+                                                 getSize(sym->type), 
+                                                 sym->usl.spillLoc->offset, op);
+       } else {
+         fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK!\n", __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);
+       }
         aop->size = getSize(sym->type);
 
         return;
@@ -1335,15 +1378,20 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
                  /* initialise for stack access via frame pointer */
                  pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
                  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                        aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2)));
+                        aop->aopu.stk.pop[i], pic16_popCopyReg(pic16_frame_plusw)));
                }
        
                 if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
               }
 
               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;
           }
@@ -1516,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];
@@ -1543,6 +1596,21 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
       strcpy(rs,s);   
       return rs;
 
+#if 0
+    case AOP_PAGED:
+      DEBUGpic16_emitcode(";","oops AOP_PAGED did this %s\n",s);
+      if (offset) {
+       sprintf(s,"(%s + %d)",
+               aop->aopu.aop_dir,
+               offset);
+      } else
+           sprintf(s,"%s",aop->aopu.aop_dir);
+      DEBUGpic16_emitcode(";","oops AOP_PAGED did this %s\n",s);
+      rs = Safe_calloc(1,strlen(s)+1);
+      strcpy(rs,s);   
+      return rs;
+#endif
+
     case AOP_STA:
         rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name);
         return (rs);
@@ -1607,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__);
 
@@ -1626,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;
@@ -1654,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) );
   }
 }
@@ -1679,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);
 
@@ -1941,6 +2058,12 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
       DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
       return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
        
+#if 0
+    case AOP_PAGED:
+      DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
+      return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
+#endif
+
     case AOP_REG:
       {
        int rIdx;
@@ -1959,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;
@@ -1998,16 +2121,16 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                          __LINE__, 
                          ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
       pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
-#if 1
-       switch( aop->aopu.pcop->type ) {
-               case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
-               case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
-               default:
-                       assert( 0 );    /* should never reach here */;
-       }
-#else
-      PCOI(pcop)->offset = offset;
-#endif
+      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;
+        default:
+         fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type);
+          assert( 0 ); /* should never reach here */;
+      }
       return pcop;
     }
 
@@ -2262,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));
@@ -2286,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 ));
   
@@ -2294,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);
   }
 
@@ -2304,7 +2428,7 @@ void pic16_testStackOverflow(void)
 void pic16_pushpCodeOp(pCodeOp *pcop)
 {
 //     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
+  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec )));   //&pic16_pc_postdec1)));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
     
@@ -2313,7 +2437,7 @@ void pic16_pushpCodeOp(pCodeOp *pcop)
 /* pop pcop from stack */
 void pic16_poppCodeOp(pCodeOp *pcop)
 {
-  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
+  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg( pic16_stack_preinc ), pcop));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
 }
@@ -2325,7 +2449,7 @@ void pic16_poppCodeOp(pCodeOp *pcop)
 void pushw(void)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
+  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
 }
@@ -2340,13 +2464,12 @@ 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_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_pc_postdec1)));
+      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec )));
   }
 
-//  pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
 }
@@ -2357,7 +2480,7 @@ void pushaop(asmop *aop, int offset)
 void popaop(asmop *aop, int offset)
 {
   DEBUGpic16_emitcode("; ***", "%s  %d", __FUNCTION__, __LINE__);
-  pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
+  pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pic16_stack_preinc, PCOR(pic16_popGet(aop, offset)), 0));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
 }
@@ -2371,7 +2494,7 @@ void popaopidx(asmop *aop, int offset, int index)
     if(STACK_MODEL_LARGE)ofs++;
 
     pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
-    pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
+    pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pic16_frame_plusw, PCOR(pic16_popGet(aop, offset)), 0));
     if(pic16_options.gstack)
       pic16_testStackOverflow();
 }
@@ -2670,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++;
     }
     
@@ -2685,6 +2808,8 @@ static void genUminus (iCode *ic)
 {
   int size, i;
   sym_link *optype, *rtype;
+  symbol *label;
+  int needLabel=0;
 
     FENTRY;    
     
@@ -2713,21 +2838,33 @@ static void genUminus (iCode *ic)
 
     /* otherwise subtract from zero by taking the 2's complement */
     size = AOP_SIZE(IC_LEFT(ic));
-
-    for(i=0; i<size; i++) {
-      if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
-        pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)),i));
-      else {
-        pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
-        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
-      }
-    }
-
-    pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
-    for(i=1; i<size; i++) {
-      emitSKPNZ;
-      pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RESULT(ic)),i));
+    label = newiTempLabel ( NULL );
+    
+    if (pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+      for (i=size-1; i > 0; i--) {
+        pic16_emitpcode (POC_COMF, pic16_popGet (AOP(IC_LEFT(ic)), i));
+      } // for
+      pic16_emitpcode (POC_NEGF, pic16_popGet (AOP(IC_LEFT(ic)), 0));
+      for (i=1; i < size; i++) {
+        if (i == size - 1) { emitSKPNZ; } else { pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++; }
+        pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_LEFT(ic)), i));
+      } // for
+    } else {
+      for (i=size-1; i >= 0; i--) {
+        pic16_emitpcode (POC_COMFW, pic16_popGet (AOP(IC_LEFT(ic)), i));
+       pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+      } // for
+      if (size > 1) {
+        for (i=0; i < size-2; i++) {
+          pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_RESULT(ic)),i));
+          pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++;
+       } // for
+        pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(IC_RESULT(ic)), size-2));
+      } // if
+      pic16_emitpcode (POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)), size-1));
     }
+    if (needLabel)
+      pic16_emitpLabel (label->key);
 
 release:
     /* release the aops */
@@ -2925,10 +3062,10 @@ static void assignResultValue(operand * oper, int rescall)
                        
        /* fix stack */
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
-       pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
+       pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));      //&pic16_pc_fsr1l ));
        if(STACK_MODEL_LARGE) {
          emitSKPNC;
-         pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
+         pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));     //&pic16_pc_fsr1h ));
        }
       }                        
     } else {
@@ -3177,7 +3314,7 @@ static void genCall (iCode *ic)
 //     stackParms = psuedoStkPtr;
 //     fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
     fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name;
-    inwparam = inWparamList(OP_SYMBOL(IC_LEFT(ic))->name);
+    inwparam = (inWparamList(OP_SYMBOL(IC_LEFT(ic))->name)) || (FUNC_ISWPARAM(OP_SYM_TYPE(IC_LEFT(ic))));
 
 #if 0
     gpsimDebug_StackDump(__FILE__, __LINE__, fname );
@@ -3243,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();
               }
             }
 
@@ -3293,14 +3432,14 @@ static void genCall (iCode *ic)
     
     if(stackParms>0) {
       if(stackParms == 1) {
-        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg(pic16_stackpnt_lo ));       //&pic16_pc_fsr1l));
       } else {
         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
-        pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
+        pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));     //&pic16_pc_fsr1l ));
       }
       if(STACK_MODEL_LARGE) {
         emitSKPNC;
-        pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));      //&pic16_pc_fsr1h ));
       }
     }
 
@@ -3381,6 +3520,11 @@ static void genPcall (iCode *ic)
     // push return address
     // push $ on return stack, then replace with retlbl
 
+    /* Thanks to Thorsten Klose for pointing out that the following
+     * snippet should be interrupt safe */
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_intcon), pic16_popCopyReg(&pic16_pc_postdec1)));
+    pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_intcon), 7));
+
     pic16_emitpcodeNULLop(POC_PUSH);
 
     pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
@@ -3390,6 +3534,11 @@ static void genPcall (iCode *ic)
     pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
 
+
+    /* restore interrupt control register */
+    pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_preinc1));
+    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_intcon));
+
     /* make the call by writing the pointer into pc */
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
@@ -3427,11 +3576,10 @@ static void genPcall (iCode *ic)
     
     if(stackParms>0) {
       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
+      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));
       if(STACK_MODEL_LARGE) {
-        /* this implies that stackParms < 256 !!! -- VR */
         emitSKPNC;
-        pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));
       }
     }
 }
@@ -3509,38 +3657,33 @@ static void genFunction (iCode *ic)
       char asymname[128];
       pBlock *apb;
 
-        {
-          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;
-        }
-
-        sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
-        asym = newSymbol(asymname, 0);
-
-        apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
-        pic16_addpBlock( apb );
+//        debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type));
 
-        pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
-        pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
-        pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+        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);
+  
+        /* 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;
@@ -3548,14 +3691,19 @@ static void genFunction (iCode *ic)
            abSym = Safe_calloc(1, sizeof(absSym));
            strcpy(abSym->name, asymname);
 
-           switch( _G.interruptvector ) {
+           switch( FUNC_INTNO(sym->type) ) {
              case 0: abSym->address = 0x000000; break;
               case 1: abSym->address = 0x000008; break;
               case 2: abSym->address = 0x000018; break;
+              
+              default:
+//                fprintf(stderr, "no interrupt number is given\n");
+                abSym->address = -1; break;
             }
 
             /* relocate interrupt vectors if needed */
-            abSym->address += pic16_options.ivt_loc;
+            if(abSym->address != -1)
+              abSym->address += pic16_options.ivt_loc;
 
             addSet(&absSymSet, abSym);
         }
@@ -3569,7 +3717,6 @@ static void genFunction (iCode *ic)
     pic16_emitcode("","%s:",sym->rname);
     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
 
-
     {
       absSym *ab;
 
@@ -3581,7 +3728,6 @@ static void genFunction (iCode *ic)
         }
     }
 
-
     if(IFFUNC_ISNAKED(ftype)) {
       DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
       return;
@@ -3592,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 */
@@ -3600,7 +3749,7 @@ static void genFunction (iCode *ic)
         _G.usefastretfie = 1;  /* use shadow registers by default */
         
         /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
-        if(!(_G.interruptvector == 1)) {
+        if(!FUNC_ISSHADOWREGS(sym->type)) {
           /* do not save WREG,STATUS,BSR for high priority interrupts
            * because they are stored in the hardware shadow registers already */
           _G.usefastretfie = 0;
@@ -3617,23 +3766,27 @@ 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_pc_fsr2h));
-        pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2l));
-//        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
-        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
+          pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_hi));
+        pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_lo));
+
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( pic16_stackpnt_lo, pic16_framepnt_lo, 0));
         if(STACK_MODEL_LARGE)
-          pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
+          pic16_emitpcode(POC_MOVFF, pic16_popCombine2( pic16_stackpnt_hi, pic16_framepnt_hi, 0));
       }
     }
 
@@ -3643,12 +3796,12 @@ static void genFunction (iCode *ic)
       if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
 
       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
-      pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
+      pic16_emitpcode(POC_SUBWF, pic16_popCopyReg( pic16_stackpnt_lo ));       //&pic16_pc_fsr1l));
       emitSKPC;
-      pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
+      pic16_emitpcode(POC_DECF, pic16_popCopyReg( pic16_stackpnt_hi ));                //&pic16_pc_fsr1h));
     }
           
-    if(inWparamList(sym->name)) {
+    if(inWparamList(sym->name) || FUNC_ISWPARAM(sym->type)) {
       if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
         _G.useWreg = 0;
       else
@@ -3714,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;
 
@@ -3727,34 +3891,38 @@ 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) {
-        pic16_emitpcode(POC_INFSNZ, pic16_popCopyReg(&pic16_pc_fsr1l));
-        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
+        pic16_emitpcode(POC_INFSNZ, pic16_popCopyReg( pic16_stackpnt_lo ));
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));
       } else {
         // we have to add more than one...
-        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc1)); // this holds a return value!
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postinc ));   // this holds a return value!
         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack-1));
-        pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
+        pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));
         emitSKPNC;
-        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));
         pic16_emitpcode(POC_COMF,  pic16_popCopyReg(&pic16_pc_wreg)); // WREG = -(WREG+1)!
-        pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_plusw1)); // this holds a retrun value!
+        pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_plusw)); // this holds a retrun value!
       }
     }
 
     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_pc_fsr2h ));
-//          pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
-        pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2l ));
-//        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+          pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_hi ));
+        pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_lo ));
       }
     }
 
@@ -3766,14 +3934,14 @@ static void genEndFunction (iCode *ic)
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
 
-      if(!(_G.interruptvector == 1)) {
+      if(!FUNC_ISSHADOWREGS(sym->type)) {
         /* do not restore interrupt vector for WREG,STATUS,BSR
          * for high priority interrupt, see genFunction */
        pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
        pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
        pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
       }
-      _G.interruptvector = 0;          /* sanity check */
+//      _G.interruptvector = 0;                /* sanity check */
 
 
       /* if debug then send end of function */
@@ -3813,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));
@@ -3853,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 */
@@ -3889,13 +4066,13 @@ static void genRet (iCode *ic)
                        
                /* setup FSR0 */
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                       pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
+                       pic16_popCopyReg( pic16_stackpnt_lo ), pic16_popCopyReg(&pic16_pc_fsr0l)));
 
                if(STACK_MODEL_LARGE) {
                        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                               pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
+                               pic16_popCopyReg( pic16_stackpnt_hi ), pic16_popCopyReg(&pic16_pc_fsr0h)));
                } else {
-                       pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
+                       pic16_emitpcode(POC_CLRF, pic16_popCopyReg( pic16_stackpnt_hi ));
                }
        }
                                
@@ -4577,6 +4754,33 @@ static void genIfxJump (iCode *ic, char *jval)
     ic->generated = 1;
 }
 
+static void genIfxpCOpJump (iCode *ic, pCodeOp *jop)
+{
+  FENTRY;
+  
+    /* if true label then we jump if condition
+    supplied is true */
+    if ( IC_TRUE(ic) ) {
+      DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__);    
+      pic16_emitpcode(POC_BTFSC, jop);
+
+      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
+      pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
+
+    } else {
+      /* false label is present */
+      DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__);
+      pic16_emitpcode(POC_BTFSS, jop);
+         
+      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
+      pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
+    }
+
+
+    /* mark the icode as generated */
+    ic->generated = 1;
+}
+
 #if 0
 // not needed ATM
 
@@ -4643,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;
@@ -4748,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    */
@@ -4771,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
@@ -4807,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! *
    **********************************************************************/
@@ -4833,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
@@ -4849,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
@@ -4871,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;
@@ -4881,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;
@@ -4957,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) {
@@ -4983,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,
@@ -5625,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));
@@ -5715,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,
@@ -5825,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)
 {
@@ -5967,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;
 
@@ -5980,7 +6170,6 @@ static void genCmp (operand *left, operand *right,
         }
       } else {
 
-
         /* unsigned compare */      
         DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
     
@@ -5991,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 );
@@ -6079,515 +6266,58 @@ static void genCmp (operand *left, operand *right,
     }
 }
 
-#else    /* } else { */
+#endif /* } */
 
-/* new version of genCmp -- VR 20041012 */
-static void genCmp (operand *left,operand *right,
-                    operand *result, iCode *ifx, int sign)
+
+
+/*-----------------------------------------------------------------*/
+/* genCmpGt :- greater than comparison                             */
+/*-----------------------------------------------------------------*/
+static void genCmpGt (iCode *ic, iCode *ifx)
 {
-  int size; //, offset = 0 ;
-  unsigned long lit = 0L,i = 0;
-  resolvedIfx rFalseIfx;
-  int willCheckCarry=0;
-  //  resolvedIfx rTrueIfx;
-  symbol *truelbl;
+  operand *left, *right, *result;
+  sym_link *letype , *retype;
+  int sign ;
 
     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);
+    
+    left = IC_LEFT(ic);
+    right= IC_RIGHT(ic);
+    result = IC_RESULT(ic);
 
-  /* POC_CPFSGT        compare f, wreg, skip if f greater than wreg
-   * POC_CPFSLT compare f, wreg, skip if f less then wreg */
-  
+    letype = getSpec(operandType(left));
+    retype =getSpec(operandType(right));
+    sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
+    /* assign the amsops */
+    pic16_aopOp (left,ic,FALSE);
+    pic16_aopOp (right,ic,FALSE);
+    pic16_aopOp (result,ic,TRUE);
 
-  /* 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;
+    genCmp(right, left, result, ifx, sign);
 
-      lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+    pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+    pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+    pic16_freeAsmop(result,NULL,ic,TRUE); 
+}
 
-//      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);
-  }
+/*-----------------------------------------------------------------*/
+/* genCmpLt - less than comparisons                                */
+/*-----------------------------------------------------------------*/
+static void genCmpLt (iCode *ic, iCode *ifx)
+{
+  operand *left, *right, *result;
+  sym_link *letype , *retype;
+  int sign ;
 
+    FENTRY;
 
-  //if(IC_TRUE(ifx) == NULL)
-  /* if left & right are bit variables */
-  if (AOP_TYPE(left) == AOP_CRY &&
-      AOP_TYPE(right) == AOP_CRY ) {
+    left = IC_LEFT(ic);
+    right= IC_RIGHT(ic);
+    result = IC_RESULT(ic);
 
-    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 */
-  }
-
-}
-#endif /* } */
-
-
-#endif /* } */
-
-
-
-/*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison                             */
-/*-----------------------------------------------------------------*/
-static void genCmpGt (iCode *ic, iCode *ifx)
-{
-  operand *left, *right, *result;
-  sym_link *letype , *retype;
-  int sign ;
-
-    FENTRY;
-    
-    left = IC_LEFT(ic);
-    right= IC_RIGHT(ic);
-    result = IC_RESULT(ic);
-
-    letype = getSpec(operandType(left));
-    retype =getSpec(operandType(right));
-    sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
-    /* assign the amsops */
-    pic16_aopOp (left,ic,FALSE);
-    pic16_aopOp (right,ic,FALSE);
-    pic16_aopOp (result,ic,TRUE);
-
-    genCmp(right, left, result, ifx, sign);
-
-    pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(result,NULL,ic,TRUE); 
-}
-
-/*-----------------------------------------------------------------*/
-/* genCmpLt - less than comparisons                                */
-/*-----------------------------------------------------------------*/
-static void genCmpLt (iCode *ic, iCode *ifx)
-{
-  operand *left, *right, *result;
-  sym_link *letype , *retype;
-  int sign ;
-
-    FENTRY;
-
-    left = IC_LEFT(ic);
-    right= IC_RIGHT(ic);
-    result = IC_RESULT(ic);
-
-    letype = getSpec(operandType(left));
-    retype =getSpec(operandType(right));
-    sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
+    letype = getSpec(operandType(left));
+    retype =getSpec(operandType(right));
+    sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
 
     /* assign the amsops */
     pic16_aopOp (left,ic,FALSE);
@@ -6948,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;
   
@@ -6972,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;
 
@@ -6993,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));
@@ -7462,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);
 
@@ -7511,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);
 
@@ -8499,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) {
@@ -8548,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);
 
@@ -8593,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);
 
@@ -8899,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));
     }
@@ -8914,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:
@@ -9628,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));
 
@@ -9754,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++;
     }
@@ -9786,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
 
@@ -9937,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++;
     }
@@ -9966,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));
@@ -10092,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));
     }
   }
 
@@ -10236,7 +10034,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));
 
@@ -10251,8 +10049,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)){
@@ -10261,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 {
 
@@ -10584,7 +10384,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));
@@ -10630,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)
@@ -10722,9 +10522,66 @@ static void genRightShift (iCode *ic) {
 #endif
 
 
-void pic16_loadFSR0(operand *op)
-{
-       pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+/* 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)
+{
+  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;
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -10733,11 +10590,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));
@@ -10757,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));
       }
@@ -10777,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 );
-       /* 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 */
@@ -10824,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 ;
 }
 
@@ -10884,7 +10682,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);
@@ -10936,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 {
@@ -10963,15 +10763,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);
 
@@ -10993,35 +10795,53 @@ static void genNearPointerGet (operand *left,
     }
     
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    pic16_aopOp (result,ic,TRUE);
+    
+    DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result);
 
-    /* if the value is already in a pointer register
-     * then don't need anything more */
-    if (!AOP_INPREG(AOP(left))) {
-      /* 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 1
+    if(IS_BITFIELD( retype )
+      && (SPEC_BLEN(operandType(result))==1)
+    ) {
+      iCode *nextic;
+      pCodeOp *jop;
+      int bitstrt, bytestrt;
+
+        /* if this is bitfield of size 1, see if we are checking the value
+         * of a single bit in an if-statement,
+         * if yes, then don't generate usual code, but execute the
+         * genIfx directly -- VR */
+
+        nextic = ic->next;
+
+        /* CHECK: if next iCode is IFX
+         * and current result operand is nextic's conditional operand
+         * and current result operand live ranges ends at nextic's key number
+         */
+        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 */
+
+            bytestrt = SPEC_BSTR(operandType(result))/8;
+            bitstrt = SPEC_BSTR(operandType(result))%8;
+            
+            jop = pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bitstrt);
 
-        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
+            genIfxpCOpJump(nextic, jop);
+            
+            pic16_freeAsmop(left, NULL, ic, TRUE);
+            pic16_freeAsmop(result, NULL, ic, TRUE);
+            return;
         }
-      }
     }
-//    else
-//    rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
-    
-    pic16_aopOp (result,ic,FALSE);
-    
-    DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result);
+#endif
 
     /* 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 */
@@ -11030,11 +10850,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),
@@ -11044,29 +10861,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 */
@@ -11088,6 +10885,7 @@ static void genNearPointerGet (operand *left,
 //          pic16_emitcode("dec","%s",rname);
        }
     }
+#endif
 
     /* done */
     pic16_freeAsmop(left,NULL,ic,TRUE);
@@ -11127,7 +10925,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)) 
@@ -11205,7 +11003,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)) 
@@ -11224,6 +11022,7 @@ static void genFarPointerGet (operand *left,
 
     pic16_freeAsmop(result,NULL,ic,TRUE);
 }
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* genCodePointerGet - get value from code space                  */
@@ -11276,6 +11075,7 @@ static void genCodePointerGet (operand *left,
     pic16_freeAsmop(result,NULL,ic,TRUE);
 }
 #endif
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* genGenPointerGet - gget value from generic pointer space        */
@@ -11317,7 +11117,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--) {
@@ -11350,15 +11150,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!)
 
@@ -11387,37 +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 );
-          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);
@@ -11444,29 +11225,11 @@ static void genConstPointerGet (operand *left,
   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
 
   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
-#if 0                                                                  // patch 15
-  pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
-  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
-  pic16_emitpLabel(albl->key);
-
-  poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
-  
-  /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
-  pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
-  pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
-  pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
-  pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
-
-  pic16_emitpLabel(blbl->key);
-
-  pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
-#endif                                                                 // patch 15
-
 
   // set up table pointer
   if( (AOP_TYPE(left) == AOP_PCODE) 
       && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
-          || (AOP(left)->aopu.pcop->type == PO_DIR)))                  // patch 15 ......
+          || (AOP(left)->aopu.pcop->type == PO_DIR)))
     {
       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
@@ -11474,25 +11237,20 @@ static void genConstPointerGet (operand *left,
       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
-    }
-  else
-    {
-      pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
-      pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
-      pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
-    }
-
+  } else {
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
+  }
 
-  while(size--)
-    {
-      pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
-      pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
-      offset++;
-    }
+  while(size--) {
+    pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
+    offset++;
+  }
     
   pic16_freeAsmop(left,NULL,ic,TRUE);
   pic16_freeAsmop(result,NULL,ic,TRUE);
-
 }
 
 
@@ -11501,9 +11259,9 @@ static void genConstPointerGet (operand *left,
 /*-----------------------------------------------------------------*/
 static void genPointerGet (iCode *ic)
 {
-    operand *left, *result ;
-    sym_link *type, *etype;
-    int p_type;
+  operand *left, *result ;
+  sym_link *type, *etype;
+  int p_type;
 
     FENTRY;
     
@@ -11524,57 +11282,56 @@ static void genPointerGet (iCode *ic)
 
     /* if left is of type of pointer then it is simple */
     if (IS_PTR(type) && !IS_FUNC(type->next)) 
-        p_type = DCL_TYPE(type);
+      p_type = DCL_TYPE(type);
     else {
-       /* we have to go by the storage class */
-       p_type = PTR_TYPE(SPEC_OCLS(etype));
+      /* we have to go by the storage class */
+      p_type = PTR_TYPE(SPEC_OCLS(etype));
 
-       DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
+      DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
 
-       if (SPEC_OCLS(etype)->codesp ) {
-         DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
-         //p_type = CPOINTER ; 
-       }
-       else
-           if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
-             DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
-              /*p_type = FPOINTER ;*/ 
-           else
-               if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
-                 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
-/*                 p_type = PPOINTER; */
-               else
-                   if (SPEC_OCLS(etype) == idata )
-                     DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
-/*                     p_type = IPOINTER; */
-                   else
-                     DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
-/*                     p_type = POINTER ; */
+      if (SPEC_OCLS(etype)->codesp ) {
+        DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
+        //p_type = CPOINTER ;  
+      } else
+      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) {
+        DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
+        /*p_type = FPOINTER ;*/ 
+      } else
+      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) {
+        DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
+        /* p_type = PPOINTER; */
+      } else
+      if (SPEC_OCLS(etype) == idata ) {
+        DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
+        /* p_type = IPOINTER; */
+      } else {
+        DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
+        /* p_type = POINTER ; */
+      }
     }
 
     /* now that we have the pointer type we assign
     the pointer values */
     switch (p_type) {
-
-    case POINTER:      
-    case IPOINTER:
+      case POINTER:    
+      case IPOINTER:
        genNearPointerGet (left,result,ic);
        break;
 
-    case PPOINTER:
+      case PPOINTER:
        genPagedPointerGet(left,result,ic);
        break;
 
-    case FPOINTER:
+      case FPOINTER:
        genFarPointerGet (left,result,ic);
        break;
 
-    case CPOINTER:
+      case CPOINTER:
        genConstPointerGet (left,result,ic);
        //pic16_emitcodePointerGet (left,result,ic);
        break;
 
-    case GPOINTER:
+      case GPOINTER:
 #if 0
       if (IS_PTR_CONST(type))
        genConstPointerGet (left,result,ic);
@@ -11588,7 +11345,6 @@ static void genPointerGet (iCode *ic)
              "genPointerGet: illegal pointer type");
     
     }
-
 }
 
 /*-----------------------------------------------------------------*/
@@ -11603,7 +11359,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);
@@ -11620,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,
@@ -11630,7 +11385,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));
@@ -11642,7 +11397,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
@@ -11673,80 +11428,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");
@@ -11756,21 +11511,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");
@@ -11782,29 +11541,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                 */
@@ -11880,7 +11650,6 @@ static void genNearPointerSet (operand *right,
                                iCode *ic)
 {
   asmop *aop = NULL;
-  char *l;
   sym_link *retype;
   sym_link *ptype = operandType(result);
   sym_link *resetype;
@@ -11910,35 +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 (!AOP_INPREG(AOP(result))) {
-               /* 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);
@@ -11947,68 +11687,62 @@ 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) {                                                       // patch 10
-                                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));                    // 
-                                       if (size) {                                                                     // 
-                                               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));        // 
-                                       } else {                                                                        // 
-                                               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));           // 
-                                       }                                                                               // 
-                               } else { // no literal                                                                  // 
-                                       if(size) {                                                                      // 
-                                               pic16_emitpcode(POC_MOVFF,                                              // 
-                                                               pic16_popGet2p(pic16_popGet(AOP(right),offset),         // 
-                                                                       pic16_popCopyReg(&pic16_pc_postinc0)));         // 
-                                       } else {                                                                        // 
-                                               pic16_emitpcode(POC_MOVFF,                                              // 
-                                                               pic16_popGet2p(pic16_popGet(AOP(right),offset),         // 
-                                                                       pic16_popCopyReg(&pic16_pc_indf0)));            //
-                                       }                                                                               //
-                               }                                                                                       // patch 10
-                       }
+                               if (AOP_TYPE(right) == AOP_LIT) {
+                                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
+                                       if (size) {
+                                               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
+                                       } else {
+                                               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
+                                       }
+                               } else { // no literal
+                                       if(size) {
+                                               pic16_emitpcode(POC_MOVFF,
+                                                               pic16_popGet2p(pic16_popGet(AOP(right),offset),
+                                                                       pic16_popCopyReg(&pic16_pc_postinc0)));
+                                       } else {
+                                               pic16_emitpcode(POC_MOVFF,
+                                                               pic16_popGet2p(pic16_popGet(AOP(right),offset),
+                                                                       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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -12273,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__);
 
@@ -12297,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
@@ -12317,27 +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 );
-        strcpy(sym->rname, fgptrput);
-        checkAddSym(&externs, sym);
-    }
+    pic16_callGenericPointerRW(1, size);
 
 release:
     pic16_freeAsmop(right,NULL,ic,TRUE);
@@ -12362,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);
@@ -12389,27 +12102,26 @@ static void genPointerSet (iCode *ic)
     /* now that we have the pointer type we assign
     the pointer values */
     switch (p_type) {
+      case POINTER:
+      case IPOINTER:
+        genNearPointerSet (right,result,ic);
+        break;
 
-    case POINTER:
-    case IPOINTER:
-       genNearPointerSet (right,result,ic);
-       break;
-
-    case PPOINTER:
-       genPagedPointerSet (right,result,ic);
-       break;
-
-    case FPOINTER:
-       genFarPointerSet (right,result,ic);
+      case PPOINTER:
+        genPagedPointerSet (right,result,ic);
        break;
 
-    case GPOINTER:
-       genGenPointerSet (right,result,ic);
-       break;
+      case FPOINTER:
+        genFarPointerSet (right,result,ic);
+        break;
+        
+      case GPOINTER:
+        genGenPointerSet (right,result,ic);
+        break;
 
-    default:
-      werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
-             "genPointerSet: illegal pointer type");
+      default:
+        werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
+          "genPointerSet: illegal pointer type");
     }
 }
 
@@ -12471,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
@@ -12486,10 +12198,10 @@ static void genAddrOf (iCode *ic)
        } // if
        DEBUGpic16_emitcode("*!*", "accessing stack symbol at offset=%d", soffs);
        pic16_emitpcode(POC_MOVLW , pic16_popGetLit( soffs & 0x00FF ));
-       pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(&pic16_pc_fsr2l));
+       pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(pic16_framepnt_lo));
        pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 0));
        pic16_emitpcode(POC_MOVLW , pic16_popGetLit( (soffs >> 8) & 0x00FF ));
-       pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(&pic16_pc_fsr2h));
+       pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi));
        pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1));
       }
 
@@ -12504,10 +12216,6 @@ static void genAddrOf (iCode *ic)
     pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
     size = AOP_SIZE(IC_RESULT(ic));
 
-
-    /* Assume that what we want the address of is in data space
-     * since there is no stack on the PIC, yet! -- VR */
-  
     pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
     pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
     pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
@@ -12669,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);
 
@@ -12701,7 +12414,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),
@@ -12709,8 +12423,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++;
@@ -12851,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 */
@@ -13017,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);
 
@@ -13205,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) {
@@ -13245,7 +12963,13 @@ static void genCast (iCode *ic)
                break;
 
             case GPOINTER:
-              pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
+               if (GPTRSIZE > AOP_SIZE(right)) {
+                 // assume data pointer... THIS MIGHT BE WRONG!
+                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
+                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
+               } else {
+                 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
+               }
               break;
               
            default:
@@ -13258,6 +12982,8 @@ static void genCast (iCode *ic)
            goto release ;
        }
        
+       
+       assert( 0 );
        /* just copy the pointers */
        size = AOP_SIZE(result);
        offset = 0 ;
@@ -13285,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++;
     }
 
@@ -13303,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));
 
@@ -13441,10 +13169,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
 }
 
 /*-----------------------------------------------------------------*/
@@ -13480,7 +13224,7 @@ void genpic16Code (iCode *lic)
 
     for (ic = lic ; ic ; ic = ic->next ) {
 
-      DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
+      DEBUGpic16_emitcode(";ic ", "\t%c 0x%x\t(%s)",ic->op, ic->op, pic16_decodeOp(ic->op));
       if ( cln != ic->lineno ) {
         if ( options.debug ) {
           debugFile->writeCLine (ic);