* src/pic16/gen.c (genNearPointerGet): fix double indirect
[fw/sdcc] / src / pic16 / gen.c
index 82665758a21b85aa5ef5207fd97dbafce67c86a1..461b8b2d27aa5113f15b541c4f1018a86a75118a 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,29 +6,32 @@
   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,2005)
-  
+             -  Vangelis Rokas <vrokas AT users.sourceforge.net> (2003-2006)
+  Bug Fixes  -  Raphael Neider <rneider AT web.de> (2004,2005)
+  Bug Fixes  -  Borut Razem <borut.razem AT siol.net> (2007)
+  Bug Fixes  -  Mauro Giachero <maurogiachero AT users.sourceforge.net> (2008)
+
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.
-  
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-  
+
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-  
+
   In other words, you are welcome to use, share and improve this program.
   You are forbidden to forbid anyone else to use, share and improve
   what you give them.   Help stamp out software-hoarding!
-  
+
   Notes:
-  000123 mlh   Moved aopLiteral to SDCCglue.c to help the split
-               Made everything static
+  000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
+                Made everything static
 -------------------------------------------------------------------------*/
 
 #include <stdio.h>
 #include "genutils.h"
 #include "device.h"
 #include "main.h"
+#include "glue.h"
+
+/* The PIC port(s) do not need to distinguish between POINTER and FPOINTER. */
+#define PIC_IS_DATA_PTR(x)      (IS_DATA_PTR(x) || IS_FARPTR(x))
+#define PIC_IS_FARPTR(x)        (IS_DATA_PTR(x) || IS_FARPTR(x))
+#define PIC_IS_TAGGED(x)        (IS_GENPTR(x) || IS_CODEPTR(x))
+#define IS_DIRECT(op)           ((AOP_TYPE(op) == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_DIR))
 
-/* Set the following to 1 to enable the slower/bigger
- * but more robust generic shifting routine (which also
- * operates correctly with negative shift values). */
-#define USE_GENERIC_SIGNED_SHIFT 1
-
-/* Set the following to 1 to enable the new
- * stripped down genCmp version.
- * This version should be easier to understand,
- * more reliable and (sigh) slighly slower. */
-#define USE_SIMPLE_GENCMP 1
-
-extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
-extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
-void pic16_genMult8X8_8 (operand *, operand *,operand *);
-void pic16_genMult16X16_16(operand *, operand *, operand *);
-void pic16_genMult32X32_32(operand *, operand *, operand *);
-pCode *pic16_AssembleLine(char *line, int peeps);
+/* Wrapper to execute `code' at most once. */
+#define PERFORM_ONCE(id,code)   do { static char id = 0; if (!id) { id = 1; code } } while (0)
+
+void pic16_genMult8X8_n (operand *, operand *,operand *);
 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);
 
-//static int aopIdx (asmop *aop, int offset);
-
 int pic16_labelOffset=0;
 extern int pic16_debug_verbose;
-#if !(USE_GENERIC_SIGNED_SHIFT)
-static int optimized_for_speed = 0;
-#endif
-/*
-  hack hack
-
-*/
 
 extern set *externs;
 
-/* max_key keeps track of the largest label number used in 
+/* max_key keeps track of the largest label number used in
    a function. This is then used to adjust the label offset
    for the next function.
 */
@@ -95,85 +82,60 @@ static int GpsuedoStkPtr=0;
 
 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
 
-unsigned int pic16aopLiteral (value *val, int offset);
 const char *pic16_AopType(short type);
 static iCode *ifxForOp ( operand *op, iCode *ic );
 
 void pic16_pushpCodeOp(pCodeOp *pcop);
 void pic16_poppCodeOp(pCodeOp *pcop);
 
-static bool is_LitOp(operand *op);
-static bool is_LitAOp(asmop *aop);
-
 
 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
 
 /* set the following macro to 1 to enable passing the
  * first byte of functions parameters via WREG */
-#define USE_WREG_IN_FUNC_PARAMS        0
+#define USE_WREG_IN_FUNC_PARAMS 0
 
 
-/* this is the down and dirty file with all kinds of 
+/* this is the down and dirty file with all kinds of
    kludgy & hacky stuff. This is what it is all about
    CODE GENERATION for a specific MCU . some of the
    routines may be reusable, will have to see */
-
 static char *zero = "#0x00";
 static char *one  = "#0x01";
-//static char *spname = "sp";
 
 
 /*
  * Function return value policy (MSB-->LSB):
- *  8 bits     -> WREG
- * 16 bits     -> PRODL:WREG
- * 24 bits     -> PRODH:PRODL:WREG
- * 32 bits     -> FSR0L:PRODH:PRODL:WREG
- * >32 bits    -> on stack, and FSR0 points to the beginning
- *
+ *  8 bits      -> WREG
+ * 16 bits      -> PRODL:WREG
+ * 24 bits      -> PRODH:PRODL:WREG
+ * 32 bits      -> FSR0L:PRODH:PRODL:WREG
+ * >32 bits     -> on stack, and FSR0 points to the beginning
  */
-
-char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" };
+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;
 
 static char *accUse[] = {"WREG"};
 
-//static short rbank = -1;
-
 static struct {
-    short r0Pushed;
-    short r1Pushed;
-    short fsr0Pushed;
     short accInUse;
     short inLine;
     short debugLine;
     short nRegsSaved;
-    short ipushRegs;
     set *sendSet;
     set *stackRegSet;
     int usefastretfie;
-    bitVect *fregsUsed;
-    int stack_lat;                     /* stack offset latency */
+    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 */
+    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;
-//static void saverbank (int, iCode *,bool);
+extern struct dbuf_s *codeOutBuf;
 
 static lineNode *lineHead = NULL;
 static lineNode *lineCurr = NULL;
@@ -200,8 +162,8 @@ int pic16_my_powof2 (unsigned long num)
     if( (num & (num-1)) == 0) {
       int nshifts = -1;
       while(num) {
-       num>>=1;
-       nshifts++;
+        num>>=1;
+        nshifts++;
       }
       return nshifts;
     }
@@ -213,79 +175,80 @@ int pic16_my_powof2 (unsigned long num)
 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
 {
   DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
-                      line_no,
-                      ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
-                      ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
-                      ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
-                      ((left)   ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
-                      ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
-                      ((right)  ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
-                      ((result) ? AOP_SIZE(result) : 0));
+                       line_no,
+                       ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
+                       ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
+                       ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
+                       ((left)   ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
+                       ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
+                       ((right)  ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
+                       ((result) ? AOP_SIZE(result) : 0));
 }
 
 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
 {
 
   DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
-                      line_no,
-                      ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
-                      ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
-                      ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
-                      ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
-                      ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
-                      ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
+                       line_no,
+                       ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
+                       ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
+                       ((left)   ? pic16_AopType(AOP_TYPE(left)) : "-"),
+                       ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
+                       ((right)  ? pic16_AopType(AOP_TYPE(right)) : "-"),
+                       ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
 
 }
 
 void pic16_emitpcomment (char *fmt, ...)
 {
     va_list ap;
-    char lb[INITIAL_INLINEASM];  
-    char *lbp = lb;
+    char lb[INITIAL_INLINEASM];
+    unsigned char *lbp = (unsigned char *)lb;
 
-    va_start(ap,fmt);   
+    va_start(ap,fmt);
 
     lb[0] = ';';
     vsprintf(lb+1,fmt,ap);
 
     while (isspace(*lbp)) lbp++;
 
-    if (lbp && *lbp) 
+    if (lbp && *lbp)
         lineCurr = (lineCurr ?
                     connectLine(lineCurr,newLineNode(lb)) :
                     (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
+    lineCurr->isComment = 1;
 
     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
     va_end(ap);
 
-//     fprintf(stderr, "%s\n", lb);
+//      fprintf(stderr, "%s\n", lb);
 }
 
 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
 {
     va_list ap;
-    char lb[INITIAL_INLINEASM];  
-    char *lbp = lb;
+    char lb[INITIAL_INLINEASM];
+    unsigned char *lbp = (unsigned char *)lb;
 
     if(!pic16_debug_verbose)
       return;
 
-    va_start(ap,fmt);   
+    va_start(ap,fmt);
 
     if (inst && *inst) {
-       if (fmt && *fmt)
-           sprintf(lb,"%s\t",inst);
-       else
-           sprintf(lb,"%s",inst);
+        if (fmt && *fmt)
+            sprintf(lb,"%s\t",inst);
+        else
+            sprintf(lb,"%s",inst);
         vsprintf(lb+(strlen(lb)),fmt,ap);
     }  else
         vsprintf(lb,fmt,ap);
 
     while (isspace(*lbp)) lbp++;
 
-    if (lbp && *lbp) 
+    if (lbp && *lbp)
         lineCurr = (lineCurr ?
                     connectLine(lineCurr,newLineNode(lb)) :
                     (lineHead = newLineNode(lb)));
@@ -295,22 +258,30 @@ void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
     va_end(ap);
 
-//     fprintf(stderr, "%s\n", lb);
+//      fprintf(stderr, "%s\n", lb);
 }
 
 
 
 void pic16_emitpLabel(int key)
 {
+  if(key>max_key)
+    max_key = key;
+
   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+pic16_labelOffset));
 }
 
 void pic16_emitpLabelFORCE(int key)
 {
+  if(key>max_key)
+    max_key = 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)
@@ -326,7 +297,7 @@ void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop)
   else
     DEBUGpic16_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
 }
-  
+
 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
 {
 
@@ -336,7 +307,7 @@ void pic16_emitpcodeNULLop(PIC_OPCODE poc)
 
 
 #if 1
-#define pic16_emitcode DEBUGpic16_emitcode
+#define pic16_emitcode  DEBUGpic16_emitcode
 #else
 /*-----------------------------------------------------------------*/
 /* pic16_emitcode - writes the code into a file : for now it is simple    */
@@ -344,28 +315,30 @@ void pic16_emitpcodeNULLop(PIC_OPCODE poc)
 void pic16_emitcode (char *inst,char *fmt, ...)
 {
     va_list ap;
-    char lb[INITIAL_INLINEASM];  
-    char *lbp = lb;
+    char lb[INITIAL_INLINEASM];
+    unsigned char *lbp = lb;
 
-    va_start(ap,fmt);   
+    va_start(ap,fmt);
 
     if (inst && *inst) {
-       if (fmt && *fmt)
-           sprintf(lb,"%s\t",inst);
-       else
-           sprintf(lb,"%s",inst);
+        if (fmt && *fmt)
+            sprintf(lb,"%s\t",inst);
+        else
+            sprintf(lb,"%s",inst);
         vsprintf(lb+(strlen(lb)),fmt,ap);
     }  else
         vsprintf(lb,fmt,ap);
 
     while (isspace(*lbp)) lbp++;
 
-    if (lbp && *lbp) 
+    if (lbp && *lbp)
         lineCurr = (lineCurr ?
                     connectLine(lineCurr,newLineNode(lb)) :
                     (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
+    lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':');
+    lineCurr->isComment = (*lbp == ';');
 
 // VR    fprintf(stderr, "lb = <%s>\n", lbp);
 
@@ -389,149 +362,6 @@ pic16_emitDebuggerSymbol (char * debugSym)
   _G.debugLine = 0;
 }
 
-
-/*-----------------------------------------------------------------*/
-/* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
-/*-----------------------------------------------------------------*/
-static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
-{
-//    bool r0iu = FALSE , r1iu = FALSE;
-//    bool r0ou = FALSE , r1ou = FALSE;
-    bool fsr0iu = FALSE, fsr0ou;
-    bool fsr2iu = FALSE, fsr2ou;
-    
-    fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result);
-
-    
-    fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
-    fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
-    
-    fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
-    fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
-
-    if(bitVectBitValue(ic->rUsed, IDX_WREG)) {
-       fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
-       DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
-    }
-
-    if(!fsr0iu && !fsr0ou) {
-       ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
-       (*aopp)->type = AOP_FSR0;
-
-       fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
-       
-      return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
-    }
-
-#if 0
-    /* no usage of FSR2 */
-    if(!fsr2iu && !fsr2ou) {
-       ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
-       (*aopp)->type = AOP_FSR2;
-
-      return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2);
-    }
-#endif
-       
-    /* now we know they both have usage */
-    /* if fsr0 not used in this instruction */
-    if (!fsr0iu) {
-       if (!_G.fsr0Pushed) {
-               pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
-               pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
-               _G.fsr0Pushed++;
-       }
-
-       ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
-       (*aopp)->type = AOP_FSR0;
-
-//     fprintf(stderr, "%s:%d returning FSR0 after pushing value to stack\n", __FILE__, __LINE__);
-
-      return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0);
-    }
-       
-
-    fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
-    assert( 0 );
-
-    return NULL;
-#if 0
-    /* the logic: if r0 & r1 used in the instruction
-    then we are in trouble otherwise */
-
-    /* first check if r0 & r1 are used by this
-    instruction, in which case we are in trouble */
-    if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
-        (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
-    {
-        goto endOfWorld;      
-    }
-
-    r0ou = bitVectBitValue(ic->rMask,R0_IDX);
-    r1ou = bitVectBitValue(ic->rMask,R1_IDX);
-
-    /* if no usage of r0 then return it */
-    if (!r0iu && !r0ou) {
-        ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
-        (*aopp)->type = AOP_R0; 
-        
-        return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
-    }
-
-    /* if no usage of r1 then return it */
-    if (!r1iu && !r1ou) {
-        ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
-        (*aopp)->type = AOP_R1;
-
-        return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
-    }    
-
-    /* now we know they both have usage */
-    /* if r0 not used in this instruction */
-    if (!r0iu) {
-        /* push it if not already pushed */
-        if (!_G.r0Pushed) {
-         //pic16_emitcode ("push","%s",
-         //          pic16_regWithIdx(R0_IDX)->dname);
-            _G.r0Pushed++ ;
-        }
-        
-        ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
-        (*aopp)->type = AOP_R0;
-
-        return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
-    }
-
-    /* if r1 not used then */
-
-    if (!r1iu) {
-        /* push it if not already pushed */
-        if (!_G.r1Pushed) {
-         //pic16_emitcode ("push","%s",
-         //          pic16_regWithIdx(R1_IDX)->dname);
-            _G.r1Pushed++ ;
-        }
-        
-        ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
-        (*aopp)->type = AOP_R1;
-        return pic16_regWithIdx(R1_IDX);
-    }
-
-endOfWorld :
-    /* I said end of world but not quite end of world yet */
-    /* if this is a result then we can push it on the stack*/
-    if (result) {
-        (*aopp)->type = AOP_STK;    
-        return NULL;
-    }
-
-    /* other wise this is true end of the world */
-    werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-           "getFreePtr should never reach here");
-    exit(0);
-#endif
-}
-
 /*-----------------------------------------------------------------*/
 /* newAsmop - creates a new asmOp                                  */
 /*-----------------------------------------------------------------*/
@@ -544,20 +374,6 @@ static asmop *newAsmop (short type)
     return aop;
 }
 
-static void genSetDPTR(int n)
-{
-    if (!n)
-    {
-        pic16_emitcode(";", "Select standard DPTR");
-        pic16_emitcode("mov", "dps, #0x00");
-    }
-    else
-    {
-        pic16_emitcode(";", "Select alternate DPTR");
-        pic16_emitcode("mov", "dps, #0x01");
-    }
-}
-
 /*-----------------------------------------------------------------*/
 /* resolveIfx - converts an iCode ifx into a form more useful for  */
 /*              generating code                                    */
@@ -565,10 +381,10 @@ static void genSetDPTR(int n)
 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
 {
   FENTRY2;
-  
+
 //  DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
 
-  if(!resIfx) 
+  if(!resIfx)
     return;
 
 
@@ -580,7 +396,7 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
 
 #if 1
     DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
-                       __FUNCTION__,__LINE__,resIfx->lbl->key);
+                        __FUNCTION__,__LINE__,resIfx->lbl->key);
 #endif
 
   } else {
@@ -592,11 +408,11 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
     }
 
 #if 1
-    if(IC_TRUE(ifx)) 
+    if(IC_TRUE(ifx))
       DEBUGpic16_emitcode("; +++","ifx true is non-null");
     else
       DEBUGpic16_emitcode("; +++","ifx true is null");
-    if(IC_FALSE(ifx)) 
+    if(IC_FALSE(ifx))
       DEBUGpic16_emitcode("; +++","ifx false is non-null");
     else
       DEBUGpic16_emitcode("; +++","ifx false is null");
@@ -628,14 +444,14 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     memmap *space= SPEC_OCLS(sym->etype);
 
     FENTRY2;
-    
-    _G.resDirect = 0;  /* clear flag that instructs the result is loaded directly from aopForSym */
-    
+
+    _G.resDirect = 0;   /* clear flag that instructs the result is loaded directly from aopForSym */
+
 //    sym = OP_SYMBOL(op);
 
     /* if already has one */
     if (sym->aop) {
-           DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
+            DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
         return sym->aop;
     }
 
@@ -643,7 +459,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     /* if symbol was initially placed onStack then we must re-place it
      * to direct memory, since pic16 does not have a specific stack */
     if(sym->onStack) {
-       fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
+        fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
     }
 #endif
 
@@ -656,26 +472,26 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
         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) );
+        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)
+    /* space we need to assign either r0 or r1 to it   */
+    if (sym->onStack)   // || sym->iaccess)
     {
       pCodeOp *pcop[4];
       int i;
-      
-       DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
-               __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
-       
+
+        DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
+                __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
+
         /* acquire a temporary register -- it is saved in function */
 
         sym->aop = aop = newAsmop(AOP_STA);
@@ -683,57 +499,75 @@ 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 */
+            _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 {
+//                debugf3("symbol `%s' level = %d / %d\n", sym->name, ic->level, ic->seq);
           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);
-       
-       if(_G.accInUse) {
-               pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
-       }
-       
-       for(i=0;i<aop->size;i++) {
-
-         /* initialise for stack access via frame pointer */
-          // operands on stack are accessible via "FSR2 + index" with index
+        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) );
+        }
+
+        for(i=0;i<aop->size;i++) {
+
+          /* initialise for stack access via frame pointer */
+          // operands on stack are accessible via "{FRAME POINTER} + index" with index
           // starting at 2 for arguments and growing from 0 downwards for
           // local variables (index == 0 is not assigned so we add one here)
-         {
-           int soffs = sym->stack;
-           if (soffs <= 0) {
-             assert (soffs < 0);
-             soffs++;
-           } // if
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
-           pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                           pic16_popCopyReg( pic16_frame_plusw ), pcop[i]));
-         }
-       }
-       
-       if(_G.accInUse) {
-               pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
-       }
-       
-       return (aop);
+          {
+            int soffs = sym->stack;
+            if (soffs <= 0) {
+              assert (soffs < 0);
+              soffs++;
+            } // if
+
+            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]));
+            }
+          }
+        }
+
+        if(_G.accInUse) {
+                pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
+        }
+
+        return (aop);
 #endif
 
 #if 0
-        /* now assign the address of the variable to 
+        /* now assign the address of the variable to
         the pointer register */
         if (aop->type != AOP_STK) {
 
@@ -744,8 +578,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
                     pic16_emitcode("mov","a,_bp");
                     pic16_emitcode("add","a,#0x%02x",
                              ((sym->stack < 0) ?
-                             ((char)(sym->stack - _G.nRegsSaved )) :
-                             ((char)sym->stack)) & 0xff);
+                              ((char)(sym->stack - _G.nRegsSaved )) :
+                              ((char)sym->stack)) & 0xff);
                     pic16_emitcode("mov","%s,a",
                              aop->aopu.aop_ptr->name);
 
@@ -764,49 +598,15 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     }
 #endif
 
-#if 0
-    if (sym->onStack && options.stack10bit)
-    {
-        /* It's on the 10 bit stack, which is located in
-         * far data space.
-         */
-         
-      //DEBUGpic16_emitcode(";","%d",__LINE__);
-
-        if ( _G.accInUse )
-               pic16_emitcode("push","acc");
-
-        pic16_emitcode("mov","a,_bp");
-        pic16_emitcode("add","a,#0x%02x",
-                 ((sym->stack < 0) ?
-                   ((char)(sym->stack - _G.nRegsSaved )) :
-                   ((char)sym->stack)) & 0xff);
-        
-        genSetDPTR(1);
-        pic16_emitcode ("mov","dpx1,#0x40");
-        pic16_emitcode ("mov","dph1,#0x00");
-        pic16_emitcode ("mov","dpl1, a");
-        genSetDPTR(0);
-       
-        if ( _G.accInUse )
-            pic16_emitcode("pop","acc");
-            
-        sym->aop = aop = newAsmop(AOP_DPTR2);
-       aop->size = getSize(sym->type); 
-       return aop;
-    }
-#endif
-
 #if 1
     /* special case for a function */
-    if (IS_FUNC(sym->type)) {   
+    if (IS_FUNC(sym->type)) {
         sym->aop = aop = newAsmop(AOP_PCODE);
-        //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
-       aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
-       PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
-       PCOI(aop->aopu.pcop)->index = 0;
-        aop->size = FPTRSIZE; 
-       DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+        aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
+        PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+        PCOI(aop->aopu.pcop)->index = 0;
+        aop->size = FPTRSIZE;
+        DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
         return aop;
     }
 #endif
@@ -819,26 +619,33 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
         sym->aop = aop = newAsmop (AOP_CRY);
         aop->aopu.aop_dir = sym->rname ;
         aop->size = getSize(sym->type);
-       DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+        DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
         return aop;
     }
     /* if it is in direct space */
     if (IN_DIRSPACE(space)) {
-        sym->aop = aop = newAsmop (AOP_DIR);
-        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;
-    }
-
+                if(!strcmp(sym->rname, "_WREG")) {
+                        sym->aop = aop = newAsmop (AOP_ACC);
+                        aop->size = getSize(sym->type);         /* should always be 1 */
+                        assert(aop->size == 1);
+                        DEBUGpic16_emitcode(";","%d sym->rname (AOP_ACC) = %s, size = %d",__LINE__,sym->rname,aop->size);
+                        return (aop);
+                } else {
+                        sym->aop = aop = newAsmop (AOP_DIR);
+                aop->aopu.aop_dir = sym->rname ;
+            aop->size = getSize(sym->type);
+                DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size);
+                        pic16_allocDirReg( IC_LEFT(ic) );
+                        return (aop);
+                }
+        }
 
     if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
         sym->aop = aop = newAsmop (AOP_DIR);
         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) );
+        DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+        pic16_allocDirReg( IC_LEFT(ic) );
         return aop;
     }
 
@@ -847,39 +654,39 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     sym->aop = aop = newAsmop(AOP_PCODE);
 
 /* change the next if to 1 to revert to good old immediate code */
-       if(IN_CODESPACE(space)) {
-               aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
-               PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
-               PCOI(aop->aopu.pcop)->index = 0;
-       } else {
-               /* try to allocate via direct register */
-               aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
-//             aop->size = getSize( sym->type );
-       }
-
-       DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
-               __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+        if(IN_CODESPACE(space)) {
+                aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
+                PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+                PCOI(aop->aopu.pcop)->index = 0;
+        } else {
+                /* try to allocate via direct register */
+                aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
+//              aop->size = getSize( sym->type );
+        }
+
+        DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
+                __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
 
 #if 0
-       if(!pic16_allocDirReg (IC_LEFT(ic)))
-               return NULL;
+        if(!pic16_allocDirReg (IC_LEFT(ic)))
+                return NULL;
 #endif
 
-       if(IN_DIRSPACE( space ))
-               aop->size = PTRSIZE;
-       else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
-               aop->size = FPTRSIZE;
-       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;
+        if(IN_DIRSPACE( space ))
+                aop->size = PTRSIZE;
+        else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
+                aop->size = FPTRSIZE;
+        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 );
-       }
+                assert( 0 );
+        }
 
     DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
 
@@ -887,13 +694,13 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     if (IN_CODESPACE(space))
         aop->code = 1;
 
-    return aop;     
+    return aop;
 }
 
 /*-----------------------------------------------------------------*/
 /* aopForRemat - rematerialzes an object                           */
 /*-----------------------------------------------------------------*/
-static asmop *aopForRemat (operand *op) // x symbol *sym)
+static asmop *aopForRemat (operand *op, bool result) // x symbol *sym)
 {
   symbol *sym = OP_SYMBOL(op);
   operand *refop;
@@ -904,76 +711,79 @@ static asmop *aopForRemat (operand *op) // x symbol *sym)
   int viaimmd=0;
 
     FENTRY2;
-    
-       ic = sym->rematiCode;
-
-       if(IS_OP_POINTER(op)) {
-               DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
-       }
-
-       for (;;) {
-               oldic = ic;
-
-//             pic16_emitpcomment("ic: %s\n", printILine(ic));
-       
-               if (ic->op == '+') {
-                       val += (int) operandLitValue(IC_RIGHT(ic));
-               } else if (ic->op == '-') {
-                       val -= (int) operandLitValue(IC_RIGHT(ic));
-               } else
-                       break;
-               
-               ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
-       }
-
-       offset = OP_SYMBOL(IC_LEFT(ic))->offset;
-       refop = IC_LEFT(ic);
-
-       if(!op->isaddr)viaimmd++; else viaimmd=0;
-               
+
+        ic = sym->rematiCode;
+
+        if(IS_OP_POINTER(op)) {
+                DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
+        }
+
+//    if(!result)               /* fixme-vr */
+        for (;;) {
+                oldic = ic;
+
+//              chat *iLine = printILine(ic);
+//              pic16_emitpcomment("ic: %s\n", iLine);
+//              dbuf_free(iLine);
+
+                if (ic->op == '+') {
+                        val += (int) operandLitValue(IC_RIGHT(ic));
+                } else if (ic->op == '-') {
+                        val -= (int) operandLitValue(IC_RIGHT(ic));
+                } else
+                        break;
+
+                ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+        }
+
+        offset = OP_SYMBOL(IC_LEFT(ic))->offset;
+        refop = IC_LEFT(ic);
+
+        if(!op->isaddr)viaimmd++; else viaimmd=0;
+
 /* set the following if to 1 to revert to good old immediate code */
-       if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
-               || viaimmd) {
+        if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
+                || viaimmd) {
 
-               DEBUGpic16_emitcode(";", "%s:%d immediate, size: %d", __FILE__, __LINE__, getSize( sym->type ));
+                DEBUGpic16_emitcode(";", "%s:%d immediate, size: %d", __FILE__, __LINE__, getSize( sym->type ));
 
-               aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
+                aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
 
 #if 0
-               PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
+                PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
 #else
-               PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
+                PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
 #endif
 
-               PCOI(aop->aopu.pcop)->index = val;
-               
-               aop->size = getSize( sym->type );
-       } else {
-               DEBUGpic16_emitcode(";", "%s:%d dir size: %d", __FILE__, __LINE__,  getSize( OP_SYMBOL( IC_LEFT(ic))->type));
+                PCOI(aop->aopu.pcop)->index = val;
+
+                aop->size = getSize( sym->type );
+        } else {
+                DEBUGpic16_emitcode(";", "%s:%d dir size: %d", __FILE__, __LINE__,  getSize( OP_SYMBOL( IC_LEFT(ic))->type));
 
-               aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
-                               getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
+                aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
+                                getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
 
-               aop->size = getSize( OP_SYMBOL( IC_LEFT(ic))->type );
-       }
+                aop->size = getSize( OP_SYMBOL( IC_LEFT(ic))->type );
+        }
 
 
-       DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
-               __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
+        DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
+                __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
 #if 0
-               val, IS_PTR_CONST(operandType(op)));
+                val, IS_PTR_CONST(operandType(op)));
 #else
-               val, IS_CODEPTR(operandType(op)));
+                val, IS_CODEPTR(operandType(op)));
 #endif
 
-//     DEBUGpic16_emitcode(";","aop type  %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
+//      DEBUGpic16_emitcode(";","aop type  %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
 
-       pic16_allocDirReg (IC_LEFT(ic));
+        pic16_allocDirReg (IC_LEFT(ic));
 
-       if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
-               aop->code = 1;
+        if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
+                aop->code = 1;
 
-  return aop;        
+  return aop;
 }
 
 #if 0
@@ -984,7 +794,7 @@ static int aopIdx (asmop *aop, int offset)
 
   if(aop->type !=  AOP_REG)
     return -2;
-       
+
   return aop->aopu.aop_reg[offset]->rIdx;
 
 }
@@ -1042,8 +852,8 @@ static bool operandsEqu ( operand *op1, operand *op2)
     /* if both are itemps & one is spilt
        and the other is not then false */
     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
-       sym1->isspilt != sym2->isspilt )
-       return FALSE ;
+        sym1->isspilt != sym2->isspilt )
+        return FALSE ;
 
     /* if they are the same */
     if (sym1 == sym2)
@@ -1055,17 +865,17 @@ static bool operandsEqu ( operand *op1, operand *op2)
 
 
     /* if left is a tmp & right is not */
-    if (IS_ITEMP(op1)  && 
+    if (IS_ITEMP(op1)  &&
         !IS_ITEMP(op2) &&
         sym1->isspilt  &&
-        (sym1->usl.spillLoc == sym2))
+        (SYM_SPIL_LOC(sym1) == sym2))
         return TRUE;
 
-    if (IS_ITEMP(op2)  && 
+    if (IS_ITEMP(op2)  &&
         !IS_ITEMP(op1) &&
         sym2->isspilt  &&
-       sym1->level > 0 &&
-        (sym2->usl.spillLoc == sym1))
+        sym1->level > 0 &&
+        (SYM_SPIL_LOC(sym2) == sym1))
         return TRUE ;
 
     return FALSE ;
@@ -1082,7 +892,7 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
         return TRUE ;
 
     DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
-               pic16_AopType(aop1->type), pic16_AopType(aop2->type));
+                pic16_AopType(aop1->type), pic16_AopType(aop2->type));
 
     if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
 
@@ -1109,13 +919,13 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
 bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset)
 {
     DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__,
-               pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
+                pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
 
     if(aop1 == aop2)return TRUE;
     if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE;
-      
+
       if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE;
-    
+
   return TRUE;
 }
 
@@ -1149,7 +959,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
 #else
       if(IS_CODEPTR(type))
 #endif
-       DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
+        DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
     }
 
     /* if already has a asmop then continue */
@@ -1164,8 +974,8 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
     }
 
     /* if this is a true symbol */
-    if (IS_TRUE_SYMOP(op)) {    
-       DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
+    if (IS_TRUE_SYMOP(op)) {
+        DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
       op->aop = aopForSym(ic, op, result);
       return ;
     }
@@ -1174,8 +984,8 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
     only four choices :
     a) register
     b) spillocation
-    c) rematerialize 
-    d) conditional   
+    c) rematerialize
+    d) conditional
     e) can be a return use only */
 
     sym = OP_SYMBOL(op);
@@ -1189,81 +999,90 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
     }
 
     /* if it is spilt then two situations
-    a) is rematerialize 
+    a) is rematerialize
     b) has a spill location */
     if (sym->isspilt || sym->nRegs == 0) {
 
-//      debugf2("%s:%d symbol %s\tisspilt: %d\tnRegs: %d\n", sym->isspilt, sym->nRegs);
+//      debugf3("symbol %s\tisspilt: %d\tnRegs: %d\n", sym->rname, sym->isspilt, sym->nRegs);
       DEBUGpic16_emitcode(";","%d",__LINE__);
         /* rematerialize it NOW */
         if (sym->remat) {
 
-            sym->aop = op->aop = aop = aopForRemat (op);
-//            aop->size = getSize(sym->type);
-//         DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
+            sym->aop = op->aop = aop = aopForRemat (op, result);
             return;
         }
 
 #if 1
-       if (sym->accuse) {
-           int i;
+        if (sym->accuse) {
+            int i;
             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
             aop->size = getSize(sym->type);
             for ( i = 0 ; i < 1 ; i++ ) {
-               aop->aopu.aop_str[i] = accUse[i];
-//                aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
-           }
-           fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
-           DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
-            return;  
-       }
+                aop->aopu.aop_str[i] = accUse[i];
+//                aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, SYM_SPIL_LOC(sym)->offset);
+            }
+            fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
+            DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
+            return;
+        }
 #endif
 
 #if 1
-        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);
-         //pic16_allocDirReg (IC_LEFT(ic));
-         aop->size = getSize(sym->type);
-         */
-
-         unsigned i;
-
-         aop = op->aop = sym->aop = newAsmop(AOP_STR);
-         aop->size = getSize(sym->type);
-         for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
-           aop->aopu.aop_str[i] = fReturn[i];
-
-         DEBUGpic16_emitcode(";","%d",__LINE__);
-         return;
+        if (sym->ruonly) {
+          /*
+          sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+          aop->aopu.pcop = pic16_popGetImmd(SYM_SPIL_LOC(sym)->rname,0,SYM_SPIL_LOC(sym)->offset);
+          //pic16_allocDirReg (IC_LEFT(ic));
+          aop->size = getSize(sym->type);
+          */
+
+          unsigned i;
+
+          aop = op->aop = sym->aop = newAsmop(AOP_REG);
+          aop->size = getSize(sym->type);
+          for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
+            aop->aopu.aop_reg[i] = PCOR(pic16_popRegFromIdx( fReturnIdx[i] ))->r;
+
+          DEBUGpic16_emitcode(";","%d",__LINE__);
+          return;
         }
 #endif
         /* else spill location  */
-       if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
-           /* force a new aop if sizes differ */
-           sym->usl.spillLoc->aop = NULL;
-       }
+        if (SYM_SPIL_LOC(sym) && getSize(sym->type) != getSize(SYM_SPIL_LOC(sym)->type)) {
+            /* force a new aop if sizes differ */
+            SYM_SPIL_LOC(sym)->aop = NULL;
+        }
 
 #if 0
-       DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
-                           __FUNCTION__,__LINE__,
-                           sym->usl.spillLoc->rname,
-                           sym->rname, sym->usl.spillLoc->offset);
+        DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
+                            __FUNCTION__,__LINE__,
+                            SYM_SPIL_LOC(sym)->rname,
+                            sym->rname, SYM_SPIL_LOC(sym)->offset);
 #endif
 
-       sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
-       //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
-       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__);
-         DEBUGpic16_emitcode (";","%s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
-         assert (getSize(sym->type) <= 1);
-         aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);//pic16_popRegFromString("_WREG", getSize(sym->type), 0, op);
-       }
+        //aop->aopu.pcop = pic16_popGetImmd(SYM_SPIL_LOC(sym)->rname,0,SYM_SPIL_LOC(sym)->offset);
+        if (SYM_SPIL_LOC(sym) && SYM_SPIL_LOC(sym)->rname) {
+          sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+          aop->aopu.pcop = pic16_popRegFromString(SYM_SPIL_LOC(sym)->rname,
+                                                  getSize(sym->type),
+                                                  SYM_SPIL_LOC(sym)->offset, op);
+        } else if (getSize(sym->type) <= 1) {
+          //fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK (size:%u)!\n", __FUNCTION__, __LINE__, getSize(sym->type));
+          pic16_emitpcomment (";!!! %s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
+          assert (getSize(sym->type) <= 1);
+          sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+          aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);
+        } else {
+          /* We need some kind of dummy area for getSize(sym->type) byte,
+           * use WREG for all storage locations.
+           * XXX: This only works if we are implementing a `dummy read',
+           *      the stored value will not be retrievable...
+           *      See #1503234 for a case requiring this. */
+          sym->aop = op->aop = aop = newAsmop(AOP_REG);
+          aop->size = getSize(sym->type);
+          for ( i = 0 ; i < aop->size ;i++)
+            aop->aopu.aop_reg[i] = pic16_pc_wreg.r;
+        }
         aop->size = getSize(sym->type);
 
         return;
@@ -1272,11 +1091,11 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
     {
       sym_link *type = operandType(op);
 #if 0
-      if(IS_PTR_CONST(type)) 
+      if(IS_PTR_CONST(type))
 #else
-      if(IS_CODEPTR(type)) 
+      if(IS_CODEPTR(type))
 #endif
-       DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
+        DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
     }
 
     /* must be in a register */
@@ -1291,62 +1110,24 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
 /* pic16_freeAsmop - free up the asmop given to an operand               */
 /*----------------------------------------------------------------*/
 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
-{   
+{
     asmop *aop ;
 
     if (!op)
         aop = aaop;
-    else 
+    else
         aop = op->aop;
 
     if (!aop)
         return ;
 
     if (aop->freed)
-        goto dealloc; 
+        goto dealloc;
 
     aop->freed = 1;
 
-    /* depending on the asmop type only three cases need work AOP_RO
-       , AOP_R1 && AOP_STK */
 #if 1
     switch (aop->type) {
-        case AOP_FSR0 :
-            if (_G.fsr0Pushed ) {
-                if (pop) {
-                   pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
-                   pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
-//                    pic16_emitcode ("pop","ar0");
-                    _G.fsr0Pushed--;
-                }
-            }
-            bitVectUnSetBit(ic->rUsed,IDX_FSR0);
-            break;
-
-        case AOP_FSR2 :
-            bitVectUnSetBit(ic->rUsed,IDX_FSR2);
-            break;
-
-        case AOP_R0 :
-            if (_G.r0Pushed ) {
-                if (pop) {
-                    pic16_emitcode ("pop","ar0");     
-                    _G.r0Pushed--;
-                }
-            }
-            bitVectUnSetBit(ic->rUsed,R0_IDX);
-            break;
-
-        case AOP_R1 :
-            if (_G.r1Pushed ) {
-                if (pop) {
-                    pic16_emitcode ("pop","ar1");
-                    _G.r1Pushed--;
-                }
-            }
-            bitVectUnSetBit(ic->rUsed,R1_IDX);          
-            break;
-
         case AOP_STA:
           {
             int i;
@@ -1363,18 +1144,34 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
                 } // if
                 if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
                 for(i=0;i<aop->size;i++) {
-                 /* initialise for stack access via frame pointer */
-                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
-                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                  /* 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_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);
+//                      pic16_popReleaseTempReg(aop->aopu.stk.pop[i], 0);
+                  }
+                }
+
+                if (_G.sregsAllocSet) {
+                  regs *sr;
+
+                    _G.sregsAllocSet = reverseSet( _G.sregsAllocSet );
+                    for(sr=setFirstItem(_G.sregsAllocSet) ; sr; sr=setFirstItem(_G.sregsAllocSet)) {
+                      pic16_poppCodeOp( pic16_popRegFromIdx( sr->rIdx ) );
+                      deleteSetItem( &_G.sregsAllocSet, sr );
+                    }
+                }
               }
               _G.resDirect = 0;
           }
@@ -1382,22 +1179,22 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
 #if 0
         case AOP_STK :
         {
-            int sz = aop->size;    
+            int sz = aop->size;
             int stk = aop->aopu.aop_stk + aop->size;
             bitVectUnSetBit(ic->rUsed,R0_IDX);
-            bitVectUnSetBit(ic->rUsed,R1_IDX);          
+            bitVectUnSetBit(ic->rUsed,R1_IDX);
 
             getFreePtr(ic,&aop,FALSE);
-            
+
             if (options.stack10bit)
             {
                 /* I'm not sure what to do here yet... */
                 /* #STUB */
-               fprintf(stderr, 
-                       "*** Warning: probably generating bad code for "
-                       "10 bit stack mode.\n");
+                fprintf(stderr,
+                        "*** Warning: probably generating bad code for "
+                        "10 bit stack mode.\n");
             }
-            
+
             if (stk) {
                 pic16_emitcode ("mov","a,_bp");
                 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
@@ -1422,7 +1219,7 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
             if (_G.r1Pushed) {
                 pic16_emitcode("pop","ar1");
                 _G.r1Pushed--;
-            }       
+            }
         }
 #endif
 
@@ -1434,9 +1231,9 @@ dealloc:
     if (op ) {
         op->aop = NULL;
         if (IS_SYMOP(op)) {
-            OP_SYMBOL(op)->aop = NULL;    
+            OP_SYMBOL(op)->aop = NULL;
             /* if the symbol has a spill */
-           if (SPIL_LOC(op))
+            if (SPIL_LOC(op))
                 SPIL_LOC(op)->aop = NULL;
         }
     }
@@ -1459,143 +1256,94 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
 
     /* depending on type */
     switch (aop->type) {
-
-    case AOP_FSR0:
-    case AOP_FSR2:
-      sprintf(s, "%s", aop->aopu.aop_ptr->name);
-      rs = Safe_calloc(1, strlen(s)+1);
-      strcpy(rs, s);
-      return (rs);
-      
-#if 0
-      /* if we need to increment it */
-      while (offset > aop->coff)
-        {
-          emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
-          aop->coff++;
-        }
-
-      while (offset < aop->coff)
-        {
-          emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
-          aop->coff--;
-        }
-      aop->coff = offset;
-      if (aop->paged)
-        {
-          emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
-          return (dname ? "acc" : "a");
-        }
-      sprintf (s, "@%s", aop->aopu.aop_ptr->name);
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
-#endif
-
-       
-    case AOP_IMMD:
-       if (bit16) 
-           sprintf (s,"%s",aop->aopu.aop_immd);
-       else
-           if (offset) 
-               sprintf(s,"(%s >> %d)",
-                       aop->aopu.aop_immd,
-                       offset*8);
-           else
-               sprintf(s,"%s",
-                       aop->aopu.aop_immd);
-       DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
-       rs = Safe_calloc(1,strlen(s)+1);
-       strcpy(rs,s);   
-       return rs;
-       
     case AOP_DIR:
       if (offset) {
-       sprintf(s,"(%s + %d)",
-               aop->aopu.aop_dir,
-               offset);
-       DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
+        sprintf(s,"(%s + %d)",
+                aop->aopu.aop_dir,
+                offset);
+        DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
       } else
-           sprintf(s,"%s",aop->aopu.aop_dir);
-       rs = Safe_calloc(1,strlen(s)+1);
-       strcpy(rs,s);   
-       return rs;
-       
+            sprintf(s,"%s",aop->aopu.aop_dir);
+        rs = Safe_calloc(1,strlen(s)+1);
+        strcpy(rs,s);
+        return rs;
+
     case AOP_REG:
-      //if (dname) 
-      //    return aop->aopu.aop_reg[offset]->dname;
-      //else
-           return aop->aopu.aop_reg[offset]->name;
-       
+      return aop->aopu.aop_reg[offset]->name;
+
     case AOP_CRY:
-      //pic16_emitcode(";","%d",__LINE__);
       return aop->aopu.aop_dir;
-       
+
     case AOP_ACC:
         DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
 //        fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
 //        assert( 0 );
-//     return aop->aopu.aop_str[offset];       //->"AOP_accumulator_bug";
-       rs = Safe_strdup("WREG");
-       return (rs);
+//      return aop->aopu.aop_str[offset];       //->"AOP_accumulator_bug";
+        rs = Safe_strdup("WREG");
+        return (rs);
 
     case AOP_LIT:
-       sprintf(s,"0X%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
-       rs = Safe_calloc(1,strlen(s)+1);
-       strcpy(rs,s);   
-       return rs;
-       
+        sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
+        rs = Safe_calloc(1,strlen(s)+1);
+        strcpy(rs,s);
+        return rs;
+
     case AOP_STR:
-       aop->coff = offset ;
-       if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
-           dname)
-           return "acc";
+        aop->coff = offset ;
+
+//      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];
-       
+
+        return aop->aopu.aop_str[offset];
+
     case AOP_PCODE:
       {
-       pCodeOp *pcop = aop->aopu.pcop;
-       DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
-       if(pcop->name) {
-         DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
-         //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
-         if (offset) {
-           sprintf(s,"(%s + %d)", pcop->name, offset);
-         } else {
-           sprintf(s,"%s", pcop->name);
-         }
-       } else
-         sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
+        pCodeOp *pcop = aop->aopu.pcop;
+        DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
+        if(pcop->name) {
+          DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
+          //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
+          if (offset) {
+            sprintf(s,"(%s + %d)", pic16_get_op (pcop, NULL, 0), offset);
+          } else {
+            sprintf(s,"%s", pic16_get_op (pcop, NULL, 0));
+          }
+        } else
+          sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
 
       }
       rs = Safe_calloc(1,strlen(s)+1);
-      strcpy(rs,s);   
+      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);
+        sprintf(s,"(%s + %d)",
+                aop->aopu.aop_dir,
+                offset);
       } else
-           sprintf(s,"%s",aop->aopu.aop_dir);
+            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);   
+      strcpy(rs,s);
       return rs;
 #endif
 
     case AOP_STA:
         rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name);
         return (rs);
-        
+
     case AOP_STK:
 //        pCodeOp *pcop = aop->aop
-       break;
+        break;
 
     }
 
@@ -1618,23 +1366,23 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
  * lock=0 to allocate registers for stack use. lock=1 will emit a warning
  * to inform the compiler developer about a possible bug. This is an internal
  * feature for developing the compiler -- VR */
+
 int _TempReg_lock = 0;
 /*-----------------------------------------------------------------*/
 /* pic16_popGetTempReg - create a new temporary pCodeOp                  */
 /*-----------------------------------------------------------------*/
 pCodeOp *pic16_popGetTempReg(int lock)
 {
-  pCodeOp *pcop;
+  pCodeOp *pcop=NULL;
   symbol *cfunc;
 
 //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if(_TempReg_lock) {
 //      werror(W_POSSBUG2, __FILE__, __LINE__);
     }
-    
+
     _TempReg_lock += lock;
-    
+
     cfunc = currFunc;
     currFunc = NULL;
 
@@ -1653,13 +1401,15 @@ pCodeOp *pic16_popGetTempReg(int lock)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic16_popGetTempRegCond - create a new temporary pCodeOp, but   */
-/*                            don't save if inside v               */
+/* pic16_popGetTempRegCond - create a new temporary pCodeOp which  */
+/*                           is not part of f, but don't save if   */
+/*                           inside v                              */
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
+pCodeOp *pic16_popGetTempRegCond(bitVect *f, bitVect *v, int lock)
 {
-  pCodeOp *pcop;
+  pCodeOp *pcop=NULL;
   symbol *cfunc;
+  int i;
 
 //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -1672,15 +1422,58 @@ pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
     cfunc = currFunc;
     currFunc = NULL;
 
-    pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
-    if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
-      PCOR(pcop)->r->wasUsed=1;
-      PCOR(pcop)->r->isFree=0;
+    i = bitVectFirstBit(f);
+    while(i < 128) {
 
-      if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) {
-      /* push value on stack */
-        pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+      /* bypass registers that are used by function */
+      if(!bitVectBitValue(f, i)) {
+
+        /* bypass registers that are already allocated for stack access */
+        if(!bitVectBitValue(v, i))  {
+
+//          debugf("getting register rIdx = %d\n", i);
+          /* ok, get the operand */
+          pcop = pic16_newpCodeOpReg( i );
+
+          /* should never by NULL */
+          assert( pcop != NULL );
+
+
+          /* sanity check */
+          if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
+            int found=0;
+
+              PCOR(pcop)->r->wasUsed=1;
+              PCOR(pcop)->r->isFree=0;
+
+
+              {
+                regs *sr;
+
+                  for(sr=setFirstItem(_G.sregsAllocSet);sr;sr=setNextItem(_G.sregsAllocSet)) {
+
+                    if(sr->rIdx == PCOR(pcop)->r->rIdx) {
+                      /* already used in previous steps, break */
+                      found=1;
+                      break;
+                    }
+                  }
+              }
+
+              /* caller takes care of the following */
+//              bitVectSetBit(v, i);
+
+              if(!found) {
+                /* push value on stack */
+                pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+                addSet(&_G.sregsAllocSet, PCOR(pcop)->r);
+              }
+
+            break;
+          }
+        }
       }
+      i++;
     }
 
     currFunc = cfunc;
@@ -1700,13 +1493,14 @@ 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) );
   }
 }
 /*-----------------------------------------------------------------*/
 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL             */
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_popGetLabel(unsigned int key)
+pCodeOp *pic16_popGetLabel(int key)
 {
 
   DEBUGpic16_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
@@ -1725,17 +1519,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);
 
@@ -1750,6 +1547,12 @@ pCodeOp *pic16_popGetLit(int lit)
   return pic16_newpCodeOpLit(lit);
 }
 
+/* Allow for 12 bit literals (LFSR x, <here!>). */
+pCodeOp *pic16_popGetLit12(int lit)
+{
+  return pic16_newpCodeOpLit12(lit);
+}
+
 /*-----------------------------------------------------------------*/
 /* pic16_popGetLit2 - asm operator to pcode operator conversion    */
 /*-----------------------------------------------------------------*/
@@ -1807,18 +1610,19 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand
   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
 
   PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
+//  PCOR(pcop)->r->wasUsed = 1;
 
   /* make sure that register doesn't exist,
    * and operand isn't NULL
    * and symbol isn't in codespace (codespace symbols are handled elsewhere) */
-  if((PCOR(pcop)->r == NULL) 
+  if((PCOR(pcop)->r == NULL)
     && (op)
     && !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
-//     fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
-//             __FUNCTION__, __LINE__, str, size, offset);
+//      fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
+//              __FUNCTION__, __LINE__, str, size, offset);
 
     PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
-    fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
+    //fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
 
   }
   PCOR(pcop)->instance = offset;
@@ -1830,16 +1634,19 @@ static pCodeOp *pic16_popRegFromIdx(int rIdx)
 {
   pCodeOp *pcop;
 
-//     DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
+//      DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
+//      fprintf(stderr, "%s:%d rIdx = 0x%0x\n", __FUNCTION__, __LINE__, rIdx);
 
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       PCOR(pcop)->rIdx = rIdx;
-       PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+        pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+        PCOR(pcop)->rIdx = rIdx;
+        PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+        if(!PCOR(pcop)->r)
+                PCOR(pcop)->r = pic16_allocWithIdx(rIdx);
 
-       PCOR(pcop)->r->isFree = 0;
-       PCOR(pcop)->r->wasUsed = 1;
+        PCOR(pcop)->r->isFree = 0;
+        PCOR(pcop)->r->wasUsed = 1;
 
-       pcop->type = PCOR(pcop)->r->pc_type;
+        pcop->type = PCOR(pcop)->r->pc_type;
 
   return pcop;
 }
@@ -1850,17 +1657,8 @@ static pCodeOp *pic16_popRegFromIdx(int rIdx)
 /*---------------------------------------------------------------------------------*/
 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
 {
-  pCodeOpReg2 *pcop2;
-  pCodeOp *temp;
-  
-       pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
-
-       /* comment the following check, so errors to throw up */
-//     if(!pcop2)return NULL;
-
-       temp = pic16_popGet(aop_dst, offset);
-       pcop2->pcop2 = temp;
-       
+  pCodeOp2 *pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(
+        pic16_popGet(aop_src, offset), pic16_popGet(aop_dst, offset));
   return PCOP(pcop2);
 }
 
@@ -1872,32 +1670,19 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
 /*--------------------------------------------------------------------------------.-*/
 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
 {
-  pCodeOpReg2 *pcop2;
-       pcop2 = (pCodeOpReg2 *)src;
-       pcop2->pcop2 = dst;
-       
-       return PCOP(pcop2);
+  pCodeOp2 *pcop2;
+  pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(src, dst);
+  return PCOP(pcop2);
 }
 
-
-
 /*---------------------------------------------------------------------------------*/
 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with      */
 /*                     movff instruction                                           */
 /*---------------------------------------------------------------------------------*/
 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
 {
-  pCodeOpReg2 *pcop2;
-
-       if(!noalloc) {
-               pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
-               pcop2->pcop2 = pic16_popCopyReg(dst);
-       } else {
-               /* the pCodeOp may be already allocated */
-               pcop2 = (pCodeOpReg2 *)(src);
-               pcop2->pcop2 = (pCodeOp *)(dst);
-       }
+  pCodeOp2 *pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(
+        pic16_popCopyReg(src), pic16_popCopyReg(dst) );
 
   return PCOP(pcop2);
 }
@@ -1908,13 +1693,13 @@ pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
 /*-----------------------------------------------------------------*/
 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 {
-  //char *s = buffer ;
-  char *rs;
+//  char *s = buffer ;
+//  char *rs;
   pCodeOp *pcop;
 
     FENTRY2;
-    /* offset is greater than
-    size then zero */
+
+      /* offset is greater than size then zero */
 
 //    if (offset > (aop->size - 1) &&
 //        aop->type != AOP_LIT)
@@ -1922,71 +1707,42 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 
     /* depending on type */
     switch (aop->type) {
-       
-    case AOP_R0:
-    case AOP_R1:
-    case AOP_DPTR:
-    case AOP_DPTR2:
-        DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
-        fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
-       assert( 0 );
-       return NULL;
-
-
-    case AOP_FSR0:
-    case AOP_FSR2:
-      pcop = Safe_calloc(1, sizeof(pCodeOpReg));
-      PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2;    /* access PLUSW register */
-      PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
-      PCOR(pcop)->r->wasUsed = 1;
-      PCOR(pcop)->r->isFree = 0;
-      
-      PCOR(pcop)->instance = offset;
-      pcop->type = PCOR(pcop)->r->pc_type;
-      return (pcop);
+                case AOP_STA:
+                        /* pCodeOp is already allocated from aopForSym */
+                        DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
+                        pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
+                        return (pcop);
 
-    case AOP_IMMD:
-      DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
-      return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
+                case AOP_ACC:
+                        {
+                          int rIdx = IDX_WREG;          //aop->aopu.aop_reg[offset]->rIdx;
 
-    case AOP_STA:
-      /* pCodeOp is already allocated from aopForSym */
-        DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
-        pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
-          
-      return (pcop);
-      
-    case AOP_ACC:
-      {
-       int rIdx = IDX_WREG;            //aop->aopu.aop_reg[offset]->rIdx;
+                                fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
 
-       fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
+                                DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
 
-       DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
-       
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       PCOR(pcop)->rIdx = rIdx;
-       PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
-       PCOR(pcop)->r->wasUsed=1;
-       PCOR(pcop)->r->isFree=0;
+                                pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+                                PCOR(pcop)->rIdx = rIdx;
+                                PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
+                                PCOR(pcop)->r->wasUsed=1;
+                                PCOR(pcop)->r->isFree=0;
 
-       PCOR(pcop)->instance = offset;
-       pcop->type = PCOR(pcop)->r->pc_type;
-//     rs = aop->aopu.aop_reg[offset]->name;
-//     DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
-       return pcop;
+                                PCOR(pcop)->instance = offset;
+                                pcop->type = PCOR(pcop)->r->pc_type;
+//                              DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
+                                return pcop;
 
 
-//     return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
+//      return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
 //      return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
 
-//     assert( 0 );
-      }
-       
+//      assert( 0 );
+                        }
+
     case AOP_DIR:
-      DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
+      DEBUGpic16_emitcode(";","%d\tAOP_DIR (name = %s)", __LINE__, aop->aopu.aop_dir);
       return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
-       
+
 #if 0
     case AOP_PAGED:
       DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
@@ -1995,30 +1751,32 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 
     case AOP_REG:
       {
-       int rIdx;
-       assert (aop && aop->aopu.aop_reg[offset] != NULL);
-       rIdx = aop->aopu.aop_reg[offset]->rIdx;
-
-       DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
-       
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-//     pcop->type = PO_GPR_REGISTER;
-       PCOR(pcop)->rIdx = rIdx;
-       PCOR(pcop)->r = pic16_allocWithIdx( rIdx );     //pic16_regWithIdx(rIdx);
-       PCOR(pcop)->r->wasUsed=1;
-       PCOR(pcop)->r->isFree=0;
-
-       PCOR(pcop)->instance = offset;
-       pcop->type = PCOR(pcop)->r->pc_type;
-       
-       DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s\n", __LINE__, dumpPicOptype(pcop->type));
-       rs = aop->aopu.aop_reg[offset]->name;
-       DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs);
-       return pcop;
+        int rIdx;
+
+//      debugf2("aop = %p\toffset = %d\n", aop, offset);
+//      assert (aop && aop->aopu.aop_reg[offset] != NULL);
+        rIdx = aop->aopu.aop_reg[offset]->rIdx;
+
+        DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
+
+        pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+//      pcop->type = PO_GPR_REGISTER;
+        PCOR(pcop)->rIdx = rIdx;
+        PCOR(pcop)->r = pic16_allocWithIdx( rIdx );     //pic16_regWithIdx(rIdx);
+        PCOR(pcop)->r->wasUsed=1;
+        PCOR(pcop)->r->isFree=0;
+
+        PCOR(pcop)->instance = offset;
+        pcop->type = PCOR(pcop)->r->pc_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;
       }
 
     case AOP_CRY:
-       DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
+        DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
 
       pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
       PCOR(pcop)->instance = offset;
@@ -2026,9 +1784,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
       //if(PCOR(pcop)->r == NULL)
       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
       return pcop;
-       
+
     case AOP_LIT:
-       DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
+        DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
       return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
 
     case AOP_STR:
@@ -2047,16 +1805,18 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 
     case AOP_PCODE:
       DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
-                         __LINE__, 
-                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
+                          __LINE__,
+                          ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
       pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
       switch( aop->aopu.pcop->type ) {
         case PO_DIR: PCOR(pcop)->instance += offset; break;
         case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
-        case PO_WREG: assert (offset==0); break;
+        case PO_WREG:
+            assert (offset==0);
+            break;
         default:
-         fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type);
-          assert( 0 ); /* should never reach here */;
+          fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type);
+          assert( 0 );  /* should never reach here */;
       }
       return pcop;
     }
@@ -2088,214 +1848,139 @@ void pic16_aopPut (asmop *aop, char *s, int offset)
     switch (aop->type) {
     case AOP_DIR:
       if (offset) {
-       sprintf(d,"(%s + %d)",
-               aop->aopu.aop_dir,offset);
-       fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
+        sprintf(d,"(%s + %d)",
+                aop->aopu.aop_dir,offset);
+        fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
 
       } else
-           sprintf(d,"%s",aop->aopu.aop_dir);
-       
-       if (strcmp(d,s)) {
-         DEBUGpic16_emitcode(";","%d",__LINE__);
-         if(strcmp(s,"W"))
-           pic16_emitcode("movf","%s,w",s);
-         pic16_emitcode("movwf","%s",d);
-
-         if(strcmp(s,"W")) {
-           pic16_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
-           if(offset >= aop->size) {
-             pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
-             break;
-           } else
-             pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
-         }
-
-         pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
-
-
-       }
-       break;
-       
+            sprintf(d,"%s",aop->aopu.aop_dir);
+
+        if (strcmp(d,s)) {
+          DEBUGpic16_emitcode(";","%d",__LINE__);
+          if(strcmp(s,"W"))
+            pic16_emitcode("movf","%s,w",s);
+          pic16_emitcode("movwf","%s",d);
+
+          if(strcmp(s,"W")) {
+            pic16_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
+            if(offset >= aop->size) {
+              pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
+              break;
+            } else
+              pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
+          }
+
+          pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
+
+
+        }
+        break;
+
     case AOP_REG:
       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
-       //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
-         /*
-           if (*s == '@'           ||
-               strcmp(s,"r0") == 0 ||
-               strcmp(s,"r1") == 0 ||
-               strcmp(s,"r2") == 0 ||
-               strcmp(s,"r3") == 0 ||
-               strcmp(s,"r4") == 0 ||
-               strcmp(s,"r5") == 0 ||
-               strcmp(s,"r6") == 0 || 
-               strcmp(s,"r7") == 0 )
-               pic16_emitcode("mov","%s,%s  ; %d",
-                        aop->aopu.aop_reg[offset]->dname,s,__LINE__);
-           else
-         */
-
-         if(strcmp(s,"W")==0 )
-           pic16_emitcode("movf","%s,w  ; %d",s,__LINE__);
-
-         pic16_emitcode("movwf","%s",
-                  aop->aopu.aop_reg[offset]->name);
-
-         if(strcmp(s,zero)==0) {
-           pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
-
-         } else if(strcmp(s,"W")==0) {
-           pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-           pcop->type = PO_GPR_REGISTER;
-
-           PCOR(pcop)->rIdx = -1;
-           PCOR(pcop)->r = NULL;
-
-           DEBUGpic16_emitcode(";","%d",__LINE__);
-           pcop->name = Safe_strdup(s);
-           pic16_emitpcode(POC_MOVFW,pcop);
-           pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
-         } else if(strcmp(s,one)==0) {
-           pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
-           pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
-         } else {
-           pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
-         }
-       }
-       break;
-       
-    case AOP_DPTR:
-    case AOP_DPTR2:
-    
-    if (aop->type == AOP_DPTR2)
-    {
-        genSetDPTR(1);
-    }
-    
-       if (aop->code) {
-           werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                  "pic16_aopPut writting to code space");
-           exit(0);
-       }
-       
-       while (offset > aop->coff) {
-           aop->coff++;
-           pic16_emitcode ("inc","dptr");
-       }
-       
-       while (offset < aop->coff) {
-           aop->coff-- ;
-           pic16_emitcode("lcall","__decdptr");
-       }
-       
-       aop->coff = offset;
-       
-       /* if not in accumulater */
-       MOVA(s);        
-       
-       pic16_emitcode ("movx","@dptr,a");
-       
-    if (aop->type == AOP_DPTR2)
-    {
-        genSetDPTR(0);
-    }
-       break;
-       
-    case AOP_R0:
-    case AOP_R1:
-       while (offset > aop->coff) {
-           aop->coff++;
-           pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
-       }
-       while (offset < aop->coff) {
-           aop->coff-- ;
-           pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
-       }
-       aop->coff = offset;
-       
-       if (aop->paged) {
-           MOVA(s);           
-           pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
-           
-       } else
-           if (*s == '@') {
-               MOVA(s);
-               pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
-           } else
-               if (strcmp(s,"r0") == 0 ||
-                   strcmp(s,"r1") == 0 ||
-                   strcmp(s,"r2") == 0 ||
-                   strcmp(s,"r3") == 0 ||
-                   strcmp(s,"r4") == 0 ||
-                   strcmp(s,"r5") == 0 ||
-                   strcmp(s,"r6") == 0 || 
-                   strcmp(s,"r7") == 0 ) {
-                   char buffer[10];
-                   sprintf(buffer,"a%s",s);
-                   pic16_emitcode("mov","@%s,%s",
-                            aop->aopu.aop_ptr->name,buffer);
-               } else
-                   pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
-       
-       break;
-       
+        //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
+          /*
+            if (*s == '@'           ||
+                strcmp(s,"r0") == 0 ||
+                strcmp(s,"r1") == 0 ||
+                strcmp(s,"r2") == 0 ||
+                strcmp(s,"r3") == 0 ||
+                strcmp(s,"r4") == 0 ||
+                strcmp(s,"r5") == 0 ||
+                strcmp(s,"r6") == 0 ||
+                strcmp(s,"r7") == 0 )
+                pic16_emitcode("mov","%s,%s  ; %d",
+                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
+            else
+          */
+
+          if(strcmp(s,"W")==0 )
+            pic16_emitcode("movf","%s,w  ; %d",s,__LINE__);
+
+          pic16_emitcode("movwf","%s",
+                   aop->aopu.aop_reg[offset]->name);
+
+          if(strcmp(s,zero)==0) {
+            pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
+
+          } else if(strcmp(s,"W")==0) {
+            pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+            pcop->type = PO_GPR_REGISTER;
+
+            PCOR(pcop)->rIdx = -1;
+            PCOR(pcop)->r = NULL;
+
+            DEBUGpic16_emitcode(";","%d",__LINE__);
+            pcop->name = Safe_strdup(s);
+            pic16_emitpcode(POC_MOVFW,pcop);
+            pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
+          } else if(strcmp(s,one)==0) {
+            pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
+            pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
+          } else {
+            pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
+          }
+        }
+        break;
+
     case AOP_STK:
-       if (strcmp(s,"a") == 0)
-           pic16_emitcode("push","acc");
-       else
-           pic16_emitcode("push","%s",s);
-       
-       break;
-       
+        if (strcmp(s,"a") == 0)
+            pic16_emitcode("push","acc");
+        else
+            pic16_emitcode("push","%s",s);
+
+        break;
+
     case AOP_CRY:
-       /* if bit variable */
-       if (!aop->aopu.aop_dir) {
-           pic16_emitcode("clr","a");
-           pic16_emitcode("rlc","a");
-       } else {
-           if (s == zero) 
-               pic16_emitcode("clr","%s",aop->aopu.aop_dir);
-           else
-               if (s == one)
-                   pic16_emitcode("setb","%s",aop->aopu.aop_dir);
-               else
-                   if (!strcmp(s,"c"))
-                       pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
-                   else {
-                       lbl = newiTempLabel(NULL);
-                       
-                       if (strcmp(s,"a")) {
-                           MOVA(s);
-                       }
-                       pic16_emitcode("clr","c");
-                       pic16_emitcode("jz","%05d_DS_",lbl->key+100);
-                       pic16_emitcode("cpl","c");
-                       pic16_emitcode("","%05d_DS_:",lbl->key+100);
-                       pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
-                   }
-       }
-       break;
-       
+        /* if bit variable */
+        if (!aop->aopu.aop_dir) {
+            pic16_emitcode("clr","a");
+            pic16_emitcode("rlc","a");
+        } else {
+            if (s == zero)
+                pic16_emitcode("clr","%s",aop->aopu.aop_dir);
+            else
+                if (s == one)
+                    pic16_emitcode("setb","%s",aop->aopu.aop_dir);
+                else
+                    if (!strcmp(s,"c"))
+                        pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
+                    else {
+                        lbl = newiTempLabel(NULL);
+
+                        if (strcmp(s,"a")) {
+                            MOVA(s);
+                        }
+                        pic16_emitcode("clr","c");
+                        pic16_emitcode("jz","%05d_DS_",lbl->key+100);
+                        pic16_emitcode("cpl","c");
+                        pic16_emitcode("","%05d_DS_:",lbl->key+100);
+                        pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
+                    }
+        }
+        break;
+
     case AOP_STR:
-       aop->coff = offset;
-       if (strcmp(aop->aopu.aop_str[offset],s))
-           pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
-       break;
-       
+        aop->coff = offset;
+        if (strcmp(aop->aopu.aop_str[offset],s))
+            pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
+        break;
+
     case AOP_ACC:
-       aop->coff = offset;
-       if (!offset && (strcmp(s,"acc") == 0))
-           break;
-       
-       if (strcmp(aop->aopu.aop_str[offset],s))
-           pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
-       break;
+        aop->coff = offset;
+        if (!offset && (strcmp(s,"acc") == 0))
+            break;
+
+        if (strcmp(aop->aopu.aop_str[offset],s))
+            pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
+        break;
 
     default :
         fprintf(stderr, "%s:%d: unknown aop->type = 0x%x\n", __FILE__, __LINE__, aop->type);
-//     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-//            "pic16_aopPut got unsupported aop->type");
-//     exit(0);    
-    }    
+//      werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+//             "pic16_aopPut got unsupported aop->type");
+//      exit(0);
+    }
 
 }
 
@@ -2306,15 +1991,32 @@ void pic16_mov2w (asmop *aop, int offset)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
 
-  if(is_LitAOp(aop))
+  if(pic16_isLitAop(aop))
     pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
   else
     pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
 }
 
-static void mov2f(asmop *dst, asmop *src, int offset)
+void pic16_mov2w_volatile (asmop *aop)
 {
-  if(is_LitAOp(src)) {
+  int i;
+
+  if(!pic16_isLitAop(aop)) {
+    // may need to protect this from the peepholer -- this is not nice but works...
+    pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(";", "VOLATILE READ - BEGIN"));
+    for (i = 0; i < aop->size; i++) {
+      if (i > 0) {
+        pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(";", "VOLATILE READ - MORE"));
+      } // if
+      pic16_emitpcode(POC_MOVFW, pic16_popGet(aop, i));
+    } // for
+    pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(";", "VOLATILE READ - END"));
+  }
+}
+
+void pic16_mov2f(asmop *dst, asmop *src, int offset)
+{
+  if(pic16_isLitAop(src)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
     pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset));
   } else {
@@ -2324,9 +2026,23 @@ static void mov2f(asmop *dst, asmop *src, int offset)
   }
 }
 
+static void pic16_movLit2f(pCodeOp *pc, int lit)
+{
+  if (0 == (lit & 0x00ff))
+  {
+    pic16_emitpcode (POC_CLRF, pc);
+  } else if (0xff == (lit & 0x00ff))
+  {
+    pic16_emitpcode (POC_SETF, pc);
+  } else {
+    pic16_emitpcode (POC_MOVLW, pic16_popGetLit (lit & 0x00ff));
+    if (pc->type != PO_WREG) pic16_emitpcode (POC_MOVWF, pc);
+  }
+}
+
 static void mov2fp(pCodeOp *dst, asmop *src, int offset)
 {
-  if(is_LitAOp(src)) {
+  if(pic16_isLitAop(src)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
     pic16_emitpcode(POC_MOVWF, dst);
   } else {
@@ -2336,15 +2052,16 @@ 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 ));
-  
+
   {
     symbol *sym;
 
       sym = newSymbol( GSTACK_TEST_NAME , 0 );
-      strcpy(sym->rname, GSTACK_TEST_NAME);
+      sprintf(sym->rname, "%s", /*port->fun_prefix,*/ GSTACK_TEST_NAME);
+//      strcpy(sym->rname, GSTACK_TEST_NAME);
       checkAddSym(&externs, sym);
   }
 
@@ -2353,11 +2070,16 @@ void pic16_testStackOverflow(void)
 /* push pcop into stack */
 void pic16_pushpCodeOp(pCodeOp *pcop)
 {
-//     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec )));   //&pic16_pc_postdec1)));
+//      DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  if (pcop->type == PO_LITERAL) {
+    pic16_emitpcode(POC_MOVLW, pcop);
+    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
+  } else {
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec )));
+  }
   if(pic16_options.gstack)
     pic16_testStackOverflow();
-    
+
 }
 
 /* pop pcop from stack */
@@ -2375,12 +2097,12 @@ void pic16_poppCodeOp(pCodeOp *pcop)
 void pushw(void)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1));
+  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
 }
 
-                
+
 /*-----------------------------------------------------------------*/
 /* pushaop - pushes aop to stack                                   */
 /*-----------------------------------------------------------------*/
@@ -2388,12 +2110,14 @@ void pushaop(asmop *aop, int offset)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-  if(is_LitAOp(aop)) {
+  if(_G.resDirect)return;
+
+  if(pic16_isLitAop(aop)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
-    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));       //&pic16_pc_postdec1));
+    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
   } else {
     pic16_emitpcode(POC_MOVFF,
-      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec )));     //&pic16_pc_postdec1)));
+      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec )));
   }
 
   if(pic16_options.gstack)
@@ -2425,65 +2149,6 @@ void popaopidx(asmop *aop, int offset, int index)
       pic16_testStackOverflow();
 }
 
-#if !(USE_GENERIC_SIGNED_SHIFT)
-/*-----------------------------------------------------------------*/
-/* reAdjustPreg - points a register back to where it should        */
-/*-----------------------------------------------------------------*/
-static void reAdjustPreg (asmop *aop)
-{
-    int size ;
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    aop->coff = 0;
-    if ((size = aop->size) <= 1)
-        return ;
-    size-- ;
-    switch (aop->type) {
-        case AOP_R0 :
-        case AOP_R1 :
-            while (size--)
-                pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
-            break;          
-        case AOP_DPTR :
-        case AOP_DPTR2:
-            if (aop->type == AOP_DPTR2)
-           {
-                genSetDPTR(1);
-           } 
-            while (size--)
-            {
-                pic16_emitcode("lcall","__decdptr");
-            }
-                
-           if (aop->type == AOP_DPTR2)
-           {
-                genSetDPTR(0);
-           }                
-            break;  
-
-    }   
-
-}
-#endif
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* opIsGptr: returns non-zero if the passed operand is            */   
-/* a generic pointer type.                                        */
-/*-----------------------------------------------------------------*/ 
-static int opIsGptr(operand *op)
-{
-    sym_link *type = operandType(op);
-    
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
-    {
-        return 1;
-    }
-    return 0;        
-}
-#endif
-
 /*-----------------------------------------------------------------*/
 /* pic16_getDataSize - get the operand data size                         */
 /*-----------------------------------------------------------------*/
@@ -2549,15 +2214,15 @@ void pic16_outBitC(operand *result)
 
     /* if the result is bit */
     if (AOP_TYPE(result) == AOP_CRY) {
-       fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
+        fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
         pic16_aopPut(AOP(result),"c",0);
     } else {
 
-       i = AOP_SIZE(result);
-       while(i--) {
-               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
-       }
-       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
+        i = AOP_SIZE(result);
+        while(i--) {
+                pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
+        }
+        pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
     }
 }
 
@@ -2573,16 +2238,16 @@ void pic16_outBitOp(operand *result, pCodeOp *pcop)
 
     /* if the result is bit */
     if (AOP_TYPE(result) == AOP_CRY) {
-       fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
+        fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
         pic16_aopPut(AOP(result),"c",0);
     } else {
 
-       i = AOP_SIZE(result);
-       while(i--) {
-               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
-       }
-        pic16_emitpcode(POC_RRCF, pcop);         
-       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
+        i = AOP_SIZE(result);
+        while(i--) {
+                pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
+        }
+        pic16_emitpcode(POC_RRCF, pcop);
+        pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
     }
 }
 
@@ -2604,125 +2269,24 @@ void pic16_toBoolean(operand *oper)
     }
 }
 
-
-#if !defined(GEN_Not)
-/*-----------------------------------------------------------------*/
-/* genNot - generate code for ! operation                          */
-/*-----------------------------------------------------------------*/
-static void pic16_genNot (iCode *ic)
-{
-  symbol *tlbl;
-  int size;
-
-  FENTRY;
-  /* assign asmOps to operand & result */
-  pic16_aopOp (IC_LEFT(ic),ic,FALSE);
-  pic16_aopOp (IC_RESULT(ic),ic,TRUE);
-
-  DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
-  /* if in bit space then a special case */
-  if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
-    if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
-      pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
-      pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
-    } else {
-      pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
-      pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
-      pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
-    }
-    goto release;
-  }
-
-  size = AOP_SIZE(IC_LEFT(ic));
-  if(size == 1) {
-    pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
-    pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
-    pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
-    goto release;
-  }
-  pic16_toBoolean(IC_LEFT(ic));
-
-  tlbl = newiTempLabel(NULL);
-  pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
-  pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-  pic16_outBitC(IC_RESULT(ic));
-
- release:    
-  /* release the aops */
-  pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-  pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
-#endif
-
-
-#if !defined(GEN_Cpl)
-/*-----------------------------------------------------------------*/
-/* genCpl - generate code for complement                           */
-/*-----------------------------------------------------------------*/
-static void pic16_genCpl (iCode *ic)
-{
-  int offset = 0;
-  int size ;
-
-    FENTRY;
-    /* assign asmOps to operand & result */
-    pic16_aopOp (IC_LEFT(ic),ic,FALSE);
-    pic16_aopOp (IC_RESULT(ic),ic,TRUE);
-
-    /* if both are in bit space then 
-    a special case */
-    if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
-        AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
-
-        pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
-        pic16_emitcode("cpl","c"); 
-        pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
-        goto release; 
-    } 
-
-    size = AOP_SIZE(IC_RESULT(ic));
-    while (size--) {
-/*
-        char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
-        MOVA(l);       
-        pic16_emitcode("cpl","a");
-        pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
-*/
-       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-             pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
-       } else {
-               pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
-               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-       }
-       offset++;
-
-    }
-
-
-release:
-    /* release the aops */
-    pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
-#endif
-
 /*-----------------------------------------------------------------*/
 /* genUminusFloat - unary minus for floating points                */
 /*-----------------------------------------------------------------*/
 static void genUminusFloat(operand *op,operand *result)
 {
   int size ,offset =0 ;
-  
+
     FENTRY;
-    /* for this we just need to flip the 
+    /* for this we just need to flip the
     first it then copy the rest in place */
     size = AOP_SIZE(op);
+    assert( size == AOP_SIZE(result) );
 
     while(size--) {
-      mov2f(AOP(result), AOP(op), offset);
+      pic16_mov2f(AOP(result), AOP(op), offset);
       offset++;
     }
-    
+
     /* toggle the MSB's highest bit */
     pic16_emitpcode(POC_BTG, pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), offset-1), 7));
 }
@@ -2732,200 +2296,105 @@ static void genUminusFloat(operand *op,operand *result)
 /*-----------------------------------------------------------------*/
 static void genUminus (iCode *ic)
 {
-  int size, i;
+  int lsize, rsize, i;
   sym_link *optype, *rtype;
   symbol *label;
   int needLabel=0;
 
-    FENTRY;    
-    
+    FENTRY;
+
     /* assign asmops */
     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
     pic16_aopOp(IC_RESULT(ic),ic,TRUE);
 
     /* if both in bit space then special case */
     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
-      && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
-        
+      && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
+
         pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
         pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
         pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(IC_RESULT(ic)),0));
-        goto release; 
-    } 
+        goto release;
+    }
 
     optype = operandType(IC_LEFT(ic));
     rtype = operandType(IC_RESULT(ic));
 
+
     /* if float then do float stuff */
-    if (IS_FLOAT(optype)) {
-      genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
-      goto release;
+    if (IS_FLOAT(optype) || IS_FIXED(optype)) {
+      if(IS_FIXED(optype))
+        debugf("implement fixed16x16 type\n", 0);
+
+        genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
+        goto release;
     }
 
     /* otherwise subtract from zero by taking the 2's complement */
-    size = AOP_SIZE(IC_LEFT(ic));
+    lsize = AOP_SIZE(IC_LEFT(ic));
+    rsize = AOP_SIZE(IC_RESULT(ic));
     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));
+      /* If the result is longer than the operand,
+         store sign extension (0x00 or 0xff) in W */
+      if (rsize > lsize) {
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0x00));
+        pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(IC_LEFT(ic)), lsize-1), 7));
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0xFF));
+      }
+      for (i = rsize - 1; i > 0; --i) {
+        if (i > lsize - 1) {
+          pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+        } else {
+          pic16_emitpcode (POC_COMF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+        } // if
       } // 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));
+      pic16_emitpcode (POC_NEGF, pic16_popGet (AOP(IC_RESULT(ic)), 0));
+      for (i = 1; i < rsize; ++i) {
+        if (i == rsize - 1) {
+          emitSKPNZ;
+        } else {
+          pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++;
+        }
+        pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_RESULT(ic)), i));
       } // for
     } else {
-      for (i=size-1; i >= 0; i--) {
+      for (i = min(rsize, lsize) - 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));
+        pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
       } // for
-      if (size > 1) {
-        for (i=0; i < size-2; i++) {
+      /* Sign extend if the result is longer than the operand */
+      if (rsize > lsize) {
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0x00));
+        pic16_emitpcode (POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(IC_RESULT(ic)), lsize - 1), 7));
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0xFF));
+        for (i = rsize - 1; i > lsize - 1; --i) {
+          pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+        } // for
+      } // if
+      if (rsize > 1) {
+        for (i = 0; i < rsize - 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));
+          pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key));
+          needLabel++;
+        } // for
+        pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(IC_RESULT(ic)), rsize - 2));
       } // if
-      pic16_emitpcode (POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)), size-1));
+      pic16_emitpcode (POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)), rsize - 1));
     }
     if (needLabel)
       pic16_emitpLabel (label->key);
 
 release:
     /* release the aops */
-    pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
+    pic16_freeAsmop(IC_LEFT(ic), NULL, ic, (RESULTONSTACK(ic) ? 0 : 1));
+    pic16_freeAsmop(IC_RESULT(ic), NULL, ic, TRUE);
 }
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* saveRegisters - will look for a call and save the registers     */
-/*-----------------------------------------------------------------*/
-static void saveRegisters(iCode *lic) 
-{
-    int i;
-    iCode *ic;
-    bitVect *rsave;
-    sym_link *dtype;
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* look for call */
-    for (ic = lic ; ic ; ic = ic->next) 
-        if (ic->op == CALL || ic->op == PCALL)
-            break;
-
-    if (!ic) {
-        fprintf(stderr,"found parameter push with no function call\n");
-        return ;
-    }
-
-    /* if the registers have been saved already then
-    do nothing */
-    if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
-        return ;
-
-    /* find the registers in use at this time 
-    and push them away to safety */
-    rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
-                          ic->rUsed);
-
-    ic->regsSaved = 1;
-    if (options.useXstack) {
-       if (bitVectBitValue(rsave,R0_IDX))
-           pic16_emitcode("mov","b,r0");
-       pic16_emitcode("mov","r0,%s",spname);
-       for (i = 0 ; i < pic16_nRegs ; i++) {
-           if (bitVectBitValue(rsave,i)) {
-               if (i == R0_IDX)
-                   pic16_emitcode("mov","a,b");
-               else
-                   pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
-               pic16_emitcode("movx","@r0,a");
-               pic16_emitcode("inc","r0");
-           }
-       }
-       pic16_emitcode("mov","%s,r0",spname);
-       if (bitVectBitValue(rsave,R0_IDX))
-           pic16_emitcode("mov","r0,b");           
-    }// else
-    //for (i = 0 ; i < pic16_nRegs ; i++) {
-    //    if (bitVectBitValue(rsave,i))
-    // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
-    //}
-
-    dtype = operandType(IC_LEFT(ic));
-    if (currFunc && dtype && 
-        (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
-       IFFUNC_ISISR(currFunc->type) &&
-        !ic->bankSaved) 
-
-        saverbank(FUNC_REGBANK(dtype),ic,TRUE);
-
-}
-/*-----------------------------------------------------------------*/
-/* unsaveRegisters - pop the pushed registers                      */
-/*-----------------------------------------------------------------*/
-static void unsaveRegisters (iCode *ic)
-{
-    int i;
-    bitVect *rsave;
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* find the registers in use at this time 
-    and push them away to safety */
-    rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
-                          ic->rUsed);
-    
-    if (options.useXstack) {
-       pic16_emitcode("mov","r0,%s",spname);   
-       for (i =  pic16_nRegs ; i >= 0 ; i--) {
-           if (bitVectBitValue(rsave,i)) {
-               pic16_emitcode("dec","r0");
-               pic16_emitcode("movx","a,@r0");
-               if (i == R0_IDX)
-                   pic16_emitcode("mov","b,a");
-               else
-                   pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
-           }       
-
-       }
-       pic16_emitcode("mov","%s,r0",spname);
-       if (bitVectBitValue(rsave,R0_IDX))
-           pic16_emitcode("mov","r0,b");
-    } //else
-    //for (i =  pic16_nRegs ; i >= 0 ; i--) {
-    //    if (bitVectBitValue(rsave,i))
-    // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
-    //}
-
-}  
-#endif
-
-#if 0  // patch 14
-/*-----------------------------------------------------------------*/
-/* pushSide -                                                     */
-/*-----------------------------------------------------------------*/
-static void pushSide(operand * oper, int size)
-{
-       int offset = 0;
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       while (size--) {
-               char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
-               if (AOP_TYPE(oper) != AOP_REG &&
-                   AOP_TYPE(oper) != AOP_DIR &&
-                   strcmp(l,"a") ) {
-                       pic16_emitcode("mov","a,%s",l);
-                       pic16_emitcode("push","acc");
-               } else
-                       pic16_emitcode("push","%s",l);
-       }
-}
-#endif // patch 14
-
 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
 {
-  if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
+  if((AOP(op)->type == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_IMMEDIATE)) {
     pic16_emitpcode(POC_MOVFW, src);
     pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
   } else {
@@ -2939,70 +2408,72 @@ void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
 /* assignResultValue - assign results to oper, rescall==1 is       */
 /*                     called from genCall() or genPcall()         */
 /*-----------------------------------------------------------------*/
-static void assignResultValue(operand * oper, int rescall)
+static void assignResultValue(operand * oper, int res_size, int rescall)
 {
   int size = AOP_SIZE(oper);
   int offset=0;
-  
+
     FENTRY2;
 //    DEBUGpic16_emitcode ("; ***","%s  %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
     DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
 
     if(rescall) {
       /* assign result from a call/pcall function() */
-               
+
       /* function results are stored in a special order,
        * see top of file with Function return policy, or manual */
 
       if(size <= 4) {
         /* 8-bits, result in WREG */
         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
-                       
-        if(size>1) {
-         /* 16-bits, result in PRODL:WREG */
-         pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
-       }
-                       
-       if(size>2) {
-         /* 24-bits, result in PRODH:PRODL:WREG */
-         pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
-       }
-                       
-       if(size>3) {
-         /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
-         pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
-       }
-      
+
+        if(size > 1 && res_size > 1) {
+          /* 16-bits, result in PRODL:WREG */
+          pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
+        }
+
+        if(size > 2 && res_size > 2) {
+          /* 24-bits, result in PRODH:PRODL:WREG */
+          pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
+        }
+
+        if(size > 3 && res_size > 3) {
+          /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
+          pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
+        }
+
+        pic16_addSign(oper, res_size, IS_UNSIGNED(operandType(oper)));
+
       } else {
         /* >32-bits, result on stack, and FSR0 points to beginning.
-        * Fix stack when done */
-       /* FIXME FIXME */
-//     debugf("WARNING: Possible bug when returning more than 4-bytes\n");
-       while (size--) {
-//         DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
+         * Fix stack when done */
+        /* FIXME FIXME */
+//      debugf("WARNING: Possible bug when returning more than 4-bytes\n");
+        while (size--) {
+//          DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
 //          DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
-               
+
           popaopidx(AOP(oper), size, GpsuedoStkPtr);
           GpsuedoStkPtr++;
-       }
-                       
-       /* fix stack */
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
-       pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));      //&pic16_pc_fsr1l ));
-       if(STACK_MODEL_LARGE) {
-         emitSKPNC;
-         pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));     //&pic16_pc_fsr1h ));
-       }
-      }                        
+        }
+
+        /* fix stack */
+        pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
+        pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));      //&pic16_pc_fsr1l ));
+        if(STACK_MODEL_LARGE) {
+          emitSKPNC;
+          pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));     //&pic16_pc_fsr1h ));
+        }
+      }
     } else {
-      int areg = 0;            /* matching argument register */
-      
+      int areg = 0;             /* matching argument register */
+
 //      debugf("_G.useWreg = %d\tGpsuedoStkPtr = %d\n", _G.useWreg, GpsuedoStkPtr);
       areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
 
 
       /* its called from genReceive (probably) -- VR */
-      /* I hope this code will not be called from somewhere else in the future! 
+      /* I hope this code will not be called from somewhere else in the future!
        * We manually set the pseudo stack pointer in genReceive. - dw
        */
       if(!GpsuedoStkPtr && _G.useWreg) {
@@ -3015,7 +2486,7 @@ static void assignResultValue(operand * oper, int rescall)
           offset++;
 //          debugf("receive from WREG\n", 0);
         }
-       GpsuedoStkPtr++; /* otherwise the calculation below fails (-_G.useWreg) */
+        GpsuedoStkPtr++; /* otherwise the calculation below fails (-_G.useWreg) */
       }
 //      GpsuedoStkPtr++;
       _G.stack_lat = AOP_SIZE(oper)-1;
@@ -3050,13 +2521,13 @@ static void genIpush (iCode *ic)
     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
   }
 
-       
+
 #if 0
     int size, offset = 0 ;
     char *l;
 
 
-    /* if this is not a parm push : ie. it is spill push 
+    /* if this is not a parm push : ie. it is spill push
     and spill push is always done on the local stack */
     if (!ic->parmPush) {
 
@@ -3075,7 +2546,7 @@ static void genIpush (iCode *ic)
             }
             pic16_emitcode("push","%s",l);
         }
-        return ;        
+        return ;
     }
 
     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
@@ -3100,7 +2571,7 @@ static void genIpop (iCode *ic)
     pic16_aopOp(IC_LEFT(ic),ic,FALSE);
     size = AOP_SIZE(IC_LEFT(ic));
     offset = (size-1);
-    while (size--) 
+    while (size--)
         pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
                                    FALSE,TRUE));
 
@@ -3108,105 +2579,6 @@ static void genIpop (iCode *ic)
 #endif
 }
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* unsaverbank - restores the resgister bank from stack            */
-/*-----------------------------------------------------------------*/
-static void unsaverbank (int bank,iCode *ic,bool popPsw)
-{
-  DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
-#if 0
-    int i;
-    asmop *aop ;
-    regs *r = NULL;
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if (popPsw) {
-       if (options.useXstack) {
-           aop = newAsmop(0);
-           r = getFreePtr(ic,&aop,FALSE);
-           
-           
-           pic16_emitcode("mov","%s,_spx",r->name);
-           pic16_emitcode("movx","a,@%s",r->name);
-           pic16_emitcode("mov","psw,a");
-           pic16_emitcode("dec","%s",r->name);
-           
-       }else
-           pic16_emitcode ("pop","psw");
-    }
-
-    for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
-        if (options.useXstack) {       
-            pic16_emitcode("movx","a,@%s",r->name);
-            //pic16_emitcode("mov","(%s+%d),a",
-           //       regspic16[i].base,8*bank+regspic16[i].offset);
-            pic16_emitcode("dec","%s",r->name);
-
-        } else 
-         pic16_emitcode("pop",""); //"(%s+%d)",
-       //regspic16[i].base,8*bank); //+regspic16[i].offset);
-    }
-
-    if (options.useXstack) {
-
-       pic16_emitcode("mov","_spx,%s",r->name);
-       pic16_freeAsmop(NULL,aop,ic,TRUE);
-
-    }
-#endif 
-}
-
-/*-----------------------------------------------------------------*/
-/* saverbank - saves an entire register bank on the stack          */
-/*-----------------------------------------------------------------*/
-static void saverbank (int bank, iCode *ic, bool pushPsw)
-{
-  DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
-#if 0
-    int i;
-    asmop *aop ;
-    regs *r = NULL;
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if (options.useXstack) {
-
-       aop = newAsmop(0);
-       r = getFreePtr(ic,&aop,FALSE);  
-       pic16_emitcode("mov","%s,_spx",r->name);
-
-    }
-
-    for (i = 0 ; i < pic16_nRegs ;i++) {
-        if (options.useXstack) {
-            pic16_emitcode("inc","%s",r->name);
-            //pic16_emitcode("mov","a,(%s+%d)",
-            //         regspic16[i].base,8*bank+regspic16[i].offset);
-            pic16_emitcode("movx","@%s,a",r->name);           
-        } else 
-         pic16_emitcode("push","");// "(%s+%d)",
-                     //regspic16[i].base,8*bank+regspic16[i].offset);
-    }
-    
-    if (pushPsw) {
-       if (options.useXstack) {
-           pic16_emitcode("mov","a,psw");
-           pic16_emitcode("movx","@%s,a",r->name);     
-           pic16_emitcode("inc","%s",r->name);
-           pic16_emitcode("mov","_spx,%s",r->name);       
-           pic16_freeAsmop (NULL,aop,ic,TRUE);
-           
-       } else
-           pic16_emitcode("push","psw");
-       
-       pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
-    }
-    ic->bankSaved = 1;
-#endif
-}
-#endif /* 0 */
-
-
 static int wparamCmp(void *p1, void *p2)
 {
   return (!strcmp((char *)p1, (char *)p2));
@@ -3215,7 +2587,7 @@ static int wparamCmp(void *p1, void *p2)
 int inWparamList(char *s)
 {
   return isinSetWith(wparamList, s, wparamCmp);
-} 
+}
 
 
 /*-----------------------------------------------------------------*/
@@ -3223,12 +2595,12 @@ int inWparamList(char *s)
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
-  sym_link *ftype;   
+  sym_link *ftype;
   int stackParms=0;
   int use_wreg=0;
   int inwparam=0;
   char *fname;
-  
+
     FENTRY;
 
     ftype = OP_SYM_TYPE(IC_LEFT(ic));
@@ -3236,9 +2608,9 @@ static void genCall (iCode *ic)
 //    if (!ic->regsSaved)
 //      saveRegisters(ic);
 
-       /* initialise stackParms for IPUSH pushes */
-//     stackParms = psuedoStkPtr;
-//     fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
+        /* initialise stackParms for IPUSH pushes */
+//      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)) || (FUNC_ISWPARAM(OP_SYM_TYPE(IC_LEFT(ic))));
 
@@ -3249,7 +2621,7 @@ static void genCall (iCode *ic)
     /* if send set is not empty the assign */
     if (_G.sendSet) {
       iCode *sic;
-      int psuedoStkPtr=-1; 
+      int psuedoStkPtr=-1;
       int firstTimeThruLoop = 1;
 
 
@@ -3257,10 +2629,10 @@ static void genCall (iCode *ic)
         if(!IFFUNC_ISREENT(ftype))
           _G.sendSet = reverseSet(_G.sendSet);
 
-       /* First figure how many parameters are getting passed */
+        /* First figure how many parameters are getting passed */
         stackParms = 0;
         use_wreg = 0;
-        
+
         for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
           int size;
 //          int offset = 0;
@@ -3285,10 +2657,10 @@ static void genCall (iCode *ic)
                    * passed in W. */
 
                   pushw();
-//                  --psuedoStkPtr;            // sanity check
+//                  --psuedoStkPtr;             // sanity check
                   use_wreg = 1;
                 }
-                
+
                 firstTimeThruLoop=0;
 
                 pic16_mov2w (AOP(IC_LEFT(sic)), size);
@@ -3305,8 +2677,10 @@ static void genCall (iCode *ic)
                 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
 
 //                pushaop(AOP(IC_LEFT(sic)), size);
-                pic16_mov2w (AOP(IC_LEFT(sic)), size);
-                pushw();
+                                pic16_mov2w( AOP(IC_LEFT(sic)), size );
+
+                if(!_G.resDirect)
+                  pushw();
               }
             }
 
@@ -3315,7 +2689,7 @@ static void genCall (iCode *ic)
 
           if(inwparam) {
             if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype)) {
-              pushw(); /* save last parameter to stack if functions has varargs */
+              pushw();  /* save last parameter to stack if functions has varargs */
               use_wreg = 0;
             } else
               use_wreg = 1;
@@ -3329,7 +2703,7 @@ static void genCall (iCode *ic)
     pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
 
     GpsuedoStkPtr=0;
-    
+
     /* if we need to assign a result value */
     if ((IS_ITEMP(IC_RESULT(ic))
           && (OP_SYMBOL(IC_RESULT(ic))->nRegs
@@ -3340,30 +2714,34 @@ static void genCall (iCode *ic)
       pic16_aopOp(IC_RESULT(ic),ic,FALSE);
       _G.accInUse--;
 
-      assignResultValue(IC_RESULT(ic), 1);
+      /* Must not assign an 8-bit result to a 16-bit variable;
+       * this would use (used...) the uninitialized PRODL! */
+      /* FIXME: Need a proper way to obtain size of function result type,
+       * OP_SYM_ETYPE does not work: it dereferences pointer types! */
+      assignResultValue(IC_RESULT(ic), getSize(OP_SYM_TYPE(IC_LEFT(ic))->next), 1);
 
       DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
                 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
-               
+
       pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
     }
 
     if(!stackParms && ic->parmBytes) {
       stackParms = ic->parmBytes;
     }
-      
+
     stackParms -= use_wreg;
-    
+
     if(stackParms>0) {
       if(stackParms == 1) {
-        pic16_emitpcode(POC_INCF, pic16_popCopyReg(pic16_stackpnt_lo ));       //&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_stackpnt_lo ));     //&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_stackpnt_hi ));      //&pic16_pc_fsr1h ));
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));       //&pic16_pc_fsr1h ));
       }
     }
 
@@ -3393,27 +2771,26 @@ static void genCall (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genPcall (iCode *ic)
 {
-  sym_link *ftype, *fntype;
+  sym_link *fntype;
   int stackParms=0;
   symbol *retlbl = newiTempLabel(NULL);
   pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
-  
+
     FENTRY;
 
-    ftype = OP_SYM_TYPE(IC_LEFT(ic));
     fntype = operandType( IC_LEFT(ic) )->next;
 
     /* if send set is not empty the assign */
     if (_G.sendSet) {
       iCode *sic;
-      int psuedoStkPtr=-1; 
+      int psuedoStkPtr=-1;
 
       /* reverse sendSet if function is not reentrant */
       if(!IFFUNC_ISREENT(fntype))
         _G.sendSet = reverseSet(_G.sendSet);
 
       stackParms = 0;
-      
+
       for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
         int size;
 
@@ -3464,11 +2841,11 @@ static void genPcall (iCode *ic)
     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)));
+    mov2fp(pic16_popCopyReg(&pic16_pc_pclatu), AOP(IC_LEFT(ic)), 2);
+    mov2fp(pic16_popCopyReg(&pic16_pc_pclath), AOP(IC_LEFT(ic)), 1);
 
     // note: MOVFF to PCL not allowed
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
+    pic16_mov2w(AOP(IC_LEFT(ic)), 0);
     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
 
 
@@ -3488,16 +2865,18 @@ static void genPcall (iCode *ic)
       pic16_aopOp(IC_RESULT(ic),ic,FALSE);
       _G.accInUse--;
 
-      assignResultValue(IC_RESULT(ic), 1);
+      /* FIXME: Need proper way to obtain the function result's type.
+       * OP_SYM_TYPE(IC_LEFT(ic))->next does not work --> points to function pointer */
+      assignResultValue(IC_RESULT(ic), getSize(OP_SYM_TYPE(IC_LEFT(ic))->next->next), 1);
 
       DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
               pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
-               
+
       pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
     }
 
 //    stackParms -= use_wreg;
-    
+
     if(stackParms>0) {
       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
       pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));
@@ -3519,19 +2898,13 @@ static int resultRemat (iCode *ic)
 
   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
-    if (sym->remat && !POINTER_SET(ic)) 
+    if (sym->remat && !POINTER_SET(ic))
       return 1;
   }
 
   return 0;
 }
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
 #if 0
 /*-----------------------------------------------------------------*/
 /* inExcludeList - return 1 if the string is in exclude Reg list   */
@@ -3540,16 +2913,16 @@ static bool inExcludeList(char *s)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
     int i =0;
-    
+
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if (options.excludeRegs[i] &&
     STRCASECMP(options.excludeRegs[i],"none") == 0)
-       return FALSE ;
+        return FALSE ;
 
     for ( i = 0 ; options.excludeRegs[i]; i++) {
-       if (options.excludeRegs[i] &&
+        if (options.excludeRegs[i] &&
         STRCASECMP(s,options.excludeRegs[i]) == 0)
-           return TRUE;
+            return TRUE;
     }
     return FALSE ;
 }
@@ -3562,7 +2935,7 @@ static void genFunction (iCode *ic)
 {
   symbol *sym;
   sym_link *ftype;
-  
+
     FENTRY;
     DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
 
@@ -3570,7 +2943,7 @@ static void genFunction (iCode *ic)
     max_key=0;
     GpsuedoStkPtr=0;
     _G.nRegsSaved = 0;
-       
+
     ftype = operandType(IC_LEFT(ic));
     sym = OP_SYMBOL(IC_LEFT(ic));
 
@@ -3581,59 +2954,47 @@ static void genFunction (iCode *ic)
       char asymname[128];
       pBlock *apb;
 
-
 //        debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type));
 
-#if 0
-        {
-          int i, found=-1;
-
-            sym = OP_SYMBOL( IC_LEFT(ic));
-            for(i=0;i<=2;i++) {
-              if(interrupts[i]->name
-                    && !STRCASECMP(interrupts[i]->name, sym->name)) {
-                  found = i;
-                  break;
-              }
-            }
-                       
-            if(found == -1) {
-              fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
-                            __FILE__, __LINE__, sym->name);
-//              assert( 0 );
-            }
-            _G.interruptvector = found;
-        }
-#endif
-
-        if(FUNC_INTNO(sym->type) == 256)
+        if(FUNC_INTNO(sym->type) == INTNO_UNSPEC)
           sprintf(asymname, "ivec_%s", sym->name);
         else
           sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name);
-        asym = newSymbol(asymname, 0);
 
-        apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
-        pic16_addpBlock( apb );
+        /* 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 */
 
-        pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
-        pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
-        pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
-               
-        /* mark the end of this tiny function */
-        pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
+        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 );
 
-       {
-         absSym *abSym;
+          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 */
 
-           abSym = Safe_calloc(1, sizeof(absSym));
-           strcpy(abSym->name, asymname);
+          /* mark the end of this tiny function */
+          pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
+        } else {
+          sprintf(asymname, "%s", sym->rname);
+        }
+
+        {
+          absSym *abSym;
 
-           switch( FUNC_INTNO(sym->type) ) {
-             case 0: abSym->address = 0x000000; break;
+            abSym = Safe_calloc(1, sizeof(absSym));
+            strcpy(abSym->name, asymname);
+
+            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;
             }
 
@@ -3650,10 +3011,12 @@ static void genFunction (iCode *ic)
     pic16_emitcode(";"," function %s",sym->name);
     pic16_emitcode(";","-----------------------------------------");
 
+    /* prevent this symbol from being emitted as 'extern' */
+    pic16_stringInSet(sym->rname, &pic16_localFunctions, 1);
+
     pic16_emitcode("","%s:",sym->rname);
     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
 
-
     {
       absSym *ab;
 
@@ -3665,24 +3028,26 @@ static void genFunction (iCode *ic)
         }
     }
 
-
     if(IFFUNC_ISNAKED(ftype)) {
       DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
       return;
     }
-       
+
     /* if critical function then turn interrupts off */
     if (IFFUNC_ISCRITICAL(ftype)) {
       //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 */
     if (IFFUNC_ISISR(sym->type)) {
-        _G.usefastretfie = 1;  /* use shadow registers by default */
-        
+        _G.usefastretfie = 1;   /* use shadow registers by default */
+
         /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
         if(!FUNC_ISSHADOWREGS(sym->type)) {
           /* do not save WREG,STATUS,BSR for high priority interrupts
@@ -3699,25 +3064,31 @@ static void genFunction (iCode *ic)
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
-        
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_pclath ));
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_pclatu ));
+
 //        pic16_pBlockConvert2ISR(pb);
-                
     }
 
     /* emit code to setup stack frame if user enabled,
      * and function is not main() */
-        
-    //fprintf(stderr, "function name: %s\n", sym->name);
+
+//    debugf(stderr, "function name: %s ARGS=%p\n", sym->name, FUNC_ARGS(sym->type));
     if(strcmp(sym->name, "main")) {
-      if(1  /*!options.ommitFramePtr || sym->regsUsed*/) {
+      if(0
+        || !options.ommitFramePtr
+//        || sym->regsUsed
+        || IFFUNC_ARGS(sym->type)
+        || FUNC_HASSTACKPARM(sym->etype)
+        ) {
         /* setup the stack frame */
         if(STACK_MODEL_LARGE)
           pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_hi));
         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_stackpnt_hi, pic16_framepnt_hi, 0));
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( pic16_stackpnt_lo, pic16_framepnt_lo, 0));
       }
     }
 
@@ -3727,11 +3098,11 @@ 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_stackpnt_lo ));       //&pic16_pc_fsr1l));
+      pic16_emitpcode(POC_SUBWF, pic16_popCopyReg( pic16_stackpnt_lo ));        //&pic16_pc_fsr1l));
       emitSKPC;
-      pic16_emitpcode(POC_DECF, pic16_popCopyReg( pic16_stackpnt_hi ));                //&pic16_pc_fsr1h));
+      pic16_emitpcode(POC_DECF, pic16_popCopyReg( pic16_stackpnt_hi ));         //&pic16_pc_fsr1h));
     }
-          
+
     if(inWparamList(sym->name) || FUNC_ISWPARAM(sym->type)) {
       if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
         _G.useWreg = 0;
@@ -3743,30 +3114,49 @@ static void genFunction (iCode *ic)
     /* if callee-save to be used for this function
      * then save the registers being used in this function */
 //    if (IFFUNC_CALLEESAVES(sym->type))
-    {
+    if(strcmp(sym->name, "main")) {
       int i;
 
         /* if any registers used */
         if (sym->regsUsed) {
-          /* save the registers used */
-          DEBUGpic16_emitcode("; **", "Saving used registers in stack");
-          pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
-          for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-            if (bitVectBitValue(sym->regsUsed,i)) {
-              pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
-              _G.nRegsSaved++;
-
-              if(!pic16_regWithIdx(i)->wasUsed) {
-                fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
-                              __FILE__, __LINE__, pic16_regWithIdx(i)->name);
-                pic16_regWithIdx(i)->wasUsed = 1;
+                  pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
+
+          if(!pic16_options.xinst) {
+            /* save the registers used */
+            DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+            for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+              if (bitVectBitValue(sym->regsUsed,i)) {
+#if 0
+                fprintf(stderr, "%s:%d local register w/rIdx = %d is used in function\n", __FUNCTION__, __LINE__, i);
+#endif
+                pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
+                _G.nRegsSaved++;
+
+                if(!pic16_regWithIdx(i)->wasUsed) {
+                  fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0\n",
+                                __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+                  pic16_regWithIdx(i)->wasUsed = 1;
+                }
+              }
+            }
+          } else {
+
+            /* xinst */
+            DEBUGpic16_emitcode("; **", "Allocate a space in stack to be used as temporary registers");
+            for(i=0;i<sym->regsUsed->size;i++) {
+              if(bitVectBitValue(sym->regsUsed, i)) {
+                _G.nRegsSaved++;
               }
             }
+
+//            pic16_emitpcode(POC_ADDFSR, pic16_popGetLit2(2, pic16_popGetLit(_G.nRegsSaved)));
           }
+
           pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
+
         }
     }
-       
+
     DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
 //    fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
 }
@@ -3790,15 +3180,26 @@ static void genEndFunction (iCode *ic)
     /* add code for ISCRITICAL */
     if(IFFUNC_ISCRITICAL(sym->type)) {
       /* if critical function, turn on interrupts */
-      
+
       /* TODO: add code here -- VR */
     }
-    
+
 //    sym->regsUsed = _G.fregsUsed;
-    
+
     /* now we need to restore the registers */
     /* if any registers used */
-    if (sym->regsUsed) {
+
+    /* 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 (strcmp(sym->name, "main") && sym->regsUsed) {
       int i;
 
         pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
@@ -3811,9 +3212,10 @@ static void genEndFunction (iCode *ic)
           }
         }
         pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
-
     }
 
+
+
     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
           && sym->stack) {
       if (sym->stack == 1) {
@@ -3821,7 +3223,7 @@ static void genEndFunction (iCode *ic)
         pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));
       } else {
         // we have to add more than one...
-        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postinc ));   // 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_stackpnt_lo ));
         emitSKPNC;
@@ -3832,17 +3234,24 @@ static void genEndFunction (iCode *ic)
     }
 
     if(strcmp(sym->name, "main")) {
-      if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
+      if(0
+        || !options.ommitFramePtr
+//        || sym->regsUsed
+        || IFFUNC_ARGS(sym->type)
+        || FUNC_HASSTACKPARM(sym->etype)
+        ) {
         /* restore stack frame */
+        pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_lo ));
         if(STACK_MODEL_LARGE)
           pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_hi ));
-        pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_lo ));
       }
     }
 
     _G.useWreg = 0;
 
     if (IFFUNC_ISISR(sym->type)) {
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_pclatu ));
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_pclath ));
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
@@ -3851,26 +3260,26 @@ static void genEndFunction (iCode *ic)
       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 ));
+        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 */
-/*     if (options.debug && currFunc)  */
+/*      if (options.debug && currFunc)  */
       if (currFunc) {
         debugFile->writeEndFunction (currFunc, ic, 1);
       }
-       
+
       if(_G.usefastretfie)
         pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
       else
         pic16_emitpcodeNULLop(POC_RETFIE);
 
       pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
-      
+
       _G.usefastretfie = 0;
       return;
     }
@@ -3886,7 +3295,7 @@ static void genEndFunction (iCode *ic)
 
     /* insert code to restore stack frame, if user enabled it
      * and function is not main() */
-        
+
 
     pic16_emitpcodeNULLop(POC_RETURN);
 
@@ -3895,40 +3304,51 @@ static void genEndFunction (iCode *ic)
 }
 
 
-void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
+void pic16_storeForReturn(iCode *ic, /*operand *op,*/ int offset, pCodeOp *dest)
 {
   unsigned long lit=1;
-  // this fails for is_LitOp(op) (if op is an AOP_PCODE)
-  if(AOP_TYPE(op) == AOP_LIT) {
-    if(!IS_FLOAT(operandType( op ))) {
-      lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit);
-    } else {
-      union {
-        unsigned long lit_int;
-        float lit_float;
-      } info;
-       
-      /* take care if literal is a float */
-      info.lit_float = floatFromVal(AOP(op)->aopu.aop_lit);
-      lit = info.lit_int;
-    }
-  }
+  operand *op;
 
-  if (is_LitOp(op)) {
-      if(lit == 0) {
-        pic16_emitpcode(POC_CLRF, dest);
+    op = IC_LEFT(ic);
+
+    // this fails for pic16_isLitOp(op) (if op is an AOP_PCODE)
+    if(AOP_TYPE(op) == AOP_LIT) {
+      if(!IS_FLOAT(operandType( op ))) {
+        lit = ulFromVal (AOP(op)->aopu.aop_lit);
       } else {
-        pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
-        if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
+        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;
       }
-  } 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));
-  }
+
+    if (AOP_TYPE(op) == AOP_LIT) {
+      /* FIXME: broken for
+       *   char __at(0x456) foo;
+       *   return &foo;
+       * (upper byte is 0x00 (__code space) instead of 0x80 (__data) */
+      pic16_movLit2f(dest, (lit >> (8ul*offset)));
+    } else if (AOP_TYPE(op) == AOP_PCODE
+                && AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
+      /* char *s= "aaa"; return s; */
+      /* XXX: Using UPPER(__str_0) will yield 0b00XXXXXX, so
+       *      that the generic pointer is interpreted correctly
+       *      as referring to __code space, but this is fragile! */
+      pic16_emitpcode(POC_MOVLW, pic16_popGet( AOP(op), offset ));
+      /* XXX: should check that dest != WREG */
+      pic16_emitpcode(POC_MOVWF, dest);
+    } 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));
+    }
 }
 
 /*-----------------------------------------------------------------*/
@@ -3940,118 +3360,64 @@ static void genRet (iCode *ic)
   operand *left;
 
     FENTRY;
-       /* if we have no return value then
-        * just generate the "ret" */
-       
-       if (!IC_LEFT(ic)) 
-               goto jumpret;       
-    
-       /* we have something to return then
-        * move the return value into place */
-       pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
-       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
-
-               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)));
-
-       } else {
-               /* >32-bits, setup stack and FSR0 */
-               while (size--) {
-//                     DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
-//                     DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
-
-                       pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
-
-//                     popaopidx(AOP(oper), size, GpseudoStkPtr);
-                       GpsuedoStkPtr++;
-               }
-                       
-               /* setup FSR0 */
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                       pic16_popCopyReg( pic16_stackpnt_lo ), pic16_popCopyReg(&pic16_pc_fsr0l)));
-
-               if(STACK_MODEL_LARGE) {
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                               pic16_popCopyReg( pic16_stackpnt_hi ), pic16_popCopyReg(&pic16_pc_fsr0h)));
-               } else {
-                       pic16_emitpcode(POC_CLRF, pic16_popCopyReg( pic16_stackpnt_hi ));
-               }
-       }
-                               
-#if 0
-       /* old code, left here for reference -- VR */    
-       while (size--) {
-         char *l ;
-
-               if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
-                       /* #NOCHANGE */
-                       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
-                       pic16_emitpcomment("push %s",l);
-                       pushed++;
-               } else {
-                       DEBUGpic16_emitcode(";", "%d", __LINE__);
-                       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
-                       DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);       
-                       
-                       if (strcmp(fReturn[offset],l)) {
-                               if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
-                                       || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
-                                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
-                               } else {
-                                       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
-                               }
-                               
-                               if(size) {
-                                       pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
-                               }
-                               offset++;
-                       }
-               }
-       }    
-
-       if (pushed) {
-               while(pushed) {
-                       pushed--;
-                       if (strcmp(fReturn[pushed],"a"))
-                               pic16_emitcode("pop",fReturn[pushed]);
-                       else
-                               pic16_emitcode("pop","acc");
-               }
-       }
-#endif
+        /* if we have no return value then
+         * just generate the "ret" */
+
+        if (!IC_LEFT(ic))
+                goto jumpret;
+
+        /* we have something to return then
+         * move the return value into place */
+        pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
+        size = AOP_SIZE(IC_LEFT(ic));
 
+        if(size <= 4) {
+          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));
+
+          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 */
+                while (size--) {
+//                      DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
+//                      DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
+
+                        pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
+
+//                      popaopidx(AOP(oper), size, GpseudoStkPtr);
+                        GpsuedoStkPtr++;
+                }
+
+                /* setup FSR0 */
+                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                        pic16_popCopyReg( pic16_stackpnt_lo ), pic16_popCopyReg(&pic16_pc_fsr0l)));
+
+                if(STACK_MODEL_LARGE) {
+                        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                pic16_popCopyReg( pic16_stackpnt_hi ), pic16_popCopyReg(&pic16_pc_fsr0h)));
+                } else {
+                        pic16_emitpcode(POC_CLRF, pic16_popCopyReg( pic16_stackpnt_hi ));
+                }
+        }
+
+        pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
 
-       pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
-    
 jumpret:
-       /* generate a jump to the return label
-        * if the next is not the return statement */
-       if (!(ic->next && ic->next->op == LABEL
-               && IC_LABEL(ic->next) == returnLabel)) {
-       
-               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
-               pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
-       }
+        /* generate a jump to the return label
+         * if the next is not the return statement */
+        if (!(ic->next && ic->next->op == LABEL
+                && IC_LABEL(ic->next) == returnLabel)) {
+
+                pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
+                pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
+        }
 }
 
 /*-----------------------------------------------------------------*/
@@ -4084,8 +3450,8 @@ static void genGoto (iCode *ic)
 /*-----------------------------------------------------------------*/
 /* genMultbits :- multiplication of bits                           */
 /*-----------------------------------------------------------------*/
-static void genMultbits (operand *left, 
-                         operand *right, 
+static void genMultbits (operand *left,
+                         operand *right,
                          operand *result)
 {
   FENTRY;
@@ -4120,24 +3486,25 @@ static void genMultOneByte (operand *left,
     left = t;
   }
 
-       /* size is already checked in genMult == 1 */
-//     size = AOP_SIZE(result);
+        /* size is already checked in genMult == 1 */
+//      size = AOP_SIZE(result);
 
-       if (AOP_TYPE(right) == AOP_LIT){
-               pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
-                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
-                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
-       } else {
-               pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
-                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
-                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
-       }
-       
-       pic16_genMult8X8_8 (left, right,result);
+        if (AOP_TYPE(right) == AOP_LIT){
+                pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+                                        pic16_aopGet(AOP(right),0,FALSE,FALSE),
+                                        pic16_aopGet(AOP(left),0,FALSE,FALSE),
+                                        pic16_aopGet(AOP(result),0,FALSE,FALSE));
+        } else {
+                pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+                                        pic16_aopGet(AOP(right),0,FALSE,FALSE),
+                                        pic16_aopGet(AOP(left),0,FALSE,FALSE),
+                                        pic16_aopGet(AOP(result),0,FALSE,FALSE));
+        }
+
+        pic16_genMult8X8_n (left, right,result);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genMultOneWord : 16 bit multiplication                          */
 /*-----------------------------------------------------------------*/
@@ -4161,20 +3528,22 @@ static void genMultOneWord (operand *left,
 //  size = AOP_SIZE(result);
 
   if (AOP_TYPE(right) == AOP_LIT) {
-    pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
-      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+    pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+      pic16_aopGet(AOP(right),0,FALSE,FALSE),
+      pic16_aopGet(AOP(left),0,FALSE,FALSE),
       pic16_aopGet(AOP(result),0,FALSE,FALSE));
   } else {
-    pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
-      pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-      pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+    pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+      pic16_aopGet(AOP(right),0,FALSE,FALSE),
+      pic16_aopGet(AOP(left),0,FALSE,FALSE),
       pic16_aopGet(AOP(result),0,FALSE,FALSE));
   }
-       
+
   pic16_genMult16X16_16(left, right,result);
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genMultOneLong : 32 bit multiplication                          */
 /*-----------------------------------------------------------------*/
@@ -4198,19 +3567,20 @@ static void genMultOneLong (operand *left,
 //  size = AOP_SIZE(result);
 
   if (AOP_TYPE(right) == AOP_LIT) {
-    pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
-        pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-        pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+    pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+        pic16_aopGet(AOP(right),0,FALSE,FALSE),
+        pic16_aopGet(AOP(left),0,FALSE,FALSE),
         pic16_aopGet(AOP(result),0,FALSE,FALSE));
   } else {
-    pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
-        pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-        pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+    pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+        pic16_aopGet(AOP(right),0,FALSE,FALSE),
+        pic16_aopGet(AOP(left),0,FALSE,FALSE),
         pic16_aopGet(AOP(result),0,FALSE,FALSE));
   }
-       
+
   pic16_genMult32X32_32(left, right,result);
 }
+#endif
 
 
 
@@ -4221,73 +3591,79 @@ static void genMult (iCode *ic)
 {
   operand *left = IC_LEFT(ic);
   operand *right = IC_RIGHT(ic);
-  operand *result= IC_RESULT(ic);   
+  operand *result= IC_RESULT(ic);
 
     FENTRY;
-       /* assign the amsops */
-       pic16_aopOp (left,ic,FALSE);
-       pic16_aopOp (right,ic,FALSE);
-       pic16_aopOp (result,ic,TRUE);
-
-       DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
-       /* special cases first *
-       * both are bits */
-       if (AOP_TYPE(left) == AOP_CRY
-               && AOP_TYPE(right)== AOP_CRY) {
-               genMultbits(left,right,result);
-         goto release ;
-       }
-
-       /* if both are of size == 1 */
-       if(AOP_SIZE(left) == 1
-               && AOP_SIZE(right) == 1) {
-               genMultOneByte(left,right,result);
-         goto release ;
-       }
-
-       /* if both are of size == 2 */
-       if(AOP_SIZE(left) == 2
-               && AOP_SIZE(right) == 2) {
-               genMultOneWord(left, right, result);
-         goto release;
-       }
-       
-       /* if both are of size == 4 */
-       if(AOP_SIZE(left) == 4
-               && AOP_SIZE(right) == 4) {
-               genMultOneLong(left, right, result);
-         goto release;
-       }
-       
-       pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
-
-
-       fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
-       /* should have been converted to function call */
-       assert(0) ;
+        /* assign the amsops */
+        pic16_aopOp (left,ic,FALSE);
+        pic16_aopOp (right,ic,FALSE);
+        pic16_aopOp (result,ic,TRUE);
+
+        DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+
+        /* special cases first *
+        * both are bits */
+        if (AOP_TYPE(left) == AOP_CRY
+                && AOP_TYPE(right)== AOP_CRY) {
+                genMultbits(left,right,result);
+          goto release ;
+        }
+
+        /* if both are of size == 1 */
+        if(AOP_SIZE(left) == 1
+                && AOP_SIZE(right) == 1) {
+                genMultOneByte(left,right,result);
+          goto release ;
+        }
+
+#if 0
+        /* if both are of size == 2 */
+        if(AOP_SIZE(left) == 2
+                && AOP_SIZE(right) == 2) {
+                genMultOneWord(left, right, result);
+          goto release;
+        }
+
+        /* if both are of size == 4 */
+        if(AOP_SIZE(left) == 4
+                && AOP_SIZE(right) == 4) {
+                genMultOneLong(left, right, result);
+          goto release;
+        }
+#endif
+
+        fprintf( stderr, "%s: should have been transformed into function call\n",__FUNCTION__ );
+        assert( !"Multiplication should have been transformed into function call!" );
+
+        pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
+
+
+        fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
+        /* should have been converted to function call */
+        assert(0) ;
 
 release :
-       pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-       pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-       pic16_freeAsmop(result,NULL,ic,TRUE); 
+        pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+        pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+        pic16_freeAsmop(result,NULL,ic,TRUE);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genDivbits :- division of bits                                  */
 /*-----------------------------------------------------------------*/
-static void genDivbits (operand *left, 
-                        operand *right, 
+static void genDivbits (operand *left,
+                        operand *right,
                         operand *result)
 {
   char *l;
 
     FENTRY;
-    /* the result must be bit */    
+    /* the result must be bit */
     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
 
-    MOVA(l);    
+    MOVA(l);
 
     pic16_emitcode("div","ab");
     pic16_emitcode("rrc","a");
@@ -4306,83 +3682,83 @@ static void genDivOneByte (operand *left,
   symbol *lbl ;
   int size,offset;
 
-       /* result = divident / divisor
-        * - divident may be a register or a literal,
-        * - divisor may be a register or a literal,
-        * so there are 3 cases (literal / literal is optimized
-        * by the front-end) to handle.
-        * In addition we must handle signed and unsigned, which
-        * result in 6 final different cases -- VR */
+        /* result = divident / divisor
+         * - divident may be a register or a literal,
+         * - divisor may be a register or a literal,
+         * so there are 3 cases (literal / literal is optimized
+         * by the front-end) to handle.
+         * In addition we must handle signed and unsigned, which
+         * result in 6 final different cases -- VR */
 
     FENTRY;
-    
+
     size = AOP_SIZE(result) - 1;
     offset = 1;
     /* signed or unsigned */
     if (SPEC_USIGN(opetype)) {
-      pCodeOp *pct1,   /* count */
-               *pct2,  /* reste */
-               *pct3;  /* temp */
+      pCodeOp *pct1,    /* count */
+                *pct2,  /* reste */
+                *pct3;  /* temp */
       symbol *label1, *label2, *label3;;
 
 
         /* unsigned is easy */
 
-       pct1 = pic16_popGetTempReg(1);
-       pct2 = pic16_popGetTempReg(1);
-       pct3 = pic16_popGetTempReg(1);
-       
-       label1 = newiTempLabel(NULL);
-       label2 = newiTempLabel(NULL);
-       label3 = newiTempLabel(NULL);
-
-       /* the following algorithm is extracted from divuint.c */
-
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
-       pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
-       
-       pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
-
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
-       
-       pic16_emitpLabel(label1->key);
-       
-       emitCLRC;
-       pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
-
-
-       emitCLRC;
-       pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
-       
-
-       emitSKPNC;
-       pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
-       
-       pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
-       
-       pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
-       pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
-       pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
-       
-       pic16_emitpLabel( label3->key );
-       pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
-       pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
-       
-       
-
-       pic16_emitpLabel(label2->key);
-       pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
-       pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
-       pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
-       
-       /* result is in wreg */
-       if(AOP_TYPE(result) != AOP_ACC)
-               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
-
-       pic16_popReleaseTempReg( pct3, 1);
-       pic16_popReleaseTempReg( pct2, 1);
-       pic16_popReleaseTempReg( pct1, 1);
+        pct1 = pic16_popGetTempReg(1);
+        pct2 = pic16_popGetTempReg(1);
+        pct3 = pic16_popGetTempReg(1);
+
+        label1 = newiTempLabel(NULL);
+        label2 = newiTempLabel(NULL);
+        label3 = newiTempLabel(NULL);
+
+        /* the following algorithm is extracted from divuint.c */
+
+        pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
+        pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
+
+        pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
+
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+
+        pic16_emitpLabel(label1->key);
+
+        emitCLRC;
+        pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
+
+
+        emitCLRC;
+        pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
+
+
+        emitSKPNC;
+        pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
+
+        pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
+
+        pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
+        pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
+        pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
+
+        pic16_emitpLabel( label3->key );
+        pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
+        pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
+
+
+
+        pic16_emitpLabel(label2->key);
+        pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
+        pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
+        pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
+
+        /* result is in wreg */
+        if(AOP_TYPE(result) != AOP_ACC)
+                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+        pic16_popReleaseTempReg( pct3, 1);
+        pic16_popReleaseTempReg( pct2, 1);
+        pic16_popReleaseTempReg( pct1, 1);
 
         return ;
     }
@@ -4390,23 +3766,23 @@ static void genDivOneByte (operand *left,
     /* signed is a little bit more difficult */
 
     /* save the signs of the operands */
-    l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
-    MOVA(l);    
+    l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
+    MOVA(l);
     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
     pic16_emitcode("push","acc"); /* save it on the stack */
 
     /* now sign adjust for both left & right */
-    l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
-    MOVA(l);       
+    l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);
+    MOVA(l);
     lbl = newiTempLabel(NULL);
-    pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
-    pic16_emitcode("cpl","a");   
+    pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
+    pic16_emitcode("cpl","a");
     pic16_emitcode("inc","a");
     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
     pic16_emitcode("mov","b,a");
 
     /* sign adjust left side */
-    l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
+    l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);
     MOVA(l);
 
     lbl = newiTempLabel(NULL);
@@ -4421,8 +3797,8 @@ static void genDivOneByte (operand *left,
     only */
     pic16_emitcode("mov","b,a");
     lbl = newiTempLabel(NULL);
-    pic16_emitcode("pop","acc");   
-    /* if there was an over flow we don't 
+    pic16_emitcode("pop","acc");
+    /* if there was an over flow we don't
     adjust the sign of the result */
     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
@@ -4436,12 +3812,13 @@ static void genDivOneByte (operand *left,
     pic16_aopPut(AOP(result),"b",0);
     if(size > 0){
         pic16_emitcode("mov","c,b.7");
-        pic16_emitcode("subb","a,acc");   
+        pic16_emitcode("subb","a,acc");
     }
     while (size--)
         pic16_aopPut(AOP(result),"a",offset++);
 
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genDiv - generates code for division                            */
@@ -4450,21 +3827,226 @@ static void genDiv (iCode *ic)
 {
     operand *left = IC_LEFT(ic);
     operand *right = IC_RIGHT(ic);
-    operand *result= IC_RESULT(ic);   
-
-
-       /* Division is a very lengthy algorithm, so it is better
-        * to call support routines than inlining algorithm.
-        * Division functions written here just in case someone
-        * wants to inline and not use the support libraries -- VR */
+    operand *result= IC_RESULT(ic);
+    int negated = 0;
+    int leftVal = 0, rightVal = 0;
+    int signedLits = 0;
+    char *functions[2][2] = { { "__divschar", "__divuchar" }, { "__modschar", "__moduchar" } };
+    int op = 0;
+
+        /* Division is a very lengthy algorithm, so it is better
+         * to call support routines than inlining algorithm.
+         * Division functions written here just in case someone
+         * wants to inline and not use the support libraries -- VR */
 
     FENTRY;
-    
+
     /* assign the amsops */
     pic16_aopOp (left,ic,FALSE);
     pic16_aopOp (right,ic,FALSE);
     pic16_aopOp (result,ic,TRUE);
 
+    if (ic->op == '/')
+      op = 0;
+    else if (ic->op == '%')
+      op = 1;
+    else
+      assert( !"invalid operation requested in genDivMod" );
+
+    /* get literal values */
+    if (IS_VALOP(left)) {
+      leftVal = (int) ulFromVal ( OP_VALUE(left) );
+      assert( leftVal >= -128 && leftVal < 256 );
+      if (leftVal < 0) { signedLits++; }
+    }
+    if (IS_VALOP(right)) {
+      rightVal = (int) ulFromVal ( OP_VALUE(right) );
+      assert( rightVal >= -128 && rightVal < 256 );
+      if (rightVal < 0) { signedLits++; }
+    }
+
+    /* We should only come here to convert all
+     * / : {u8_t, s8_t} x {u8_t, s8_t} -> {u8_t, s8_t}
+     * with exactly one operand being s8_t into
+     * u8_t x u8_t -> u8_t. All other cases should have been
+     * turned into calls to support routines beforehand... */
+    if ((AOP_SIZE(left) == 1 || IS_VALOP(left))
+        && (AOP_SIZE(right) == 1 || IS_VALOP(right)))
+    {
+      if ((!IS_UNSIGNED(operandType(right)) || rightVal < 0)
+          && (!IS_UNSIGNED(operandType(left)) || leftVal < 0))
+      {
+        /* Both operands are signed or negative, use _divschar
+         * instead of _divuchar */
+        pushaop(AOP(right), 0);
+        pushaop(AOP(left), 0);
+
+        /* call _divschar */
+        pic16_emitpcode(POC_CALL, pic16_popGetWithString(functions[op][0]));
+
+        {
+          symbol *sym;
+          sym = newSymbol( functions[op][0], 0 );
+          sym->used++;
+          strcpy(sym->rname, functions[op][0]);
+          checkAddSym(&externs, sym);
+        }
+
+        /* assign result */
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+        if (AOP_SIZE(result) > 1)
+        {
+          pic16_emitpcode(POC_MOVFF,
+              pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
+                pic16_popGet(AOP(result), 1)));
+          /* sign extend */
+          pic16_addSign(result, 2, 1);
+        }
+
+        /* clean up stack */
+        pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
+        pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
+
+        goto release;
+      }
+
+      /* push right operand */
+      if (IS_VALOP(right)) {
+        if (rightVal < 0) {
+          pic16_pushpCodeOp( pic16_popGetLit(-rightVal) );
+          negated++;
+        } else {
+          pushaop(AOP(right), 0);
+        }
+      } else if (!IS_UNSIGNED(operandType(right))) {
+        pic16_mov2w(AOP(right), 0);
+        pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
+        pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
+        negated++;
+      } else {
+        pushaop(AOP(right), 0);
+      }
+
+      /* push left operand */
+      if (IS_VALOP(left)) {
+        if (leftVal < 0) {
+          pic16_pushpCodeOp(pic16_popGetLit(-leftVal));
+          negated++;
+        } else {
+          pushaop(AOP(left), 0);
+        }
+      } else if (!IS_UNSIGNED(operandType(left))) {
+        pic16_mov2w(AOP(left),0);
+        pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+        pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
+        negated++;
+      } else {
+        pushaop(AOP(left), 0);
+      }
+
+      /* call _divuchar */
+      pic16_emitpcode(POC_CALL, pic16_popGetWithString(functions[op][1]));
+
+      {
+        symbol *sym;
+        sym = newSymbol( functions[op][1], 0 );
+        sym->used++;
+        strcpy(sym->rname, functions[op][1]);
+        checkAddSym(&externs, sym);
+      }
+
+      /* Revert negation(s) from above.
+       * This is inefficient: if both operands are negative, this
+       * should not touch WREG. However, determining that exactly
+       * one operand was negated costs at least 3 instructions,
+       * so there is nothing to be gained here, is there?
+       *
+       * I negate WREG because either operand might share registers with
+       * result, so assigning first might destroy an operand. */
+
+      /* For the modulus operator, (a/b)*b == a shall hold.
+       * Thus: a>0, b>0 --> a/b >= 0 and a%b >= 0
+       *       a>0, b<0 --> a/b <= 0 and a%b >= 0 (e.g. 128 / -5 = -25, -25*(-5) =  125 and +3 remaining)
+       *       a<0, b>0 --> a/b <= 0 and a%b < 0  (e.g. -128 / 5 = -25, -25*  5  = -125 and -3 remaining)
+       *       a<0, b<0 --> a/b >= 0 and a%b < 0  (e.g. -128 / -5 = 25,  25*(-5) = -125 and -3 remaining)
+       * Only invert the result if the left operand is negative (sigh).
+       */
+      if (AOP_SIZE(result) <= 1 || !negated)
+      {
+        if (ic->op == '/')
+        {
+          if (IS_VALOP(right)) {
+            if (rightVal < 0) {
+              /* we negated this operand above */
+              pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+            }
+          } else if (!IS_UNSIGNED(operandType(right))) {
+            pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
+            pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+          }
+        }
+
+        if (IS_VALOP(left)) {
+          if (leftVal < 0) {
+            /* we negated this operand above */
+            pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+          }
+        } else if (!IS_UNSIGNED(operandType(left))) {
+          pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+          pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+        }
+
+        /* Move result to destination. */
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+        /* Zero-extend:  no operand was signed (or result is just a byte). */
+        pic16_addSign(result, 1, 0);
+      } else {
+        assert( AOP_SIZE(result) > 1 );
+        pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+        if (ic->op == '/')
+        {
+          if (IS_VALOP(right)) {
+            if (rightVal < 0) {
+              /* we negated this operand above */
+              pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+            }
+          } else if (!IS_UNSIGNED(operandType(right))) {
+            pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
+            pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+          }
+        }
+
+        if (IS_VALOP(left)) {
+          if (leftVal < 0) {
+            /* we negated this operand above */
+            pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+          }
+        } else if (!IS_UNSIGNED(operandType(left))) {
+          pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+          pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+        }
+
+        /* Move result to destination. */
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+        /* Negate result if required. */
+        pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(result), 1, 7));
+        pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(result), 0));
+
+        /* Sign-extend. */
+        pic16_addSign(result, 2, 1);
+      }
+
+      /* clean up stack */
+      pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
+      pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
+      goto release;
+    }
+
+#if 0
     /* special cases first */
     /* both are bits */
     if (AOP_TYPE(left) == AOP_CRY &&
@@ -4479,32 +4061,34 @@ static void genDiv (iCode *ic)
         genDivOneByte(left,right,result);
         goto release ;
     }
+#endif
 
     /* should have been converted to function call */
     assert(0);
 release :
     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(result,NULL,ic,TRUE); 
+    pic16_freeAsmop(result,NULL,ic,TRUE);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genModbits :- modulus of bits                                   */
 /*-----------------------------------------------------------------*/
-static void genModbits (operand *left, 
-                        operand *right, 
+static void genModbits (operand *left,
+                        operand *right,
                         operand *result)
 {
   char *l;
 
-    FENTRY;  
-    
+    FENTRY;
+
     werror(W_POSSBUG2, __FILE__, __LINE__);
-    /* the result must be bit */    
+    /* the result must be bit */
     pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
     l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
 
-    MOVA(l);       
+    MOVA(l);
 
     pic16_emitcode("div","ab");
     pic16_emitcode("mov","a,b");
@@ -4531,7 +4115,7 @@ static void genModOneByte (operand *left,
         /* unsigned is easy */
         pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
         l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);    
+        MOVA(l);
         pic16_emitcode("div","ab");
         pic16_aopPut(AOP(result),"b",0);
         return ;
@@ -4540,30 +4124,30 @@ static void genModOneByte (operand *left,
     /* signed is a little bit more difficult */
 
     /* save the signs of the operands */
-    l = pic16_aopGet(AOP(left),0,FALSE,FALSE);    
+    l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
     MOVA(l);
 
     pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
     pic16_emitcode("push","acc"); /* save it on the stack */
 
     /* now sign adjust for both left & right */
-    l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);    
+    l =  pic16_aopGet(AOP(right),0,FALSE,FALSE);
     MOVA(l);
 
     lbl = newiTempLabel(NULL);
-    pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
-    pic16_emitcode("cpl","a");   
+    pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
+    pic16_emitcode("cpl","a");
     pic16_emitcode("inc","a");
     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
-    pic16_emitcode("mov","b,a"); 
+    pic16_emitcode("mov","b,a");
 
     /* sign adjust left side */
-    l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);    
+    l =  pic16_aopGet(AOP(left),0,FALSE,FALSE);
     MOVA(l);
 
     lbl = newiTempLabel(NULL);
     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
-    pic16_emitcode("cpl","a");   
+    pic16_emitcode("cpl","a");
     pic16_emitcode("inc","a");
     pic16_emitcode("","%05d_DS_:",(lbl->key+100));
 
@@ -4572,8 +4156,8 @@ static void genModOneByte (operand *left,
     /* we are interested in the lower order
     only */
     lbl = newiTempLabel(NULL);
-    pic16_emitcode("pop","acc");   
-    /* if there was an over flow we don't 
+    pic16_emitcode("pop","acc");
+    /* if there was an over flow we don't
     adjust the sign of the result */
     pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
     pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
@@ -4587,18 +4171,22 @@ static void genModOneByte (operand *left,
     pic16_aopPut(AOP(result),"b",0);
 
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genMod - generates code for division                            */
 /*-----------------------------------------------------------------*/
 static void genMod (iCode *ic)
 {
+  /* Task deferred to genDiv */
+  genDiv(ic);
+#if 0
   operand *left = IC_LEFT(ic);
   operand *right = IC_RIGHT(ic);
-  operand *result= IC_RESULT(ic);  
+  operand *result= IC_RESULT(ic);
 
     FENTRY;
-    
+
     /* assign the amsops */
     pic16_aopOp (left,ic,FALSE);
     pic16_aopOp (right,ic,FALSE);
@@ -4625,7 +4213,8 @@ static void genMod (iCode *ic)
 release :
     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(result,NULL,ic,TRUE); 
+    pic16_freeAsmop(result,NULL,ic,TRUE);
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -4637,37 +4226,37 @@ release :
 static void genIfxJump (iCode *ic, char *jval)
 {
   FENTRY;
-  
+
     /* if true label then we jump if condition
     supplied is true */
     if ( IC_TRUE(ic) ) {
 
-       if(strcmp(jval,"a") == 0)
-         emitSKPZ;
-       else if (strcmp(jval,"c") == 0)
-         emitSKPNC;
-       else {
-         DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
-         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
-       }
+        if(strcmp(jval,"a") == 0)
+          emitSKPZ;
+        else if (strcmp(jval,"c") == 0)
+          emitSKPNC;
+        else {
+          DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+          pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
+        }
 
-       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
-       pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
+        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 */
-       if(strcmp(jval,"a") == 0)
-         emitSKPNZ;
-       else if (strcmp(jval,"c") == 0)
-         emitSKPC;
-       else {
-         DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
-         pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
-       }
+        if(strcmp(jval,"a") == 0)
+          emitSKPNZ;
+        else if (strcmp(jval,"c") == 0)
+          emitSKPC;
+        else {
+          DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+          pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
+        }
 
-       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
-       pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
+        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
+        pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
 
     }
 
@@ -4679,11 +4268,11 @@ static void genIfxJump (iCode *ic, char *jval)
 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__);    
+      DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__);
       pic16_emitpcode(POC_BTFSC, jop);
 
       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
@@ -4693,7 +4282,7 @@ static void genIfxpCOpJump (iCode *ic, pCodeOp *jop)
       /* 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);
     }
@@ -4764,121 +4353,18 @@ static void genSkip(iCode *ifx,int status_bit)
 static void genSkipc(resolvedIfx *rifx)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d rifx= %p",__FUNCTION__,__LINE__, rifx);
-  
+
   if(!rifx)
     return;
 
   if(rifx->condition)
-    emitSKPC;
-  else
     emitSKPNC;
-
-  pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
-  rifx->generated = 1;
-}
-
-#if !(USE_SIMPLE_GENCMP)
-/*-----------------------------------------------------------------*/
-/* genSkipz2                                                       */
-/*-----------------------------------------------------------------*/
-static void genSkipz2(resolvedIfx *rifx, int invert_condition)
-{
-  DEBUGpic16_emitcode ("; ***","%s  %d rifx= %p",__FUNCTION__,__LINE__, rifx);
-  
-  if(!rifx)
-    return;
-
-  if( (rifx->condition ^ invert_condition) & 1)
-    emitSKPZ;
-  else
-    emitSKPNZ;
-
-  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
-  rifx->generated = 1;
-}
-#endif
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* genSkipz                                                        */
-/*-----------------------------------------------------------------*/
-static void genSkipz(iCode *ifx, int condition)
-{
-  if(!ifx)
-    return;
-
-  if(condition)
-    emitSKPNZ;
-  else
-    emitSKPZ;
-
-  if ( IC_TRUE(ifx) )
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-  else
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
-
-  if ( IC_TRUE(ifx) )
-    pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
-  else
-    pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
-
-}
-#endif
-
-#if !(USE_SIMPLE_GENCMP)
-/*-----------------------------------------------------------------*/
-/* genSkipCond                                                     */
-/*-----------------------------------------------------------------*/
-static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
-{
-  if(!rifx)
-    return;
-
-  if(rifx->condition)
-    pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
   else
-    pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
-
+    emitSKPC;
 
-  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
+  pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
   rifx->generated = 1;
 }
-#endif
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* genChkZeroes :- greater or less than comparison                 */
-/*     For each byte in a literal that is zero, inclusive or the   */
-/*     the corresponding byte in the operand with W                */
-/*     returns true if any of the bytes are zero                   */
-/*-----------------------------------------------------------------*/
-static int genChkZeroes(operand *op, int lit,  int size)
-{
-
-  int i;
-  int flag =1;
-
-  while(size--) {
-    i = (lit >> (size*8)) & 0xff;
-
-    if(i==0) {
-      if(flag) 
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
-      else
-       pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
-      flag = 0;
-    }
-  }
-
-  return (flag==0);
-}
-#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    */
@@ -4897,8 +4383,6 @@ void mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) {
 /* genCmp :- greater or less than comparison                       */
 /*-----------------------------------------------------------------*/
 
-#if USE_SIMPLE_GENCMP
-
 /* genCmp performs a left < right comparison, stores
  * the outcome in result (if != NULL) and generates
  * control flow code for the ifx (if != NULL).
@@ -4920,9 +4404,9 @@ static void genCmp (operand *left,operand *right,
   int performedLt;
 
   FENTRY;
-  
-  assert (AOP_SIZE(left) == AOP_SIZE(right));
+
   assert (left && right);
+  assert (AOP_SIZE(left) == AOP_SIZE(right));
 
   size = AOP_SIZE(right) - 1;
   mask = (0x100UL << (size*8)) - 1;
@@ -4930,9 +4414,13 @@ static void genCmp (operand *left,operand *right,
   performedLt = 1;
   templbl = NULL;
   lit = 0;
-  
+
   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! *
    **********************************************************************/
@@ -4959,14 +4447,12 @@ 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
     // left < right <==> right > left <==> (right >= left + 1)
-    lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+    lit = ulFromVal (AOP(left)->aopu.aop_lit);
 
     if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) {
       // MAXVALUE < right? always false
@@ -4975,16 +4461,16 @@ 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);
+    lit = ulFromVal (AOP(right)->aopu.aop_lit);
   } // if
 
   assert (isAOP_REGlike(left)); // left must be register or the like
@@ -4997,29 +4483,25 @@ 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;
-       goto correct_result_in_carry;
+        // unsigned left < 0? always false
+        if (performedLt) emitCLRC; else emitSETC;
+        goto correct_result_in_carry;
       }
     } 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;
-       goto correct_result_in_carry;
+        // signed left < 0x80000000? always false
+        if (performedLt) emitCLRC; else emitSETC;
+        goto correct_result_in_carry;
       } else if (lit == 0) {
-       // compare left < 0; set CARRY if SIGNBIT(left) is set
-       if (performedLt) emitSETC; else emitCLRC;
-       pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet (AOP(left), size), 7));
-       if (performedLt) emitCLRC; else emitSETC;
-       goto correct_result_in_carry;
+        // compare left < 0; set CARRY if SIGNBIT(left) is set
+        if (performedLt) emitSETC; else emitCLRC;
+        pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet (AOP(left), size), 7));
+        if (performedLt) emitCLRC; else emitSETC;
+        goto correct_result_in_carry;
       }
     } // if (!sign)
   } // right is literal
@@ -5042,17 +4524,18 @@ static void genCmp (operand *left,operand *right,
       unsigned char litbyte = (lit >> (8*size)) & 0xFF;
 
       if (litbyte == 0x80) {
-       // left >= 0x80 -- always true, but more bytes to come
-       pic16_mov2w (AOP(left), size);
-       pic16_emitpcode (POC_XORLW, pic16_popGetLit (0x80)); // set ZERO flag
-       emitSETC;
+        // left >= 0x80 -- always true, but more bytes to come
+        pic16_mov2w (AOP(left), size);
+        pic16_emitpcode (POC_XORLW, pic16_popGetLit (0x80)); // set ZERO flag
+        emitSETC;
       } else {
-       // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
-       pic16_mov2w (AOP(left), size);
-       pic16_emitpcode (POC_ADDLW, pic16_popGetLit (0x80));
-       pic16_emitpcode (POC_ADDLW, pic16_popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
+        // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
+        pic16_mov2w (AOP(left), size);
+        pic16_emitpcode (POC_ADDLW, pic16_popGetLit (0x80));
+        pic16_emitpcode (POC_ADDLW, pic16_popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
       } // if
     } else {
+      /* using PRODL as a temporary register here */
       pCodeOp *pctemp = pic16_popCopyReg(&pic16_pc_prodl);
       //pCodeOp *pctemp = pic16_popGetTempReg(1);
       pic16_mov2w (AOP(left), size);
@@ -5078,12 +4561,12 @@ static void genCmp (operand *left,operand *right,
   goto result_in_carry;
 
 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) {
@@ -5109,2111 +4592,250 @@ 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
-               /* { */
-      /* original code */
-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;
-  //  resolvedIfx rTrueIfx;
-  symbol *truelbl;
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-/*
-  if(ifx) {
-    DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
-    DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
-  }
-*/
+  operand *left, *right, *result;
+  sym_link *letype , *retype;
+  int sign ;
 
-  FENTRY;
-  
-  resolveIfx(&rFalseIfx,ifx);
-  truelbl  = newiTempLabel(NULL);
-  size = max(AOP_SIZE(left),AOP_SIZE(right));
+    FENTRY;
 
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+    left = IC_LEFT(ic);
+    right= IC_RIGHT(ic);
+    result = IC_RESULT(ic);
 
-#define _swapp
+    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;
-    lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-#ifdef _swapp
+    genCmp(right, left, result, ifx, sign);
 
-    lit = (lit - 1) & mask;
-    right = left;
-    left = tmp;
-    rFalseIfx.condition ^= 1;
-#endif
+    pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+    pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+    pic16_freeAsmop(result,NULL,ic,TRUE);
+}
 
-  } else if ((AOP_TYPE(left) == AOP_LIT)) {
-    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 ) {
-    assert (0 && "bit variables used in genCmp");
-    pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-    pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-  } else {
-    /* subtract right from left if at the
-       end the carry flag is set then we know that
-       left is greater than right */
+    left = IC_LEFT(ic);
+    right= IC_RIGHT(ic);
+    result = IC_RESULT(ic);
 
-    symbol *lbl  = newiTempLabel(NULL);
+    letype = getSpec(operandType(left));
+    retype =getSpec(operandType(right));
+    sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
 
-#if 0
-       fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
-               __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
-#endif
+    /* assign the amsops */
+    pic16_aopOp (left,ic,FALSE);
+    pic16_aopOp (right,ic,FALSE);
+    pic16_aopOp (result,ic,TRUE);
 
-#ifndef _swapp
-    if(AOP_TYPE(right) == AOP_LIT) {
+    genCmp(left, right, 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);
+}
 
-      DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
+/*-----------------------------------------------------------------*/
+/* pic16_isLitOp - check if operand has to be treated as literal   */
+/*-----------------------------------------------------------------*/
+bool pic16_isLitOp(operand *op)
+{
+  return ((AOP_TYPE(op) == AOP_LIT)
+      || ( (AOP_TYPE(op) == AOP_PCODE)
+          && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
+              || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) )));
+}
 
-      /* special cases */
+/*-----------------------------------------------------------------*/
+/* pic16_isLitAop - check if operand has to be treated as literal  */
+/*-----------------------------------------------------------------*/
+bool pic16_isLitAop(asmop *aop)
+{
+  return ((aop->type == AOP_LIT)
+      || ( (aop->type == AOP_PCODE)
+          && ( (aop->aopu.pcop->type == PO_LITERAL)
+              || (aop->aopu.pcop->type == PO_IMMEDIATE) )));
+}
 
-      if(lit == 0) {
 
-       if(sign != 0) 
-         genSkipCond(&rFalseIfx,left,size-1,7);
-       else 
-         /* no need to compare to 0...*/
-         /* NOTE: this is a de-generate compare that most certainly 
-          *       creates some dead code. */
-         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
 
-       if(ifx) ifx->generated = 1;
-       return;
+/*-----------------------------------------------------------------*/
+/* genCmpEq - generates code for equal to                          */
+/*-----------------------------------------------------------------*/
+static void genCmpEq (iCode *ic, iCode *ifx)
+{
+  operand *left, *right, *result;
+  symbol *falselbl = newiTempLabel(NULL);
+  symbol *donelbl = newiTempLabel(NULL);
 
-      }
-      size--;
-
-      if(size == 0) {
-       //i = (lit >> (size*8)) & 0xff;
-       DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
-       
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-
-       i = ((0-lit) & 0xff);
-       if(sign) {
-         if( i == 0x81) { 
-           /* lit is 0x7f, all signed chars are less than
-            * this except for 0x7f itself */
-           pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
-           genSkipz2(&rFalseIfx,0);
-         } else {
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
-           genSkipc(&rFalseIfx);
-         }
-
-       } else {
-         if(lit == 1) {
-           genSkipz2(&rFalseIfx,1);
-         } else {
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
-           genSkipc(&rFalseIfx);
-         }
-       }
-
-       if(ifx) ifx->generated = 1;
-       return;
-      }
+  int preserve_result = 0;
+  int generate_result = 0;
+  int i=0;
+  unsigned long lit = -1;
 
-      /* chars are out of the way. now do ints and longs */
+  FENTRY;
 
+  pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
+  pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+  pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
-      DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
-       
-      /* special cases */
+  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
 
-      if(sign) {
+  if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
+    {
+      werror(W_POSSBUG2, __FILE__, __LINE__);
+      DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
+      fprintf(stderr, "%s  %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
+      goto release;
+    }
 
-       if(lit == 0) {
-         genSkipCond(&rFalseIfx,left,size,7);
-         if(ifx) ifx->generated = 1;
-         return;
-       }
+  if (pic16_isLitOp(left) || (AOP_TYPE(right) == AOP_ACC))
+    {
+      operand *tmp = right ;
+      right = left;
+      left = tmp;
+    }
 
-       if(lit <0x100) {
-         DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+  if (AOP_TYPE(right) == AOP_LIT) {
+    lit = ulFromVal (AOP(right)->aopu.aop_lit);
+  }
 
-         //rFalseIfx.condition ^= 1;
-         //genSkipCond(&rFalseIfx,left,size,7);
-         //rFalseIfx.condition ^= 1;
+  if ( regsInCommon(left, result) || regsInCommon(right, result) )
+    preserve_result = 1;
 
-         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-         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(0x100-lit));
-         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
-         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
-
-         while(size > 1)
-           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
+  if(result && AOP_SIZE(result))
+    generate_result = 1;
 
-         if(rFalseIfx.condition) {
-           emitSKPZ;
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-         } else {
-           emitSKPNZ;
-         }
+  if(generate_result && !preserve_result)
+    {
+      for(i = 0; i < AOP_SIZE(result); i++)
+        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
+    }
 
-         genSkipc(&rFalseIfx);
-         pic16_emitpLabel(truelbl->key);
-         if(ifx) ifx->generated = 1;
-         return;
+  assert( AOP_SIZE(left) == AOP_SIZE(right) );
+  for(i=0; i < AOP_SIZE(left); i++)
+    {
+      if(AOP_TYPE(left) != AOP_ACC)
+        {
+          if(pic16_isLitOp(left))
+            pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
+          else
+            pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
+        }
+      if(pic16_isLitOp(right)) {
+        if (pic16_isLitOp(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));
+    }
 
-       if(size == 1) {
+  // result == true
 
-         if( (lit & 0xff) == 0) {
-           /* lower byte is zero */
-           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-           i = ((lit >> 8) & 0xff) ^0x80;
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-           genSkipc(&rFalseIfx);
+  if(generate_result && preserve_result)
+    {
+      for(i = 0; i < AOP_SIZE(result); i++)
+        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
+    }
 
+  if(generate_result)
+    pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
 
-           if(ifx) ifx->generated = 1;
-           return;
+  if(generate_result && preserve_result)
+    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
 
-         }
-       } else {
-         /* Special cases for signed longs */
-         if( (lit & 0xffffff) == 0) {
-           /* lower byte is zero */
-           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-           i = ((lit >> 8*3) & 0xff) ^0x80;
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-           genSkipc(&rFalseIfx);
+  if(ifx && IC_TRUE(ifx))
+    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
 
+  if(ifx && IC_FALSE(ifx))
+    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
 
-           if(ifx) ifx->generated = 1;
-           return;
+  pic16_emitpLabel(falselbl->key);
 
-         }
+  // result == false
 
-       }
+  if(ifx && IC_FALSE(ifx))
+    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
 
+  if(generate_result && preserve_result)
+    {
+      for(i = 0; i < AOP_SIZE(result); i++)
+        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
+    }
 
-       if(lit & (0x80 << (size*8))) {
-         /* lit is negative */
-         DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+  pic16_emitpLabel(donelbl->key);
 
-         //genSkipCond(&rFalseIfx,left,size,7);
+  if(ifx)
+    ifx->generated = 1;
 
-         pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+release:
+  pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+  pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+  pic16_freeAsmop(result,NULL,ic,TRUE);
 
-         if(rFalseIfx.condition)
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-         else
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
+}
 
 
-       } else {
-         /* lit is positive */
-         DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-         if(rFalseIfx.condition)
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-         else
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
+#if 0
+// old version kept for reference
 
-       }
+/*-----------------------------------------------------------------*/
+/* genCmpEq - generates code for equal to                          */
+/*-----------------------------------------------------------------*/
+static void genCmpEq (iCode *ic, iCode *ifx)
+{
+    operand *left, *right, *result;
+    unsigned long lit = 0L;
+    int size,offset=0;
+    symbol *falselbl  = newiTempLabel(NULL);
 
-       /*
-         This works, but is only good for ints.
-         It also requires a "known zero" register.
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
-         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
-         pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
-         pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
-         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
-         genSkipc(&rFalseIfx);
 
-         pic16_emitpLabel(truelbl->key);
-         if(ifx) ifx->generated = 1;
-         return;
-       **/
-         
-       /* There are no more special cases, so perform a general compare */
-  
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
-       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-       while(size--) {
+    if(ifx)
+      DEBUGpic16_emitcode ("; ifx is non-null","");
+    else
+      DEBUGpic16_emitcode ("; ifx is null","");
 
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
-         emitSKPNZ;
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-       }
-       //rFalseIfx.condition ^= 1;
-       genSkipc(&rFalseIfx);
-
-       pic16_emitpLabel(truelbl->key);
-
-       if(ifx) ifx->generated = 1;
-       return;
-
-
-      }
-
-
-      /* sign is out of the way. So now do an unsigned compare */
-      DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
-
-
-      /* General case - compare to an unsigned literal on the right.*/
-
-      i = (lit >> (size*8)) & 0xff;
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),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(left),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(left),size));
-       }
-      }
-
-
-      pic16_emitpLabel(lbl->key);
-//     pic16_emitpLabel(truelbl->key);
-      //if(emitFinalCheck)
-      genSkipc(&rFalseIfx);
-      if(sign)
-       pic16_emitpLabel(truelbl->key);
-
-      if(ifx) ifx->generated = 1;
-      return;
-
-
-    }
-#endif  // _swapp
-
-    if(AOP_TYPE(left) == AOP_LIT) {
-      //symbol *lbl = newiTempLabel(NULL);
-
-      //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
-
-
-      DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
-
-      /* Special cases */
-      if((lit == 0) && (sign == 0)){
-
-       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 */
-
-         int lp1 = (lit+1) & 0xff;
-
-         DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
-         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_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 */
-
-         switch(lit & 0xff ) {
-         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;
-
-           if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-             goto check_carry;
-
-           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;
-
-           if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-             goto check_carry;
-
-           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));
-
-           if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) {
-             emitTOGC;
-             if(ifx) ifx->generated = 1;
-             goto check_carry;
-           } else {
-             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;
-
-
-          if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-            goto check_carry;
-
-         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;
-
-            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-              goto check_carry;
-
-           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;
-
-            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-              goto check_carry;
-
-       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;
-
-            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-              goto check_carry;
-
-       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;
-
-
-            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-              goto check_carry;
-
-    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 */
-  }
-
-}
-
-#else  /* old version of genCmp() */   /* } else { */
-
-/* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
-static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
-        operand *result, int offset, int invert_op)
-{
-  /* add code here */
-  
-  /* check condition, > or < ?? */
-  if(rIfx->condition != 0)invert_op ^= 1;
-  
-  if(ifx && IC_FALSE(ifx))invert_op ^= 1;
-
-  if(!ifx)invert_op ^= 1;
-
-  DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
-      __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
-  
-  /* do selection */
-  if(!invert_op)return POC_CPFSGT;
-  else return POC_CPFSLT;
-}
-
-static int compareAopfirstpass=1;
-
-static void compareAop(resolvedIfx *resIfx, iCode *ifx, symbol *falselbl,
-            operand *oper, int offset, operand *result,
-            int sign, int invert_op, pCodeOp *pcop, pCodeOp *pcop2,
-            symbol *tlbl)
-{
-  int op;
-  symbol *truelbl;
-
-  /* invert if there is a result to be loaded, in order to fit,
-   * SETC/CLRC sequence */
-  if(AOP_SIZE(result))invert_op ^= 1;
-
-//  if(sign && !offset)invert_op ^= 1;
-  
-//  if(sign)invert_op ^= 1;
-  
-  op = selectCompareOp(resIfx, ifx, result, offset, invert_op);
-
-  if(AOP_SIZE(result) && compareAopfirstpass) {
-    if(!ifx) {
-      if(pcop2)
-        pic16_emitpcode(POC_SETF, pcop2);
-      else
-        emitSETC;
-    } else {
-      if(pcop2)
-        pic16_emitpcode(POC_CLRF, pcop2);
-      else
-        emitCLRC;
-    }
-  }
-
-  compareAopfirstpass = 0;
-
-      /* there is a bug when comparing operands with size > 1,
-       * because higher bytes can be equal and test should be performed
-       * to the next lower byte, current algorithm, considers operands
-       * inequal in these cases! -- VR 20041107 */
-
-    
-  if(pcop)
-    pic16_emitpcode(op, pcop);
-  else
-    pic16_emitpcode(op, pic16_popGet(AOP(oper), offset));
-
-
-  if((!sign || !offset) && AOP_SIZE(result)) {
-    if(!ifx) {
-      if(pcop2)
-        pic16_emitpcode(POC_CLRF, pcop2);
-        else
-        emitCLRC;
-    } else {
-      if(pcop2)
-        pic16_emitpcode(POC_SETF, pcop2);
-      else
-        emitSETC;
-    }
-    
-    /* don't emit final branch (offset == 0) */
-    if(offset) {
-
-      if(pcop2)
-        pic16_emitpcode(POC_RRCF, pcop2);
-
-      pic16_emitpcode(POC_BNC, pic16_popGetLabel(falselbl->key));
-    }
-  } else {
-    if((ifx && (IC_TRUE(ifx)!=NULL)) || (sign && !offset)) {
-      DEBUGpic16_emitcode ("; +++","%s: %d: ifx = %p, IC_TRUE(ifx) = %d, sign = %d, offset = %d",
-            __FUNCTION__, __LINE__, ifx, (ifx&&IC_TRUE(ifx)), sign, offset);
-
-      truelbl = newiTempLabel( NULL );
-      pic16_emitpcode(POC_BRA, pic16_popGetLabel(truelbl->key));
-      if((!ifx || !IC_TRUE(ifx)) && (sign && !offset))
-        pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
-      else
-        pic16_emitpcode(POC_GOTO, pic16_popGetLabel(resIfx->lbl->key));
-      pic16_emitpLabel(truelbl->key);
-    } else {
-      pic16_emitpcode(POC_GOTO, pic16_popGetLabel(resIfx->lbl->key));
-    }
-  }
-}
-
-
-  
-
-#if 1  /* { */
-static void genCmp (operand *left, operand *right,
-                    operand *result, iCode *ifx, int sign)
-{
-  int size, cmpop=1;
-  long lit = 0L;
-  resolvedIfx rFalseIfx;
-  symbol *falselbl, *tlbl;
-
-    FENTRY;
-    
-    DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
-    resolveIfx(&rFalseIfx, ifx);
-    size = max(AOP_SIZE(left), AOP_SIZE(right));
-    
-    /* if left & right are bit variables */
-    if(AOP_TYPE(left) == AOP_CRY
-      && AOP_TYPE(right) == AOP_CRY ) {
-
-        pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-        pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-        
-        werror(W_POSSBUG2, __FILE__, __LINE__);
-        exit(-1);
-    }
-    
-    /* if literal is on the right then swap with left */
-    if((AOP_TYPE(right) == AOP_LIT)) {
-      operand *tmp = right ;
-//      unsigned long mask = (0x100 << (8*(size-1))) - 1;
-
-        lit = /*(unsigned long)*/floatFromVal(AOP(right)->aopu.aop_lit);
-
-//      lit = (lit - 1) & mask;
-        right = left;
-        left = tmp;
-        rFalseIfx.condition ^= 1;              /* reverse compare */
-    } else
-    if ((AOP_TYPE(left) == AOP_LIT)) {
-      /* float compares are handled by support functions */
-      lit = /*(unsigned long)*/floatFromVal(AOP(left)->aopu.aop_lit);
-    }
-
-    /* actual comparing algorithm */
-//    size = AOP_SIZE( right );
-
-    falselbl = newiTempLabel( NULL );
-    if(AOP_TYPE(left) == AOP_LIT) {
-      /* compare to literal */
-      DEBUGpic16_emitcode ("; ***","%s: %d: compare to literal", __FUNCTION__, __LINE__);
-      
-      if(sign) {
-        pCodeOp *pct, *pct2;
-        symbol *tlbl1;
-
-        /* signed compare */
-        DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
-
-        pct = pic16_popCopyReg(&pic16_pc_prodl);
-        pct2 = pic16_popCopyReg(&pic16_pc_prodh);
-        tlbl = newiTempLabel( NULL );
-        
-        /* first compare signs:
-         *  a. if both are positive, compare just like unsigned
-         *  b. if both are negative, invert cmpop, compare just like unsigned
-         *  c. if different signs, determine the result directly */
-
-        size--;
-
-#if 1
-       /* { */
-        tlbl1 = newiTempLabel( NULL );
-//        pic16_emitpcode(POC_RLCFW, pic16_popGet( AOP(right), size)); /* move sign to carry */
-
-        if(lit > 0) {
-
-          /* literal is zero or positive:
-           *  a. if carry is zero, too, continue compare,
-           *  b. if carry is set, then continue depending on cmpop ^ condition:
-           *   1. '<' return false (literal < variable),
-           *   2. '>' return true (literal > variable) */
-//          pic16_emitpcode(POC_BNC, pic16_popGetLabel( tlbl1->key ));
-          pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-          
-          
-          if(cmpop ^ rFalseIfx.condition)pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
-          else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key ));
-        } else 
-        if(lit < 0) {
-          
-          /* literal is negative:
-           *  a. if carry is set, too, continue compare,
-           *  b. if carry is zero, then continue depending on cmpop ^ condition:
-           *   1. '<' return true (literal < variable),
-           *   2. '>' return false (literal > variable) */
-//          pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key ));
-          pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-          
-          if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
-          else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
-        }
-#if 1
-        else {
-          /* lit == 0 */
-          pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-          
-          if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
-          else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
-        }
-#endif
-        
-        
-        pic16_emitpLabel( tlbl1->key );
-#endif /* } */
-
-        compareAopfirstpass=1;
-//        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-//        pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
-//        pic16_emitpcode(POC_MOVWF, pct);
-
-//        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
-        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
-//        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
-
-        /* generic case */        
-          while( size-- ) {
-//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0));
-//            pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
-//            pic16_emitpcode(POC_MOVWF, pct);
-
-//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
-            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x0));
-            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
-//            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-//            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
-          }
-//        }
-        
-        if(ifx)ifx->generated = 1;
-
-        if(AOP_SIZE(result)) {
-          pic16_emitpLabel(tlbl->key);
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitOp( result, pct2 );
-        } else {
-          pic16_emitpLabel(tlbl->key);
-        }
-      } else {
-
-
-        /* unsigned compare */      
-        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-    
-        compareAopfirstpass=1;
-        while(size--) {
-          
-          pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
-          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
-
-        }
-
-        if(ifx)ifx->generated = 1;
-
-
-        if(AOP_SIZE(result)) {
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitC( result );
-        }
-
-      }
-    } else {
-      /* compare registers */
-      DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__);
-
-
-      if(sign) {
-        pCodeOp *pct, *pct2;
-        
-        /* signed compare */
-        DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
-
-        pct = pic16_popCopyReg(&pic16_pc_prodl);       /* first temporary register */
-        pct2 = pic16_popCopyReg(&pic16_pc_prodh);      /* second temporary register */
-        tlbl = newiTempLabel( NULL );
-        
-        compareAopfirstpass=1;
-
-        size--;
-        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-        pic16_emitpcode(POC_MOVWF, pct);
-
-        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
-        /* WREG already holds left + 0x80 */
-        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-        
-        while( size-- ) {
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-          pic16_emitpcode(POC_MOVWF, pct);
-                
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
-          /* WREG already holds left + 0x80 */
-          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-//          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
-        }
-        
-        if(ifx)ifx->generated = 1;
-
-        if(AOP_SIZE(result)) {
-          pic16_emitpLabel(tlbl->key);
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitOp( result, pct2 );
-        } else {
-          pic16_emitpLabel(tlbl->key);
-        }
-
-      } else {
-        /* unsigned compare */      
-        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-
-        compareAopfirstpass=1;
-        while(size--) {
-          
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
-
-        }
-
-        if(ifx)ifx->generated = 1;
-        if(AOP_SIZE(result)) {
-
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitC( result );
-        }
-
-      }
-    }
-}
-
-#else    /* } else { */
-
-/* new version of genCmp -- VR 20041012 */
-static void genCmp (operand *left,operand *right,
-                    operand *result, iCode *ifx, int sign)
-{
-  int size; //, offset = 0 ;
-  unsigned long lit = 0L,i = 0;
-  resolvedIfx rFalseIfx;
-  int willCheckCarry=0;
-  //  resolvedIfx rTrueIfx;
-  symbol *truelbl;
-
-    FENTRY;
-  
-  /* General concept:
-   * subtract right from left if at the end the carry flag is set then we
-   * know that left is greater than right */
-            
-  resolveIfx(&rFalseIfx,ifx);
-  truelbl  = newiTempLabel(NULL);
-  size = max(AOP_SIZE(left),AOP_SIZE(right));
-
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
-  /* POC_CPFSGT        compare f, wreg, skip if f greater than wreg
-   * POC_CPFSLT compare f, wreg, skip if f less then wreg */
-  
-
-  /* if literal is on the right then swap with left */
-  if ((AOP_TYPE(right) == AOP_LIT)) {
-    operand *tmp = right ;
-    unsigned long mask = (0x100 << (8*(size-1))) - 1;
-
-      lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
-//      lit = (lit - 1) & mask;
-      right = left;
-      left = tmp;
-      rFalseIfx.condition ^= 1;                /* reverse compare */
-  } else
-  if ((AOP_TYPE(left) == AOP_LIT)) {
-    /* float compares are handled by support functions */
-    lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
-  }
-
-
-  //if(IC_TRUE(ifx) == NULL)
-  /* if left & right are bit variables */
-  if (AOP_TYPE(left) == AOP_CRY &&
-      AOP_TYPE(right) == AOP_CRY ) {
-
-    pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-    pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-
-  } else {
-    symbol *lbl  = newiTempLabel(NULL);
-
-    if(AOP_TYPE(left) == AOP_LIT) {
-      DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
-
-      if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-        willCheckCarry = 1;
-      else willCheckCarry = 0;
-
-      /* Special cases */
-      if((lit == 0) && (sign == 0)) {
-        /* unsigned compare to 0 */
-        DEBUGpic16_emitcode("; unsigned compare to 0","lit = 0x%x, sign=%d",lit,sign);
-        
-       size--;
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-       while(size) 
-         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
-
-       genSkipz2(&rFalseIfx,0);
-       if(ifx)ifx->generated = 1;
-       return;
-      }
-
-      if(size==1) {
-       /* Special cases */
-       lit &= 0xff;
-       if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
-         /* degenerate compare can never be true */
-         if(rFalseIfx.condition == 0)
-           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
-
-         if(ifx) ifx->generated = 1;
-         return;
-       }
-
-       if(sign) {
-         /* signed comparisons to a literal byte */
-          DEBUGpic16_emitcode(";signed compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
-         int lp1 = (lit+1) & 0xff;
-
-         DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d lp1 = %i",__LINE__,lit, rFalseIfx.condition, lp1);
-         switch (lp1) {
-         case 0:
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,0,7);
-           break;
-         case 0x7f:
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
-           genSkipz2(&rFalseIfx,1);
-           break;
-         default:
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
-           
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
-            else
-              pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
-
-           if(willCheckCarry) {
-              if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
-              else { emitSETC; emitCLRC; }
-              
-            } else {
-              pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
-            }              
-                     
-/*         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
-           rFalseIfx.condition ^= 1;
-           genSkipc(&rFalseIfx);
-*/
-           break;
-         }
-       } else {
-         /* unsigned comparisons to a literal byte */
-          DEBUGpic16_emitcode("; unsigned compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
-         switch(lit & 0xff ) {
-                         /* special cases */
-         case 0:
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           genSkipz2(&rFalseIfx,0);
-           break;
-         case 0x7f:
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,0,7);
-           break;
-         default:
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
-           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-           DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-           rFalseIfx.condition ^= 1;
-           if (AOP_TYPE(result) == AOP_CRY)
-             genSkipc(&rFalseIfx);
-           else {
-             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
-             pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
-           }         
-           break;
-         }
-       }
-
-       if(ifx) ifx->generated = 1;
-       if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-               goto check_carry;
-       return;
-
-      } else {
-
-       /* Size is greater than 1 */
-
-       if(sign) {
-         int lp1 = lit+1;
-
-         size--;
-
-         if(lp1 == 0) {
-           /* this means lit = 0xffffffff, or -1 */
-
-
-           DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,size,7);
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if(lit == 0) {
-           int s = size;
-
-           if(rFalseIfx.condition) {
-             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-           }
-
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-           while(size--)
-             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-
-           emitSKPZ;
-           if(rFalseIfx.condition) {
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-             pic16_emitpLabel(truelbl->key);
-           }else {
-             rFalseIfx.condition ^= 1;
-             genSkipCond(&rFalseIfx,right,s,7);
-           }
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if((size == 1) &&  (0 == (lp1&0xff))) {
-           /* lower byte of signed word is zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
-           i = ((lp1 >> 8) & 0xff) ^0x80;
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-           rFalseIfx.condition ^= 1;
-           genSkipc(&rFalseIfx);
-
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if(lit & (0x80 << (size*8))) {
-           /* Lit is less than zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
-           //rFalseIfx.condition ^= 1;
-           //genSkipCond(&rFalseIfx,left,size,7);
-           //rFalseIfx.condition ^= 1;
-           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-           //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-           else
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-
-         } else {
-           /* Lit is greater than or equal to zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
-           //rFalseIfx.condition ^= 1;
-           //genSkipCond(&rFalseIfx,right,size,7);
-           //rFalseIfx.condition ^= 1;
-
-           //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
-           //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-
-           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-           else
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-
-         }
-
-
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
-         while(size--) {
-
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
-           emitSKPNZ;
-           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-         }
-         rFalseIfx.condition ^= 1;
-         //rFalseIfx.condition = 1;
-         genSkipc(&rFalseIfx);
-
-         pic16_emitpLabel(truelbl->key);
-
-         if(ifx) ifx->generated = 1;
-         return;
-         // end of if (sign)
-       } else {
-
-         /* compare word or long to an unsigned literal on the right.*/
-
-
-         size--;
-         if(lit < 0xff) {
-           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
-           switch (lit) {
-           case 0:
-             break; /* handled above */
-/*
-           case 0xff:
-             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-             while(size--)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-             genSkipz2(&rFalseIfx,0);
-             break;
-*/
-           default:
-             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-             while(--size)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-             emitSKPZ;
-             if(rFalseIfx.condition)
-               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-             else
-               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-
-             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
-             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-
-             rFalseIfx.condition ^= 1;
-             genSkipc(&rFalseIfx);
-           }
-
-           pic16_emitpLabel(truelbl->key);
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-
-         lit++;
-         DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
-         i = (lit >> (size*8)) & 0xff;
-
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
-         while(size--) {
-           i = (lit >> (size*8)) & 0xff;
-
-           if(i) {
-             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-             emitSKPNZ;
-             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-           } else {
-             /* this byte of the lit is zero, 
-              * if it's not the last then OR in the variable */
-             if(size)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-           }
-         }
-
-
-         pic16_emitpLabel(lbl->key);
-
-         rFalseIfx.condition ^= 1;
-
-         genSkipc(&rFalseIfx);
-       }
-
-       if(sign)
-         pic16_emitpLabel(truelbl->key);
-       if(ifx) ifx->generated = 1;
-       return;
-      }
-    }
-    /* Compare two variables */
-
-    DEBUGpic16_emitcode(";sign","%d",sign);
-
-    size--;
-    if(sign) {
-      /* Sigh. thus sucks... */
-      if(size) {
-       pCodeOp *pctemp;
-       
-       pctemp = pic16_popGetTempReg(1);
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-       pic16_emitpcode(POC_MOVWF, pctemp);             //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-       pic16_emitpcode(POC_XORWF, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
-       pic16_emitpcode(POC_SUBFW, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_popReleaseTempReg(pctemp, 1);
-      } else {
-       /* Signed char comparison */
-       /* Special thanks to Nikolai Golovchenko for this snippet */
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
-       pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       genSkipc(&rFalseIfx);
-         
-       if(ifx) ifx->generated = 1;
-       return;
-      }
-
-    } else {
-
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-    }
-
-
-    /* The rest of the bytes of a multi-byte compare */
-    while (size) {
-
-      emitSKPZ;
-      pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
-      size--;
-
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-
-
-    }
-
-    pic16_emitpLabel(lbl->key);
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
-       (AOP_TYPE(result) == AOP_REG)) {
-      pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
-    } else {
-      genSkipc(&rFalseIfx);
-    }        
-    //genSkipc(&rFalseIfx);
-    if(ifx) ifx->generated = 1;
-
-    return;
-
-  }
-
-check_carry:
-  if ((AOP_TYPE(result) != AOP_CRY) 
-       && AOP_SIZE(result)) {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
-
-    pic16_outBitC(result);
-  } else {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if the result is used in the next
-       ifx conditional branch then generate
-       code a little differently */
-    if (ifx )
-      genIfxJump (ifx,"c");
-    else
-      pic16_outBitC(result);
-    /* leave the result in acc */
-  }
-
-}
-#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));
-
-    /* assign the amsops */
-    pic16_aopOp (left,ic,FALSE);
-    pic16_aopOp (right,ic,FALSE);
-    pic16_aopOp (result,ic,TRUE);
-
-    genCmp(left, right, 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); 
-}
-
-#if 0
-// not needed ATM
-// FIXME reenable literal optimisation when the pic16 port is stable
-
-/*-----------------------------------------------------------------*/
-/* genc16bit2lit - compare a 16 bit value to a literal             */
-/*-----------------------------------------------------------------*/
-static void genc16bit2lit(operand *op, int lit, int offset)
-{
-  int i;
-
-  DEBUGpic16_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
-  if( (lit&0xff) == 0) 
-    i=1;
-  else
-    i=0;
-
-  switch( BYTEofLONG(lit,i)) { 
-  case 0:
-    pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
-    break;
-  case 1:
-    pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
-    break;
-  case 0xff:
-    pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
-    break;
-  default:
-    pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
-    pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
-  }
-
-  i ^= 1;
-
-  switch( BYTEofLONG(lit,i)) { 
-  case 0:
-    pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
-    break;
-  case 1:
-    emitSKPNZ;
-    pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
-    break;
-  case 0xff:
-    emitSKPNZ;
-    pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
-    break;
-  default:
-    pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
-    emitSKPNZ;
-    pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
-
-  }
-
-}
-#endif
-
-#if 0
-// not needed ATM
-/*-----------------------------------------------------------------*/
-/* gencjneshort - compare and jump if not equal                    */
-/*-----------------------------------------------------------------*/
-static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
-{
-  int size = max(AOP_SIZE(left),AOP_SIZE(right));
-  int offset = 0;
-  int res_offset = 0;  /* the result may be a different size then left or right */
-  int res_size = AOP_SIZE(result);
-  resolvedIfx rIfx;
-  symbol *lbl, *lbl_done;
-
-  unsigned long lit = 0L;
-  int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
-
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-  if(result)
-    DEBUGpic16_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
-  resolveIfx(&rIfx,ifx);
-  lbl =  newiTempLabel(NULL);
-  lbl_done =  newiTempLabel(NULL);
-
-
-  /* if the left side is a literal or 
-     if the right is in a pointer register and left 
-     is not */
-  if ((AOP_TYPE(left) == AOP_LIT) || 
-      (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
-    operand *t = right;
-    right = left;
-    left = t;
-  }
-  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;
-
-  if(result && !preserve_result)
-    {
-      int i;
-      for(i = 0; i < AOP_SIZE(result); i++)
-        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
-    }
-
-
-  /* if the right side is a literal then anything goes */
-  if (AOP_TYPE(right) == AOP_LIT &&
-      AOP_TYPE(left) != AOP_DIR ) {
-    switch(size) {
-    case 2:
-      genc16bit2lit(left, lit, 0);
-      emitSKPZ;
-      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
-      break;
-    default:
-      DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-      while (size--) {
-       if(lit & 0xff) {
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-         pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
-       } else {
-         pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
-       }
-
-       emitSKPZ;
-       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
-       offset++;
-       if(res_offset < res_size-1)
-         res_offset++;
-       lit >>= 8;
-      }
-      break;
-    }
-  }
-
-  /* if the right side is in a register or in direct space or
-     if the left is a pointer register & right is not */    
-  else if (AOP_TYPE(right) == AOP_REG ||
-          AOP_TYPE(right) == AOP_DIR || 
-          (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
-          (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
-    //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
-    int lbl_key = lbl->key;
-
-    if(result) {
-      // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
-      //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
-    }else {
-      DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
-      fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
-             __FUNCTION__,__LINE__);
-      return;
-    }
-   
-/*     switch(size) { */
-/*     case 2: */
-/*       genc16bit2lit(left, lit, 0); */
-/*       emitSKPNZ; */
-/*       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
-/*       break; */
-/*     default: */
-    while (size--) {
-      int emit_skip=1;
-      if((AOP_TYPE(left) == AOP_DIR) && 
-        ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
-
-       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
-
-      } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
-           
-       switch (lit & 0xff) {
-       case 0:
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-         break;
-       case 1:
-         pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
-         //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
-         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
-         emit_skip=0;
-         break;
-       case 0xff:
-         pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
-         //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
-         //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
-         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
-         emit_skip=0;
-         break;
-       default:
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-         pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
-       }
-       lit >>= 8;
-
-      } else {
-       pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
-      }
-      if(emit_skip) {
-       if(AOP_TYPE(result) == AOP_CRY) {
-         pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
-         if(rIfx.condition)
-           emitSKPNZ;
-         else
-           emitSKPZ;
-         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
-       } else {
-         /* fix me. probably need to check result size too */
-         //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
-         if(rIfx.condition)
-           emitSKPZ;
-         else
-           emitSKPNZ;
-         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
-         //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
-       }
-       if(ifx)
-         ifx->generated=1;
-      }
-      emit_skip++;
-      offset++;
-      if(res_offset < res_size-1)
-       res_offset++;
-    }
-/*       break; */
-/*     } */
-  } else if(AOP_TYPE(right) == AOP_REG &&
-           AOP_TYPE(left) != AOP_DIR){
-
-    while(size--) {
-      pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-      pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
-      pic16_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
-      if(rIfx.condition)
-       emitSKPNZ;
-      else
-       emitSKPZ;
-      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
-      offset++;
-      if(res_offset < res_size-1)
-       res_offset++;
-    }
-      
-  }else{
-    /* right is a pointer reg need both a & b */
-    while(size--) {
-      char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
-      if(strcmp(l,"b"))
-       pic16_emitcode("mov","b,%s",l);
-      MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-      pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
-      offset++;
-    }
-  }
-
-  if(result && preserve_result)
-    {
-      int i;
-      for(i = 0; i < AOP_SIZE(result); i++)
-        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
-    }
-
-  pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
-
-  if(result && preserve_result)
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
-
-  if(!rIfx.condition)
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
-
-  pic16_emitpLabel(lbl->key);
-
-  if(result && preserve_result)
-    {
-      int i;
-      for(i = 0; i < AOP_SIZE(result); i++)
-        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
-
-      pic16_emitpLabel(lbl_done->key);
-   }
-
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  if(ifx)
-    ifx->generated = 1;
-}
-#endif
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* gencjne - compare and jump if not equal                         */
-/*-----------------------------------------------------------------*/
-static void gencjne(operand *left, operand *right, iCode *ifx)
-{
-    symbol *tlbl  = newiTempLabel(NULL);
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    gencjneshort(left, right, lbl);
-
-    pic16_emitcode("mov","a,%s",one);
-    pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
-    pic16_emitcode("","%05d_DS_:",lbl->key+100);
-    pic16_emitcode("clr","a");
-    pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-
-    pic16_emitpLabel(lbl->key);
-    pic16_emitpLabel(tlbl->key);
-
-}
-#endif
-
-
-/*-----------------------------------------------------------------*/
-/* is_LitOp - check if operand has to be treated as literal        */
-/*-----------------------------------------------------------------*/
-static bool is_LitOp(operand *op)
-{
-  return ((AOP_TYPE(op) == AOP_LIT)
-      || ( (AOP_TYPE(op) == AOP_PCODE)
-          && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
-              || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) )));
-}
-
-/*-----------------------------------------------------------------*/
-/* is_LitAOp - check if operand has to be treated as literal        */
-/*-----------------------------------------------------------------*/
-static bool is_LitAOp(asmop *aop)
-{
-  return ((aop->type == AOP_LIT)
-      || ( (aop->type == AOP_PCODE)
-          && ( (aop->aopu.pcop->type == PO_LITERAL)
-              || (aop->aopu.pcop->type == PO_IMMEDIATE) )));
-}
-
-
-
-/*-----------------------------------------------------------------*/
-/* genCmpEq - generates code for equal to                          */
-/*-----------------------------------------------------------------*/
-static void genCmpEq (iCode *ic, iCode *ifx)
-{
-  operand *left, *right, *result;
-  symbol *falselbl = newiTempLabel(NULL);
-  symbol *donelbl = newiTempLabel(NULL);
-
-  int preserve_result = 0;
-  int generate_result = 0;
-  int i=0;
-  unsigned long lit = -1;
-
-  FENTRY;
-  
-  pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
-  pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-  pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
-  if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
-    {
-      werror(W_POSSBUG2, __FILE__, __LINE__);
-      DEBUGpic16_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
-      fprintf(stderr, "%s  %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
-      goto release;
-    }
-
-  if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
-    {
-      operand *tmp = right ;
-      right = left;
-      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;
-
-  if(result && AOP_SIZE(result))
-    generate_result = 1;
-
-  if(generate_result && !preserve_result)
-    {
-      for(i = 0; i < AOP_SIZE(result); i++)
-        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
-    }
-
-  for(i=0; i < AOP_SIZE(left); i++)
-    {
-      if(AOP_TYPE(left) != AOP_ACC)
-        {
-          if(is_LitOp(left))
-            pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
-          else
-            pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
-        }
-      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));
-    }
-
-  // result == true
-
-  if(generate_result && preserve_result)
-    {
-      for(i = 0; i < AOP_SIZE(result); i++)
-        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
-    }
-
-  if(generate_result)
-    pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
-
-  if(generate_result && preserve_result)
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
-
-  if(ifx && IC_TRUE(ifx))
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-
-  if(ifx && IC_FALSE(ifx))
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
-
-  pic16_emitpLabel(falselbl->key);
-
-  // result == false
-
-  if(ifx && IC_FALSE(ifx))
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
-
-  if(generate_result && preserve_result)
-    {
-      for(i = 0; i < AOP_SIZE(result); i++)
-        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
-    }
-
-  pic16_emitpLabel(donelbl->key);
-
-  if(ifx)
-    ifx->generated = 1;
-
-release:
-  pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-  pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-  pic16_freeAsmop(result,NULL,ic,TRUE);
-
-}
-
-
-#if 0
-// old version kept for reference
-
-/*-----------------------------------------------------------------*/
-/* genCmpEq - generates code for equal to                          */
-/*-----------------------------------------------------------------*/
-static void genCmpEq (iCode *ic, iCode *ifx)
-{
-    operand *left, *right, *result;
-    unsigned long lit = 0L;
-    int size,offset=0;
-    symbol *falselbl  = newiTempLabel(NULL);
-
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    if(ifx)
-      DEBUGpic16_emitcode ("; ifx is non-null","");
-    else
-      DEBUGpic16_emitcode ("; ifx is null","");
-
-    pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
-    pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-    pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
+    pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
+    pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+    pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
     size = max(AOP_SIZE(left),AOP_SIZE(right));
 
     DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
 
-    /* if literal, literal on the right or 
-    if the right is in a pointer register and left 
+    /* if literal, literal on the right or
+    if the right is in a pointer register and left
     is not */
-    if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
-        (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+    if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT)) {
       operand *tmp = right ;
       right = left;
       left = tmp;
@@ -7222,13 +4844,13 @@ static void genCmpEq (iCode *ic, iCode *ifx)
 
     if(ifx && !AOP_SIZE(result)){
         symbol *tlbl;
-       DEBUGpic16_emitcode ("; ***","%s  %d CASE 1",__FUNCTION__,__LINE__);
+        DEBUGpic16_emitcode ("; ***","%s  %d CASE 1",__FUNCTION__,__LINE__);
         /* if they are both bit variables */
         if (AOP_TYPE(left) == AOP_CRY &&
             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
-               DEBUGpic16_emitcode ("; ***","%s  %d CASE 11",__FUNCTION__,__LINE__);
+                DEBUGpic16_emitcode ("; ***","%s  %d CASE 11",__FUNCTION__,__LINE__);
             if(AOP_TYPE(right) == AOP_LIT){
-                unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+                unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
                 if(lit == 0L){
                     pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
                     pic16_emitcode("cpl","c");
@@ -7257,170 +4879,170 @@ static void genCmpEq (iCode *ic, iCode *ifx)
             }
             pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
 
-               {
-               /* left and right are both bit variables, result is carry */
-                       resolvedIfx rIfx;
-             
-                       resolveIfx(&rIfx,ifx);
-
-                       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
-                       pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
-                       pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
-                       pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
-                       genSkipz2(&rIfx,0);
-               }
+                {
+                /* left and right are both bit variables, result is carry */
+                        resolvedIfx rIfx;
+
+                        resolveIfx(&rIfx,ifx);
+
+                        pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
+                        pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
+                        pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
+                        pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
+                        genSkipz2(&rIfx,0);
+                }
         } else {
 
-                       DEBUGpic16_emitcode ("; ***","%s  %d CASE 12",__FUNCTION__,__LINE__);
-
-                       /* They're not both bit variables. Is the right a literal? */
-                       if(AOP_TYPE(right) == AOP_LIT) {
-                       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-           
-                       switch(size) {
-
-                               case 1:
-                                       switch(lit & 0xff) {
-                                               case 1:
-                                                               if ( IC_TRUE(ifx) ) {
-                                                                       pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
-                                                                       emitSKPNZ;
-                                                                       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-                                                               } else {
-                                                                       pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
-                                                                       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
-                                                               }
-                                                               break;
-                                               case 0xff:
-                                                               if ( IC_TRUE(ifx) ) {
-                                                                       pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
-                                                                       emitSKPNZ;
-                                                                       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-                                                               } else {
-                                                                       pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
-                                                                       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
-                                                               }
-                                                               break;
-                                               default:
-                                                               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-                                                               if(lit)
-                                                                       pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
-                                                               genSkip(ifx,'z');
-                                       } // switch lit
-
-
-                                       /* end of size == 1 */
-                                       break;
-             
-                               case 2:
-                                       genc16bit2lit(left,lit,offset);
-                                       genSkip(ifx,'z');
-                                       break;
-                                       /* end of size == 2 */
-
-                               default:
-                                       /* size is 4 */
-                                       if(lit==0) {
-                                               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
-                                               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
-                                               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
-                                               pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
-                                               genSkip(ifx,'z');
-                                       } else {
-                                               /* search for patterns that can be optimized */
-
-                                               genc16bit2lit(left,lit,0);
-                                               lit >>= 16;
-                                               if(lit) {
-                                                               if(IC_TRUE(ifx))
-                                                               emitSKPZ; // if hi word unequal
-                                                               else
-                                                               emitSKPNZ; // if hi word equal
-                                                               // fail early
-                                                       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
-                                                       genc16bit2lit(left,lit,2);
-                                                       genSkip(ifx,'z');
-                                               } else {
-                                                       pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
-                                                       pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
-                                                       genSkip(ifx,'z');
-                                               }
-                                       }
-                                               pic16_emitpLabel(falselbl->key);
-                                               break;
-
-                       } // switch size
-         
-                       ifx->generated = 1;
-                       goto release ;
-           
-
-         } else if(AOP_TYPE(right) == AOP_CRY ) {
-           /* we know the left is not a bit, but that the right is */
-           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-           pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
-                     pic16_popGet(AOP(right),offset));
-           pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
-
-           /* if the two are equal, then W will be 0 and the Z bit is set
-            * we could test Z now, or go ahead and check the high order bytes if
-            * the variable we're comparing is larger than a byte. */
-
-           while(--size)
-             pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
-
-           if ( IC_TRUE(ifx) ) {
-             emitSKPNZ;
-             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-             // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
-           } else {
-             emitSKPZ;
-             pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
-             // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
-           }
-
-         } else {
-           /* They're both variables that are larger than bits */
-           int s = size;
-
-           tlbl = newiTempLabel(NULL);
-
-           while(size--) {
-             pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-             pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
-
-             if ( IC_TRUE(ifx) ) {
-               if(size) {
-                 emitSKPZ;
-               
-                       DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
-
-                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-                 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
-               } else {
-                 emitSKPNZ;
-
-                       DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
-
-
-                 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-                 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
-               }
-             } else {
-               emitSKPZ;
-
-                       DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
-
-               pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
-               pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
-             }
-             offset++;
-           }
-           if(s>1 && IC_TRUE(ifx)) {
-             pic16_emitpLabel(tlbl->key);
-             pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);                
-           }
-         }
+                        DEBUGpic16_emitcode ("; ***","%s  %d CASE 12",__FUNCTION__,__LINE__);
+
+                        /* They're not both bit variables. Is the right a literal? */
+                        if(AOP_TYPE(right) == AOP_LIT) {
+                        lit = ulFromVal (AOP(right)->aopu.aop_lit);
+
+                        switch(size) {
+
+                                case 1:
+                                        switch(lit & 0xff) {
+                                                case 1:
+                                                                if ( IC_TRUE(ifx) ) {
+                                                                        pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
+                                                                        emitSKPNZ;
+                                                                        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+                                                                } else {
+                                                                        pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
+                                                                        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+                                                                }
+                                                                break;
+                                                case 0xff:
+                                                                if ( IC_TRUE(ifx) ) {
+                                                                        pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
+                                                                        emitSKPNZ;
+                                                                        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+                                                                } else {
+                                                                        pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
+                                                                        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+                                                                }
+                                                                break;
+                                                default:
+                                                                pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+                                                                if(lit)
+                                                                        pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
+                                                                genSkip(ifx,'z');
+                                        } // switch lit
+
+
+                                        /* end of size == 1 */
+                                        break;
+
+                                case 2:
+                                        genc16bit2lit(left,lit,offset);
+                                        genSkip(ifx,'z');
+                                        break;
+                                        /* end of size == 2 */
+
+                                default:
+                                        /* size is 4 */
+                                        if(lit==0) {
+                                                pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
+                                                pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
+                                                pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
+                                                pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
+                                                genSkip(ifx,'z');
+                                        } else {
+                                                /* search for patterns that can be optimized */
+
+                                                genc16bit2lit(left,lit,0);
+                                                lit >>= 16;
+                                                if(lit) {
+                                                                if(IC_TRUE(ifx))
+                                                                emitSKPZ; // if hi word unequal
+                                                                else
+                                                                emitSKPNZ; // if hi word equal
+                                                                // fail early
+                                                        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
+                                                        genc16bit2lit(left,lit,2);
+                                                        genSkip(ifx,'z');
+                                                } else {
+                                                        pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
+                                                        pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
+                                                        genSkip(ifx,'z');
+                                                }
+                                        }
+                                                pic16_emitpLabel(falselbl->key);
+                                                break;
+
+                        } // switch size
+
+                        ifx->generated = 1;
+                        goto release ;
+
+
+          } else if(AOP_TYPE(right) == AOP_CRY ) {
+            /* we know the left is not a bit, but that the right is */
+            pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+            pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
+                      pic16_popGet(AOP(right),offset));
+            pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
+
+            /* if the two are equal, then W will be 0 and the Z bit is set
+             * we could test Z now, or go ahead and check the high order bytes if
+             * the variable we're comparing is larger than a byte. */
+
+            while(--size)
+              pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
+
+            if ( IC_TRUE(ifx) ) {
+              emitSKPNZ;
+              pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+              // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
+            } else {
+              emitSKPZ;
+              pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+              // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
+            }
+
+          } else {
+            /* They're both variables that are larger than bits */
+            int s = size;
+
+            tlbl = newiTempLabel(NULL);
+
+            while(size--) {
+              pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+              pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
+
+              if ( IC_TRUE(ifx) ) {
+                if(size) {
+                  emitSKPZ;
+
+                        DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
+
+                  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
+                  pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
+                } else {
+                  emitSKPNZ;
+
+                        DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
+
+
+                  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+                  pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
+                }
+              } else {
+                emitSKPZ;
+
+                        DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
+
+                pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+                pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
+              }
+              offset++;
+            }
+            if(s>1 && IC_TRUE(ifx)) {
+              pic16_emitpLabel(tlbl->key);
+              pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
+            }
+          }
         }
         /* mark the icode as generated */
         ifx->generated = 1;
@@ -7430,9 +5052,9 @@ static void genCmpEq (iCode *ic, iCode *ifx)
     /* if they are both bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
-       DEBUGpic16_emitcode ("; ***","%s  %d CASE 2",__FUNCTION__,__LINE__);
+        DEBUGpic16_emitcode ("; ***","%s  %d CASE 2",__FUNCTION__,__LINE__);
         if(AOP_TYPE(right) == AOP_LIT){
-            unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+            unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
             if(lit == 0L){
                 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
                 pic16_emitcode("cpl","c");
@@ -7462,35 +5084,35 @@ static void genCmpEq (iCode *ic, iCode *ifx)
         then put the result in place */
         pic16_outBitC(result);
     } else {
-      
+
       DEBUGpic16_emitcode ("; ***","%s  %d CASE 3",__FUNCTION__,__LINE__);
       gencjne(left,right,result,ifx);
 /*
-      if(ifx) 
-       gencjne(left,right,newiTempLabel(NULL));
+      if(ifx)
+        gencjne(left,right,newiTempLabel(NULL));
       else {
-       if(IC_TRUE(ifx)->key)
-         gencjne(left,right,IC_TRUE(ifx)->key);
-       else
-         gencjne(left,right,IC_FALSE(ifx)->key);
-       ifx->generated = 1;
-       goto release ;
+        if(IC_TRUE(ifx)->key)
+          gencjne(left,right,IC_TRUE(ifx)->key);
+        else
+          gencjne(left,right,IC_FALSE(ifx)->key);
+        ifx->generated = 1;
+        goto release ;
       }
       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-       pic16_aopPut(AOP(result),"a",0);
-       goto release ;
+        pic16_aopPut(AOP(result),"a",0);
+        goto release ;
       }
 
       if (ifx) {
-       genIfxJump (ifx,"a");
-       goto release ;
+        genIfxJump (ifx,"a");
+        goto release ;
       }
 */
       /* if the result is used in an arithmetic operation
-        then put the result in place */
+         then put the result in place */
 /*
-      if (AOP_TYPE(result) != AOP_CRY) 
-       pic16_outAcc(result);
+      if (AOP_TYPE(result) != AOP_CRY)
+        pic16_outAcc(result);
 */
       /* leave the result in acc */
     }
@@ -7517,11 +5139,11 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
     the next instruction is ifx with the same operand
     and live to of the operand is upto the ifx only then */
     if (ic->next
-       && ic->next->op == IFX
+        && ic->next->op == IFX
         && IC_COND(ic->next)->key == op->key
         && OP_SYMBOL(op)->liveTo <= ic->next->seq
         ) {
-               DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
+                DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
           return ic->next;
     }
 
@@ -7544,18 +5166,18 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
         IC_COND(ic->next)->key == op->key) {
       DEBUGpic16_emitcode ("; "," key is okay");
       DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
-                          OP_SYMBOL(op)->liveTo,
-                          ic->next->seq);
+                           OP_SYMBOL(op)->liveTo,
+                           ic->next->seq);
     }
 
 #if 0
     /* the code below is completely untested
      * it just allows ulong2fs.c compile -- VR */
-        
+
     ic = ic->next;
     fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
-                                       __FILE__, __FUNCTION__, __LINE__);
-       
+                                        __FILE__, __FUNCTION__, __LINE__);
+
     /* if this has register type condition and
     the next instruction is ifx with the same operand
     and live to of the operand is upto the ifx only then */
@@ -7573,9 +5195,9 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
     }
 
     fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
-                                       __FILE__, __FUNCTION__, __LINE__);
+                                        __FILE__, __FUNCTION__, __LINE__);
 
-//  return ic->next->next;             /* this just might work */ /* FIXME FIXME */
+//  return ic->next->next;              /* this just might work */ /* FIXME FIXME */
 #endif
 
     return NULL;
@@ -7595,7 +5217,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);
 
@@ -7637,14 +5259,14 @@ static void genOrOp (iCode *ic)
   operand *left,*right, *result;
   symbol *tlbl;
 
-    FENTRY;  
+    FENTRY;
 
   /* note here that || operations that are in an
     if statement are taken away by backPatchLabels
     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);
 
@@ -7653,17 +5275,17 @@ static void genOrOp (iCode *ic)
         AOP_TYPE(right) == AOP_CRY ) {
       pic16_emitcode("clrc","");
       pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
-              AOP(left)->aopu.aop_dir,
-              AOP(left)->aopu.aop_dir);
+               AOP(left)->aopu.aop_dir,
+               AOP(left)->aopu.aop_dir);
       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-              AOP(right)->aopu.aop_dir,
-              AOP(right)->aopu.aop_dir);
+               AOP(right)->aopu.aop_dir,
+               AOP(right)->aopu.aop_dir);
       pic16_emitcode("setc","");
 
     } else {
         tlbl = newiTempLabel(NULL);
         pic16_toBoolean(left);
-       emitSKPZ;
+        emitSKPZ;
         pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
         pic16_toBoolean(right);
         pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
@@ -7673,7 +5295,7 @@ static void genOrOp (iCode *ic)
 
     pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(result,NULL,ic,TRUE);            
+    pic16_freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7689,7 +5311,7 @@ static int isLiteralBit(unsigned long lit)
     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
     int idx;
-    
+
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     for(idx = 0; idx < 32; idx++)
         if(lit == pw[idx])
@@ -7728,7 +5350,7 @@ static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
   FENTRY;
   if(IC_TRUE(ic)){
     symbol *nlbl = newiTempLabel(NULL);
-      pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
+      pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
       pic16_emitcode("","%05d_DS_:",tlbl->key+100);
       pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
       pic16_emitcode("","%05d_DS_:",nlbl->key+100);
@@ -7745,47 +5367,50 @@ static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
 static void genAnd (iCode *ic, iCode *ifx)
 {
   operand *left, *right, *result;
-  int size, offset=0;  
+  int size, offset = 0;
   unsigned long lit = 0L;
-  int bytelit = 0;
   resolvedIfx rIfx;
 
-    FENTRY;
-    
-  pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
-  pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-  pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
+  FENTRY;
+
+  pic16_aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+  pic16_aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
+  pic16_aopOp ((result = IC_RESULT (ic)), ic, TRUE);
 
-  resolveIfx(&rIfx,ifx);
+  resolveIfx (&rIfx, ifx);
 
   /* if left is a literal & right is not then exchange them */
-  if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
-      AOP_NEEDSACC(left)) {
-    operand *tmp = right ;
-    right = left;
-    left = tmp;
-  }
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
+      AOP_NEEDSACC (left))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
 
   /* if result = right then exchange them */
-  if(pic16_sameRegs(AOP(result),AOP(right))){
-    operand *tmp = right ;
-    right = left;
-    left = tmp;
-  }
+  if (pic16_sameRegs (AOP (result), AOP (right)))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
 
   /* if right is bit then exchange them */
-  if (AOP_TYPE(right) == AOP_CRY &&
-      AOP_TYPE(left) != AOP_CRY){
-    operand *tmp = right ;
-    right = left;
-    left = tmp;
-  }
-  if(AOP_TYPE(right) == AOP_LIT)
-    lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+  if (AOP_TYPE (right) == AOP_CRY &&
+      AOP_TYPE (left) != AOP_CRY)
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  if (AOP_TYPE (right) == AOP_LIT)
+    lit = ulFromVal (AOP (right)->aopu.aop_lit);
 
-  size = AOP_SIZE(result);
+  size = AOP_SIZE (result);
 
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+  DEBUGpic16_pic16_AopType (__LINE__, left, right, result);
 
   // if(bit & yy)
   // result = bit & yy;
@@ -7793,33 +5418,33 @@ static void genAnd (iCode *ic, iCode *ifx)
     // c = bit & literal;
     if(AOP_TYPE(right) == AOP_LIT){
       if(lit & 1) {
-       if(size && pic16_sameRegs(AOP(result),AOP(left)))
-         // no change
-         goto release;
-       pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+        if(size && pic16_sameRegs(AOP(result),AOP(left)))
+          // no change
+          goto release;
+        pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
       } else {
-       // bit(result) = 0;
-       if(size && (AOP_TYPE(result) == AOP_CRY)){
-         pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
-         goto release;
-       }
-       if((AOP_TYPE(result) == AOP_CRY) && ifx){
-         jumpIfTrue(ifx);
-         goto release;
-       }
-       pic16_emitcode("clr","c");
+        // bit(result) = 0;
+        if(size && (AOP_TYPE(result) == AOP_CRY)){
+          pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
+          goto release;
+        }
+        if((AOP_TYPE(result) == AOP_CRY) && ifx){
+          jumpIfTrue(ifx);
+          goto release;
+        }
+        pic16_emitcode("clr","c");
       }
     } else {
       if (AOP_TYPE(right) == AOP_CRY){
-       // c = bit & bit;
-       pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-       pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+        // c = bit & bit;
+        pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+        pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
       } else {
-       // c = bit & val;
-       MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
-       // c = lsb
-       pic16_emitcode("rrc","a");
-       pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+        // c = bit & val;
+        MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
+        // c = lsb
+        pic16_emitcode("rrc","a");
+        pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
       }
     }
     // bit = c
@@ -7828,169 +5453,157 @@ static void genAnd (iCode *ic, iCode *ifx)
       pic16_outBitC(result);
     // if(bit & ...)
     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-      genIfxJump(ifx, "c");           
+      genIfxJump(ifx, "c");
     goto release ;
   }
 
-  // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
+  // if (val & 0xZZ)      - size = 0, ifx != FALSE -
   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
-  if((AOP_TYPE(right) == AOP_LIT) &&
-     (AOP_TYPE(result) == AOP_CRY) &&
-     (AOP_TYPE(left) != AOP_CRY)){
-    int posbit = isLiteralBit(lit);
-    /* left &  2^n */
-    if(posbit){
-      posbit--;
-      //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
-      // bit = left & 2^n
-      if(size)
-       pic16_emitcode("mov","c,acc.%d",posbit&0x07);
-      // if(left &  2^n)
-      else{
-       if(ifx){
-/*
-         if(IC_TRUE(ifx)) {
-           pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
-           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
-         } else {
-           pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
-           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
-         }
-*/
-       DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
-       size = AOP_SIZE(left);
-
-       {
-         int bp = posbit, ofs=0;
-         
-           while(bp > 7) {
-             bp -= 8;
-             ofs++;
-           }
-       
-         pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
-                   pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
-
-       }
-/*
-         pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
-                   pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
-*/
-         pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
-         
-         ifx->generated = 1;
-       }
-       goto release;
-      }
-    } else {
-      symbol *tlbl = newiTempLabel(NULL);
-      int sizel = AOP_SIZE(left);
+  if ((AOP_TYPE (right) == AOP_LIT) &&
+     (AOP_TYPE (result) == AOP_CRY) &&
+     (AOP_TYPE (left) != AOP_CRY))
+    {
+      symbol *tlbl = newiTempLabel (NULL);
+      int sizel = AOP_SIZE (left);
+      int nonnull = 0;
+      char emitBra;
 
-      if(size)
+      if (size)
         emitSETC;
 
-      while(sizel--) {
-        if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) {
+      /* get number of non null bytes in literal */
+      while (sizel--)
+        {
+          if (lit & (0xff << (sizel * 8)))
+            ++nonnull;
+        }
+
+      emitBra = nonnull || rIfx.condition;
 
-          /* patch provided by Aaron Colwell */
-          if((posbit = isLiteralBit(bytelit)) != 0) {
-              pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
-                              pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE),
-                                                (posbit-1),0, PO_GPR_REGISTER));
+      for (sizel = AOP_SIZE (left); sizel--; ++offset, lit >>= 8)
+        {
+          unsigned char bytelit = lit;
 
-              pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
-//              pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
-          } else {
-              if (bytelit == 0xff) {
-                  /* Aaron had a MOVF instruction here, changed to MOVFW cause
-                   * a peephole could optimize it out -- VR */
-                  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
-              } else {
-                  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
-                  pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
-              }
+          if (bytelit != 0)
+            {
+              int posbit;
+
+              --nonnull;
+
+              /* patch provided by Aaron Colwell */
+              if ((posbit = isLiteralBit (bytelit)) != 0)
+                {
+                  if (nonnull)
+                    {
+                      pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet (AOP (left), offset, FALSE, FALSE), posbit - 1, 0, PO_GPR_REGISTER));
+                      pic16_emitpcode (POC_GOTO, pic16_popGetLabel (rIfx.condition ? rIfx.lbl->key : tlbl->key));
+                    }
+                  else
+                    {
+                      pic16_emitpcode (rIfx.condition ? POC_BTFSC :POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet (AOP (left), offset, FALSE, FALSE), posbit - 1, 0, PO_GPR_REGISTER));
+                    }
+                }
+              else
+                {
+                  if (bytelit == 0xff)
+                    {
+                      /* Aaron had a MOVF instruction here, changed to MOVFW cause
+                       * a peephole could optimize it out -- VR */
+                      pic16_emitpcode (POC_MOVFW, pic16_popGet (AOP (left), offset));
+                    }
+                  else
+                    {
+                      pic16_emitpcode (POC_MOVFW, pic16_popGet (AOP (left), offset));
+                      pic16_emitpcode (POC_ANDLW, pic16_popGetLit (bytelit));
+                    }
+                  if (nonnull)
+                    {
+                      if (rIfx.condition)
+                        {
+                          emitSKPZ;
+                          pic16_emitpcode (POC_GOTO, pic16_popGetLabel (rIfx.lbl->key)); /* to false */
+                        }
+                      else
+                        {
+                          pic16_emitpcode (POC_BNZ, pic16_popGetLabel (tlbl->key)); /* to true */
+                        }
+                    }
+                  else
+                    {
+                      /* last non null byte */
+                      if (rIfx.condition)
+                        emitSKPZ;
+                      else
+                        emitSKPNZ;
+                    }
+                }
+            }
+        }
 
-              pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
-                            pic16_popGetLabel(tlbl->key));
-          }
-        
-#if 0
-          /* old code, left here for reference -- VR 09/2004 */
-         MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-         // byte ==  2^n ?
-         if((posbit = isLiteralBit(bytelit)) != 0)
-           pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
-         else{
-           if(bytelit != 0x0FFL)
-             pic16_emitcode("anl","a,%s",
-                            pic16_aopGet(AOP(right),offset,FALSE,TRUE));
-           pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
-          }
-#endif
-       }
-       offset++;
-      }
       // bit = left & literal
-      if(size) {
-        emitCLRC;
-        pic16_emitpLabel(tlbl->key);
-      }
+      if (size)
+        {
+          emitCLRC;
+          pic16_emitpLabel (tlbl->key);
+        }
+
       // if(left & literal)
-      else {
-        if(ifx) {
-          pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
-          ifx->generated = 1;
+      else
+        {
+          if (ifx)
+            {
+              if (emitBra)
+                pic16_emitpcode (POC_GOTO, pic16_popGetLabel (rIfx.lbl->key));
+              ifx->generated = 1;
+            }
+          pic16_emitpLabel (tlbl->key);
+          goto release;
         }
-        pic16_emitpLabel(tlbl->key);
-        goto release;
-      }
+      pic16_outBitC (result);
+      goto release;
     }
 
-    pic16_outBitC(result);
-    goto release ;
-  }
-
   /* if left is same as result */
   if(pic16_sameRegs(AOP(result),AOP(left))){
     int know_W = -1;
     for(;size--; offset++,lit>>=8) {
       if(AOP_TYPE(right) == AOP_LIT){
-       switch(lit & 0xff) {
-       case 0x00:
-         /*  and'ing with 0 has clears the result */
-//       pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-         pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
-         break;
-       case 0xff:
-         /* and'ing with 0xff is a nop when the result and left are the same */
-         break;
-
-       default:
-         {
-           int p = pic16_my_powof2( (~lit) & 0xff );
-           if(p>=0) {
-             /* only one bit is set in the literal, so use a bcf instruction */
-//           pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
-             pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
-
-           } else {
-             pic16_emitcode("movlw","0x%x", (lit & 0xff));
-             pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
-             if(know_W != (lit&0xff))
-               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
-             know_W = lit &0xff;
-             pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
-           }
-         }    
-       }
+        switch(lit & 0xff) {
+        case 0x00:
+          /*  and'ing with 0 has clears the result */
+//        pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+          pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
+          break;
+        case 0xff:
+          /* and'ing with 0xff is a nop when the result and left are the same */
+          break;
+
+        default:
+          {
+            int p = pic16_my_powof2( (~lit) & 0xff );
+            if(p>=0) {
+              /* only one bit is set in the literal, so use a bcf instruction */
+//            pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
+              pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
+
+            } else {
+              pic16_emitcode("movlw","0x%x", (lit & 0xff));
+              pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
+              if(know_W != (lit&0xff))
+                pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+              know_W = lit &0xff;
+              pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
+            }
+          }
+        }
       } else {
-       if (AOP_TYPE(left) == AOP_ACC) {
-         pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
-       } else {                    
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
-         pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
+        if (AOP_TYPE(left) == AOP_ACC) {
+          pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
+        } else {
+          pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
+          pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
 
-       }
+        }
       }
     }
 
@@ -8003,74 +5616,74 @@ static void genAnd (iCode *ic, iCode *ifx)
       symbol *tlbl = newiTempLabel(NULL);
       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
       if(size)
-       pic16_emitcode("setb","c");
+        pic16_emitcode("setb","c");
       while(sizer--){
-       MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-       pic16_emitcode("anl","a,%s",
-                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-       pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
-       offset++;
+        MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+        pic16_emitcode("anl","a,%s",
+                       pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+        pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
+        offset++;
       }
       if(size){
-       CLRC;
-       pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-       pic16_outBitC(result);
+        CLRC;
+        pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+        pic16_outBitC(result);
       } else if(ifx)
-       jmpTrueOrFalse(ifx, tlbl);
+        jmpTrueOrFalse(ifx, tlbl);
     } else {
       for(;(size--);offset++) {
-       // normal case
-       // result = left & right
-       if(AOP_TYPE(right) == AOP_LIT){
-         int t = (lit >> (offset*8)) & 0x0FFL;
-         switch(t) { 
-         case 0x00:
-           pic16_emitcode("clrf","%s",
-                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-           pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
-           break;
-         case 0xff:
-           pic16_emitcode("movf","%s,w",
-                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-           pic16_emitcode("movwf","%s",
-                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-           pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
-           break;
-         default:
-           pic16_emitcode("movlw","0x%x",t);
-           pic16_emitcode("andwf","%s,w",
-                          pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-           pic16_emitcode("movwf","%s",
-                          pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-             
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
-           pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
-           pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
-         }
-         continue;
-       }
-
-       if (AOP_TYPE(left) == AOP_ACC) {
-         pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-         pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
-       } else {
-         pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-         pic16_emitcode("andwf","%s,w",
-                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
-         pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
-       }
-       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+        // normal case
+        // result = left & right
+        if(AOP_TYPE(right) == AOP_LIT){
+          int t = (lit >> (offset*8)) & 0x0FFL;
+          switch(t) {
+          case 0x00:
+            pic16_emitcode("clrf","%s",
+                           pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+            pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
+            break;
+          case 0xff:
+            pic16_emitcode("movf","%s,w",
+                           pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+            pic16_emitcode("movwf","%s",
+                           pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+            pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+            pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+            break;
+          default:
+            pic16_emitcode("movlw","0x%x",t);
+            pic16_emitcode("andwf","%s,w",
+                           pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+            pic16_emitcode("movwf","%s",
+                           pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+
+            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+            pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
+            pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+          }
+          continue;
+        }
+
+        if (AOP_TYPE(left) == AOP_ACC) {
+          pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+          pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
+        } else {
+          pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+          pic16_emitcode("andwf","%s,w",
+                         pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+          pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
+          pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
+        }
+        pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+        pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
       }
     }
   }
 
-  release :
-    pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+release :
+  pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
   pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-  pic16_freeAsmop(result,NULL,ic,TRUE);     
+  pic16_freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -8078,593 +5691,709 @@ static void genAnd (iCode *ic, iCode *ifx)
 /*-----------------------------------------------------------------*/
 static void genOr (iCode *ic, iCode *ifx)
 {
-    operand *left, *right, *result;
-    int size, offset=0;
-    unsigned long lit = 0L;
+  operand *left, *right, *result;
+  int size, offset = 0;
+  unsigned long lit = 0L;
+  resolvedIfx rIfx;
 
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  FENTRY;
 
-    pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
-    pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-    pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
+  pic16_aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+  pic16_aopOp ((right= IC_RIGHT (ic)), ic, FALSE);
+  pic16_aopOp ((result=IC_RESULT (ic)), ic, TRUE);
 
-    DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+  resolveIfx (&rIfx, ifx);
 
-    /* if left is a literal & right is not then exchange them */
-    if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
-       AOP_NEEDSACC(left)) {
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
+  /* if left is a literal & right is not then exchange them */
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
+      AOP_NEEDSACC (left))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
     }
 
-    /* if result = right then exchange them */
-    if(pic16_sameRegs(AOP(result),AOP(right))){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
+  /* if result = right then exchange them */
+  if (pic16_sameRegs (AOP (result), AOP (right)))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
     }
 
-    /* if right is bit then exchange them */
-    if (AOP_TYPE(right) == AOP_CRY &&
-        AOP_TYPE(left) != AOP_CRY){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
+  /* if right is bit then exchange them */
+  if (AOP_TYPE (right) == AOP_CRY &&
+      AOP_TYPE (left) != AOP_CRY)
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
     }
 
-    DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+  DEBUGpic16_pic16_AopType (__LINE__, left, right, result);
 
-    if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+  if (AOP_TYPE (right) == AOP_LIT)
+      lit = ulFromVal (AOP (right)->aopu.aop_lit);
 
-    size = AOP_SIZE(result);
+  size = AOP_SIZE (result);
+
+  // if(bit | yy)
+  // xx = bit | yy;
+  if (AOP_TYPE(left) == AOP_CRY){
+      if(AOP_TYPE(right) == AOP_LIT){
+          // c = bit & literal;
+          if(lit){
+              // lit != 0 => result = 1
+              if(AOP_TYPE(result) == AOP_CRY){
+                if(size)
+                  pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+                //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+                //     AOP(result)->aopu.aop_dir,
+                //     AOP(result)->aopu.aop_dir);
+                  else if(ifx)
+                      continueIfTrue(ifx);
+                  goto release;
+              }
+          } else {
+              // lit == 0 => result = left
+              if(size && pic16_sameRegs(AOP(result),AOP(left)))
+                  goto release;
+              pic16_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
+          }
+      } else {
+          if (AOP_TYPE(right) == AOP_CRY){
+            if(pic16_sameRegs(AOP(result),AOP(left))){
+              // c = bit | bit;
+              pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
+              pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+              pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
+
+            } else {
+              if( AOP_TYPE(result) == AOP_ACC) {
+                pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
+                pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
+                pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
+                pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
+
+              } else {
+
+                pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
+                pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
+                pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
+                pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
+
+              }
+            }
+          } else {
+              // c = bit | val;
+              symbol *tlbl = newiTempLabel(NULL);
+              pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
+
+              pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
+              if( AOP_TYPE(right) == AOP_ACC) {
+                pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
+                emitSKPNZ;
+                pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
+                pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
+              }
 
-    // if(bit | yy)
-    // xx = bit | yy;
-    if (AOP_TYPE(left) == AOP_CRY){
+
+
+              if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
+                  pic16_emitcode(";XXX setb","c");
+              pic16_emitcode(";XXX jb","%s,%05d_DS_",
+                       AOP(left)->aopu.aop_dir,tlbl->key+100);
+              pic16_toBoolean(right);
+              pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+              if((AOP_TYPE(result) == AOP_CRY) && ifx){
+                  jmpTrueOrFalse(ifx, tlbl);
+                  goto release;
+              } else {
+                  CLRC;
+                  pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+              }
+          }
+      }
+      // bit = c
+      // val = c
+      if(size)
+          pic16_outBitC(result);
+      // if(bit | ...)
+      else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+          genIfxJump(ifx, "c");
+      goto release ;
+  }
+
+  // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
+  // bit = val | 0xZZ     - size = 1, ifx = FALSE -
+  if ((AOP_TYPE (right) == AOP_LIT) &&
+     (AOP_TYPE (result) == AOP_CRY) &&
+     (AOP_TYPE (left) != AOP_CRY))
+    {
+      if (IS_OP_VOLATILE(left)) {
+          pic16_mov2w_volatile(AOP(left));
+      } // if
+      if (lit)
+        {
+          if (rIfx.condition)
+            pic16_emitpcode (POC_GOTO, pic16_popGetLabel (rIfx.lbl->key)); /* to false */
+          ifx->generated = 1;
+        }
+      else
+        wassert (0);
+
+      goto release;
+  }
+
+  /* if left is same as result */
+  if(pic16_sameRegs(AOP(result),AOP(left))){
+    int know_W = -1;
+    for(;size--; offset++,lit>>=8) {
+      if(AOP_TYPE(right) == AOP_LIT){
+        if(((lit & 0xff) == 0) && !IS_OP_VOLATILE(left)) {
+          /*  or'ing with 0 has no effect */
+          continue;
+        } else {
+          int p = pic16_my_powof2(lit & 0xff);
+          if(p>=0) {
+            /* only one bit is set in the literal, so use a bsf instruction */
+            pic16_emitpcode(POC_BSF,
+                      pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
+          } else {
+            if(know_W != (lit & 0xff))
+              pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+            know_W = lit & 0xff;
+            pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
+          }
+
+        }
+      } else {
+        if (AOP_TYPE(left) == AOP_ACC) {
+          pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(right),offset));
+        } else {
+          pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
+          pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(left),offset));
+        }
+      }
+    }
+  } else {
+      // left & result in different registers
+      if(AOP_TYPE(result) == AOP_CRY){
+          // result = bit
+          // if(size), result in bit
+          // if(!size && ifx), conditional oper: if(left | right)
+          symbol *tlbl = newiTempLabel(NULL);
+          int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
+          pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
+
+          if(size)
+              pic16_emitcode(";XXX setb","c");
+          while(sizer--){
+              MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+              pic16_emitcode(";XXX orl","a,%s",
+                       pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+              pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+              offset++;
+          }
+          if(size){
+              CLRC;
+              pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+              pic16_outBitC(result);
+          } else if(ifx)
+              jmpTrueOrFalse(ifx, tlbl);
+      } else for(;(size--);offset++){
+        // normal case
+        // result = left & right
         if(AOP_TYPE(right) == AOP_LIT){
-            // c = bit & literal;
-            if(lit){
-                // lit != 0 => result = 1
-                if(AOP_TYPE(result) == AOP_CRY){
-                 if(size)
-                   pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
-                 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
-                 //     AOP(result)->aopu.aop_dir,
-                 //     AOP(result)->aopu.aop_dir);
-                    else if(ifx)
-                        continueIfTrue(ifx);
-                    goto release;
+          int t = (lit >> (offset*8)) & 0x0FFL;
+          switch(t) {
+          case 0x00:
+            pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
+            pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
+            break;
+          default:
+            pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(t));
+            pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
+            pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
+          }
+          continue;
+        }
+
+        // faster than result <- left, anl result,right
+        // and better if result is SFR
+        if (AOP_TYPE(left) == AOP_ACC) {
+          pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(right),offset));
+        } else {
+          pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
+          pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
+        }
+        pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
+      }
+  }
+
+release :
+  pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+  pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+  pic16_freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genXor - code for xclusive or                                   */
+/*-----------------------------------------------------------------*/
+static void genXor (iCode *ic, iCode *ifx)
+{
+  operand *left, *right, *result;
+  int size, offset = 0;
+  unsigned long lit = 0L;
+  resolvedIfx rIfx;
+
+  FENTRY;
+
+  pic16_aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+  pic16_aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
+  pic16_aopOp ((result = IC_RESULT (ic)), ic, TRUE);
+
+  resolveIfx (&rIfx,ifx);
+
+  /* if left is a literal & right is not ||
+     if left needs acc & right does not */
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
+      (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  /* if result = right then exchange them */
+  if (pic16_sameRegs (AOP (result), AOP (right)))
+    {
+      operand *tmp = right ;
+      right = left;
+      left = tmp;
+    }
+
+  /* if right is bit then exchange them */
+  if (AOP_TYPE (right) == AOP_CRY &&
+      AOP_TYPE (left) != AOP_CRY)
+    {
+      operand *tmp = right ;
+      right = left;
+      left = tmp;
+    }
+
+  if (AOP_TYPE (right) == AOP_LIT)
+    lit = ulFromVal (AOP (right)->aopu.aop_lit);
+
+  size = AOP_SIZE (result);
+
+  // if(bit ^ yy)
+  // xx = bit ^ yy;
+  if (AOP_TYPE(left) == AOP_CRY)
+    {
+      if (AOP_TYPE(right) == AOP_LIT)
+        {
+          // c = bit & literal;
+          if (lit >> 1)
+            {
+              // lit>>1  != 0 => result = 1
+              if (AOP_TYPE(result) == AOP_CRY)
+                {
+                  if (size)
+                    {
+                      pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result), offset));
+                    }
+                  else if (ifx)
+                    continueIfTrue(ifx);
+                  goto release;
                 }
-            } else {
-                // lit == 0 => result = left
-                if(size && pic16_sameRegs(AOP(result),AOP(left)))
+              pic16_emitcode("setb", "c");
+            }
+          else
+            {
+              // lit == (0 or 1)
+              if (lit == 0)
+                {
+                  // lit == 0, result = left
+                  if (size && pic16_sameRegs(AOP(result), AOP(left)))
                     goto release;
-                pic16_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
+                  pic16_emitcode("mov", "c,%s", AOP(left)->aopu.aop_dir);
+                }
+              else
+                {
+                  // lit == 1, result = not(left)
+                  if (size && pic16_sameRegs(AOP(result), AOP(left)))
+                    {
+                      pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result), offset));
+                      pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result), offset));
+                      pic16_emitcode("cpl", "%s", AOP(result)->aopu.aop_dir);
+                      goto release;
+                    }
+                  else
+                    {
+                      pic16_emitcode("mov", "c,%s", AOP(left)->aopu.aop_dir);
+                      pic16_emitcode("cpl", "c");
+                    }
+                }
             }
-        } else {
-            if (AOP_TYPE(right) == AOP_CRY){
-             if(pic16_sameRegs(AOP(result),AOP(left))){
-                // c = bit | bit;
-               pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
-               pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
-               pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
-
-               pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
-               pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                        AOP(right)->aopu.aop_dir,
-                        AOP(right)->aopu.aop_dir);
-               pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
-             } else {
-               if( AOP_TYPE(result) == AOP_ACC) {
-                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
-                 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
-                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
-                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
-
-               } else {
-
-                 pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
-                 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
-                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
-                 pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
-
-                 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
-                                AOP(result)->aopu.aop_dir,
-                                AOP(result)->aopu.aop_dir);
-                 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
-                                AOP(right)->aopu.aop_dir,
-                                AOP(right)->aopu.aop_dir);
-                 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                                AOP(left)->aopu.aop_dir,
-                                AOP(left)->aopu.aop_dir);
-                 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
-                                AOP(result)->aopu.aop_dir,
-                                AOP(result)->aopu.aop_dir);
-               }
-             }
-            } else {
-                // c = bit | val;
-                symbol *tlbl = newiTempLabel(NULL);
-                pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+        }
+      else
+        {
+          // right != literal
+          symbol *tlbl = newiTempLabel(NULL);
+          if (AOP_TYPE(right) == AOP_CRY)
+            {
+              // c = bit ^ bit;
+              pic16_emitcode("mov", "c,%s", AOP(right)->aopu.aop_dir);
+            }
+          else
+            {
+              int sizer = AOP_SIZE(right);
+              // c = bit ^ val
+              // if val>>1 != 0, result = 1
+              pic16_emitcode("setb", "c");
+              while (sizer)
+                {
+                  MOVA(pic16_aopGet(AOP(right), sizer - 1, FALSE, FALSE));
+                  if (sizer == 1)
+                    // test the msb of the lsb
+                    pic16_emitcode("anl", "a,#0xfe");
+                  pic16_emitcode("jnz", "%05d_DS_", tlbl->key+100);
+                  sizer--;
+                }
+              // val = (0,1)
+              pic16_emitcode("rrc", "a");
+            }
+          pic16_emitcode("jnb", "%s,%05d_DS_", AOP(left)->aopu.aop_dir, (tlbl->key + 100));
+          pic16_emitcode("cpl", "c");
+          pic16_emitcode("", "%05d_DS_:", (tlbl->key + 100));
+        }
+      // bit = c
+      // val = c
+      if (size)
+        pic16_outBitC(result);
+      // if(bit | ...)
+      else if ((AOP_TYPE(result) == AOP_CRY) && ifx)
+        genIfxJump(ifx, "c");
+      goto release;
+    }
+
+  // if(val ^ 0xZZ)       - size = 0, ifx != FALSE  -
+  // bit = val ^ 0xZZ     - size = 1, ifx = FALSE -
+  if ((AOP_TYPE (right) == AOP_LIT) &&
+     (AOP_TYPE (result) == AOP_CRY) &&
+     (AOP_TYPE (left) != AOP_CRY))
+    {
+      symbol *tlbl = newiTempLabel (NULL);
+      int sizel;
+
+      if (size)
+        emitSETC;
+
+      for (sizel = AOP_SIZE(left); sizel--; ++offset, lit >>= 8)
+        {
+          unsigned char bytelit = lit;
+
+          switch (bytelit)
+            {
+            case 0xff:
+              pic16_emitpcode (POC_COMFW, pic16_popGet (AOP (left), offset));
+              break;
 
+            case 0x00:
+              pic16_emitpcode (POC_MOVFW, pic16_popGet (AOP (left), offset));
+              break;
 
-               pic16_emitpcode(POC_BCF,   pic16_popGet(AOP(result),0));
-               if( AOP_TYPE(right) == AOP_ACC) {
-                 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
-                 emitSKPNZ;
-                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
-                 pic16_emitpcode(POC_BSF,   pic16_popGet(AOP(result),0));
-               }
+            default:
+              pic16_emitpcode (POC_MOVLW, pic16_popGetLit (bytelit));
+              pic16_emitpcode (POC_XORFW, pic16_popGet (AOP (left), offset));
+              break;
+            }
+          if (sizel)
+            {
+              if (rIfx.condition)
+                {
+                  /* rIfx.lbl might be far away... */
+                  emitSKPZ;
+                  pic16_emitpcode (POC_GOTO, pic16_popGetLabel (rIfx.lbl->key)); /* to false */
+                }
+              else
+                {
+                  pic16_emitpcode (POC_BNZ, pic16_popGetLabel (tlbl->key)); /* to true */
+                }
+            }
+          else
+            {
+              /* last non null byte */
+              if (rIfx.condition)
+                emitSKPZ;
+              else
+                emitSKPNZ;
+            }
+        }
 
+      // bit = left ^ literal
+      if (size)
+        {
+          emitCLRC;
+          pic16_emitpLabel (tlbl->key);
+        }
+      // if (left ^ literal)
+      else
+        {
+          if (ifx)
+            {
+              pic16_emitpcode (POC_GOTO, pic16_popGetLabel (rIfx.lbl->key));
+              ifx->generated = 1;
+            }
+          pic16_emitpLabel (tlbl->key);
+          goto release;
+        }
 
+      pic16_outBitC (result);
+      goto release;
+  }
 
-                if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
-                    pic16_emitcode(";XXX setb","c");
-                pic16_emitcode(";XXX jb","%s,%05d_DS_",
-                         AOP(left)->aopu.aop_dir,tlbl->key+100);
-                pic16_toBoolean(right);
-                pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
-                if((AOP_TYPE(result) == AOP_CRY) && ifx){
-                    jmpTrueOrFalse(ifx, tlbl);
-                    goto release;
-                } else {
-                    CLRC;
-                    pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+  if (pic16_sameRegs(AOP(result), AOP(left)))
+    {
+      /* if left is same as result */
+      for (; size--; offset++)
+        {
+          if (AOP_TYPE(right) == AOP_LIT)
+            {
+              int t  = (lit >> (offset * 8)) & 0x0FFL;
+              if  (t == 0x00L)
+                continue;
+              else
+                {
+                  pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+                  pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(left), offset));
                 }
             }
-        }
-        // bit = c
-        // val = c
-        if(size)
-            pic16_outBitC(result);
-        // if(bit | ...)
-        else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-            genIfxJump(ifx, "c");           
-        goto release ;
-    }
-
-    // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
-    // bit = val | 0xZZ     - size = 1, ifx = FALSE -
-    if((AOP_TYPE(right) == AOP_LIT) &&
-       (AOP_TYPE(result) == AOP_CRY) &&
-       (AOP_TYPE(left) != AOP_CRY)){
-        if(lit){
-         pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-            // result = 1
-            if(size)
-                pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
-            else 
-                continueIfTrue(ifx);
-            goto release;
-        } else {
-         pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-            // lit = 0, result = boolean(left)
-            if(size)
-                pic16_emitcode(";XXX setb","c");
-            pic16_toBoolean(right);
-            if(size){
-                symbol *tlbl = newiTempLabel(NULL);
-                pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
-                CLRC;
-                pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-            } else {
-                genIfxJump (ifx,"a");
-                goto release;
+          else
+            {
+              if (AOP_TYPE(left) == AOP_ACC)
+                pic16_emitcode("xrl", "a,%s", pic16_aopGet(AOP(right), offset, FALSE, FALSE));
+              else
+                {
+                  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset));
+                  pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(left), offset));
+                }
             }
         }
-        pic16_outBitC(result);
-        goto release ;
     }
+  else
+    {
+    // left ^ result in different registers
+    if (AOP_TYPE(result) == AOP_CRY)
+      {
+        // result = bit
+        // if(size), result in bit
+        // if(!size && ifx), conditional oper: if(left ^ right)
+        symbol *tlbl = newiTempLabel(NULL);
+        int sizer = max(AOP_SIZE(left), AOP_SIZE(right));
+        if (size)
+          pic16_emitcode("setb", "c");
+        while (sizer--)
+          {
+            if ((AOP_TYPE(right) == AOP_LIT) &&
+              (((lit >> (offset*8)) & 0x0FFL) == 0x00L))
+              {
+                MOVA(pic16_aopGet(AOP(left), offset, FALSE, FALSE));
+              }
+            else
+              {
+                MOVA(pic16_aopGet(AOP(right), offset, FALSE, FALSE));
+                pic16_emitcode("xrl", "a,%s",
+                               pic16_aopGet(AOP(left), offset, FALSE, FALSE));
+              }
+            pic16_emitcode("jnz", "%05d_DS_", tlbl->key + 100);
+            offset++;
+          }
+        if (size)
+          {
+            CLRC;
+            pic16_emitcode("", "%05d_DS_:", tlbl->key + 100);
+            pic16_outBitC(result);
+          }
+        else if (ifx)
+          jmpTrueOrFalse(ifx, tlbl);
+      }
+    else
+      {
+        for (; (size--); offset++)
+          {
+            // normal case
+            // result = left ^ right
+            if (AOP_TYPE(right) == AOP_LIT)
+              {
+                int t = (lit >> (offset * 8)) & 0x0FFL;
+                switch(t)
+                  {
+                  case 0x00:
+                    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
+                    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+                    break;
+
+                  case 0xff:
+                    pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(left), offset));
+                    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+                    break;
+
+                  default:
+                    pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+                    pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left), offset));
+                    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+                  }
+                continue;
+              }
 
-    /* if left is same as result */
-    if(pic16_sameRegs(AOP(result),AOP(left))){
-      int know_W = -1;
-      for(;size--; offset++,lit>>=8) {
-       if(AOP_TYPE(right) == AOP_LIT){
-         if((lit & 0xff) == 0)
-           /*  or'ing with 0 has no effect */
-           continue;
-         else {
-           int p = pic16_my_powof2(lit & 0xff);
-           if(p>=0) {
-             /* only one bit is set in the literal, so use a bsf instruction */
-             pic16_emitpcode(POC_BSF,
-                       pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
-           } else {
-             if(know_W != (lit & 0xff))
-               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
-             know_W = lit & 0xff;
-             pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
-           }
-                   
-         }
-       } else {
-         if (AOP_TYPE(left) == AOP_ACC) {
-           pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(right),offset));
-           pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-         } else {                  
-           pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
-           pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(left),offset));
-
-           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-           pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-
-         }
-       }
+            // faster than result <- left, anl result,right
+            // and better if result is SFR
+            if (AOP_TYPE(left) == AOP_ACC)
+              {
+                pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), offset));
+              }
+            else
+              {
+                pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset));
+                pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left), offset));
+              }
+            if ( AOP_TYPE(result) != AOP_ACC)
+              {
+                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+              }
+          }
       }
-    } else {
-        // left & result in different registers
-        if(AOP_TYPE(result) == AOP_CRY){
-            // result = bit
-            // if(size), result in bit
-            // if(!size && ifx), conditional oper: if(left | right)
-            symbol *tlbl = newiTempLabel(NULL);
-            int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
-           pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-
-
-            if(size)
-                pic16_emitcode(";XXX setb","c");
-            while(sizer--){
-                MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-                pic16_emitcode(";XXX orl","a,%s",
-                         pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-                pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
-                offset++;
-            }
-            if(size){
-                CLRC;
-                pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-                pic16_outBitC(result);
-            } else if(ifx)
-                jmpTrueOrFalse(ifx, tlbl);
-        } else for(;(size--);offset++){
-         // normal case
-         // result = left & right
-         if(AOP_TYPE(right) == AOP_LIT){
-           int t = (lit >> (offset*8)) & 0x0FFL;
-           switch(t) { 
-           case 0x00:
-             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
-             pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
-
-             pic16_emitcode("movf","%s,w",
-                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-             pic16_emitcode("movwf","%s",
-                      pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-             break;
-           default:
-             pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(t));
-             pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
-             pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
-
-             pic16_emitcode("movlw","0x%x",t);
-             pic16_emitcode("iorwf","%s,w",
-                      pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-             pic16_emitcode("movwf","%s",
-                      pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-             
-           }
-           continue;
-         }
-
-         // faster than result <- left, anl result,right
-         // and better if result is SFR
-         if (AOP_TYPE(left) == AOP_ACC) {
-           pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(right),offset));
-           pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-         } else {
-           pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(right),offset));
-           pic16_emitpcode(POC_IORFW,  pic16_popGet(AOP(left),offset));
-
-           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-           pic16_emitcode("iorwf","%s,w",
-                    pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-         }
-         pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
-         pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-       }
-    }
+  }
 
 release :
-    pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(result,NULL,ic,TRUE);     
+  pic16_freeAsmop(left, NULL, ic, (RESULTONSTACK(ic) ? FALSE : TRUE));
+  pic16_freeAsmop(right, NULL, ic, (RESULTONSTACK(ic) ? FALSE : TRUE));
+  pic16_freeAsmop(result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genXor - code for xclusive or                                   */
+/* genInline - write the inline code out                           */
 /*-----------------------------------------------------------------*/
-static void genXor (iCode *ic, iCode *ifx)
+static void genInline (iCode *ic)
 {
-  operand *left, *right, *result;
-  int size, offset=0;
-  unsigned long lit = 0L;
+  char *buffer, *bp, *bp1;
+  bool inComment = FALSE;
 
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-  pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
-  pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-  pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
+  _G.inLine += (!options.asmpeep);
 
-  /* if left is a literal & right is not ||
-     if left needs acc & right does not */
-  if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
-      (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
-    operand *tmp = right ;
-    right = left;
-    left = tmp;
-  }
+  buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
 
-  /* if result = right then exchange them */
-  if(pic16_sameRegs(AOP(result),AOP(right))){
-    operand *tmp = right ;
-    right = left;
-    left = tmp;
+  while((bp1=strstr(bp, "\\n"))) {
+    *bp1++ = '\n';
+    *bp1++ = ' ';
+    bp = bp1;
   }
+  bp = bp1 = buffer;
 
-  /* if right is bit then exchange them */
-  if (AOP_TYPE(right) == AOP_CRY &&
-      AOP_TYPE(left) != AOP_CRY){
-    operand *tmp = right ;
-    right = left;
-    left = tmp;
-  }
-  if(AOP_TYPE(right) == AOP_LIT)
-    lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+#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;
 
-  size = AOP_SIZE(result);
+            bp++;
+            i = *bp - '0';
+            if(i>elementsInSet(asmInlineMap))break;
 
-  // if(bit ^ yy)
-  // xx = bit ^ yy;
-  if (AOP_TYPE(left) == AOP_CRY){
-    if(AOP_TYPE(right) == AOP_LIT){
-      // c = bit & literal;
-      if(lit>>1){
-       // lit>>1  != 0 => result = 1
-       if(AOP_TYPE(result) == AOP_CRY){
-         if(size)
-           {pic16_emitpcode(POC_BSF,  pic16_popGet(AOP(result),offset));
-           pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
-         else if(ifx)
-           continueIfTrue(ifx);
-         goto release;
-       }
-       pic16_emitcode("setb","c");
-      } else{
-       // lit == (0 or 1)
-       if(lit == 0){
-         // lit == 0, result = left
-         if(size && pic16_sameRegs(AOP(result),AOP(left)))
-           goto release;
-         pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-       } else{
-         // lit == 1, result = not(left)
-         if(size && pic16_sameRegs(AOP(result),AOP(left))){
-           pic16_emitpcode(POC_MOVLW,  pic16_popGet(AOP(result),offset));
-           pic16_emitpcode(POC_XORWF,  pic16_popGet(AOP(result),offset));
-           pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
-           goto release;
-         } else {
-           pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-           pic16_emitcode("cpl","c");
-         }
-       }
-      }
+            bp++;
+            s = indexSet(asmInlineMap, i);
+            DEBUGpc("searching symbol s = `%s'", s);
+            sym = findSym(SymbolTab, NULL, s);
 
-    } else {
-      // right != literal
-      symbol *tlbl = newiTempLabel(NULL);
-      if (AOP_TYPE(right) == AOP_CRY){
-       // c = bit ^ bit;
-       pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-      }
-      else{
-       int sizer = AOP_SIZE(right);
-       // c = bit ^ val
-       // if val>>1 != 0, result = 1
-       pic16_emitcode("setb","c");
-       while(sizer){
-         MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
-         if(sizer == 1)
-           // test the msb of the lsb
-           pic16_emitcode("anl","a,#0xfe");
-         pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
-         sizer--;
-       }
-       // val = (0,1)
-       pic16_emitcode("rrc","a");
-      }
-      pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
-      pic16_emitcode("cpl","c");
-      pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
-    }
-    // bit = c
-    // val = c
-    if(size)
-      pic16_outBitC(result);
-    // if(bit | ...)
-    else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-      genIfxJump(ifx, "c");           
-    goto release ;
-  }
+            if(sym->reqv) {
+              strcat(bp1, sym->reqv->operand.symOperand->regs[0]->name);
+            } else {
+              strcat(bp1, sym->rname);
+            }
 
-  if(pic16_sameRegs(AOP(result),AOP(left))){
-    /* if left is same as result */
-    for(;size--; offset++) {
-      if(AOP_TYPE(right) == AOP_LIT){
-       int t  = (lit >> (offset*8)) & 0x0FFL;
-       if(t == 0x00L)
-         continue;
-       else
-         if (IS_AOP_PREG(left)) {
-           MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-           pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
-           pic16_aopPut(AOP(result),"a",offset);
-         } else {
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
-           pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
-           pic16_emitcode("xrl","%s,%s",
-                          pic16_aopGet(AOP(left),offset,FALSE,TRUE),
-                          pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-         }
-      } else {
-       if (AOP_TYPE(left) == AOP_ACC)
-         pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-       else {
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
-         pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
-/*
-         if (IS_AOP_PREG(left)) {
-           pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
-           pic16_aopPut(AOP(result),"a",offset);
-         } else
-           pic16_emitcode("xrl","%s,a",
-                          pic16_aopGet(AOP(left),offset,FALSE,TRUE));
-*/
-       }
-      }
-    }
-  } else {
-    // left & result in different registers
-    if(AOP_TYPE(result) == AOP_CRY){
-      // result = bit
-      // if(size), result in bit
-      // if(!size && ifx), conditional oper: if(left ^ right)
-      symbol *tlbl = newiTempLabel(NULL);
-      int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
-      if(size)
-       pic16_emitcode("setb","c");
-      while(sizer--){
-       if((AOP_TYPE(right) == AOP_LIT) &&
-          (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
-         MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-       } else {
-         MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-         pic16_emitcode("xrl","a,%s",
-                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-       }
-       pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
-       offset++;
-      }
-      if(size){
-       CLRC;
-       pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-       pic16_outBitC(result);
-      } else if(ifx)
-       jmpTrueOrFalse(ifx, tlbl);
-    } else for(;(size--);offset++){
-      // normal case
-      // result = left & right
-      if(AOP_TYPE(right) == AOP_LIT){
-       int t = (lit >> (offset*8)) & 0x0FFL;
-       switch(t) { 
-       case 0x00:
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
-         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
-         pic16_emitcode("movf","%s,w",
-                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-         pic16_emitcode("movwf","%s",
-                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-         break;
-       case 0xff:
-         pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
-         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
-         pic16_emitcode("comf","%s,w",
-                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-         pic16_emitcode("movwf","%s",
-                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-         break;
-       default:
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
-         pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
-         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
-         pic16_emitcode("movlw","0x%x",t);
-         pic16_emitcode("xorwf","%s,w",
-                        pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-         pic16_emitcode("movwf","%s",
-                        pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-
-       }
-       continue;
-      }
+            while(*bp1)bp1++;
+        }
 
-      // faster than result <- left, anl result,right
-      // and better if result is SFR
-      if (AOP_TYPE(left) == AOP_ACC) {
-       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
-       pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-      } else {
-       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
-       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
-       pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-       pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-      }
-      if ( AOP_TYPE(result) != AOP_ACC){
-       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
-       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+        if(strlen(bp1) > cblen - 16) {
+          int i = strlen(cbuf);
+          cblen += 50;
+          cbuf = realloc(cbuf, cblen);
+          memset(cbuf+i, 0, 50);
+          bp1 = cbuf + i;
+        }
       }
-    }
-  }
-
-  release :
-    pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-  pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-  pic16_freeAsmop(result,NULL,ic,TRUE);     
-}
-
-/*-----------------------------------------------------------------*/
-/* genInline - write the inline code out                           */
-/*-----------------------------------------------------------------*/
-static void genInline (iCode *ic)
-{
-  char *buffer, *bp, *bp1;
-    
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-       _G.inLine += (!options.asmpeep);
 
-       buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
-       strcpy(buffer,IC_INLINE(ic));
+      free(buffer);
+      buffer = Safe_strdup( cbuf );
+      free(cbuf);
 
-//     fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
-
-       /* emit each line as a code */
-       while (*bp) {
-               if (*bp == '\n') {
-                       *bp++ = '\0';
+      bp = bp1 = buffer;
+  }
+#endif  /* 0 */
 
-                       if(*bp1)
-                               pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
-                       bp1 = bp;
-               } else {
-                       if (*bp == ':') {
-                               bp++;
-                               *bp = '\0';
-                               bp++;
+  /* emit each line as a code */
+  while (*bp)
+    {
+      switch (*bp)
+        {
+        case ';':
+          inComment = TRUE;
+          ++bp;
+          break;
 
-                               /* print label, use this special format with NULL directive
-                                * to denote that the argument should not be indented with tab */
-                               pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
-                               bp1 = bp;
-                       } else
-                               bp++;
-               }
-       }
+        case '\n':
+          inComment = FALSE;
+          *bp++ = '\0';
+          if (*bp1)
+            pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+          bp1 = bp;
+          break;
 
-       if ((bp1 != bp) && *bp1)
-               pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+        default:
+          /* Add \n for labels, not dirs such as c:\mydir */
+          if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1])))
+            {
+              ++bp;
+              *bp = '\0';
+              ++bp;
+              /* print label, use this special format with NULL directive
+               * to denote that the argument should not be indented with tab */
+              pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
+              bp1 = bp;
+            }
+          else
+            ++bp;
+          break;
+        }
+    }
 
+  if ((bp1 != bp) && *bp1)
+    pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
 
-    Safe_free(buffer);
+  Safe_free (buffer);
 
-    _G.inLine -= (!options.asmpeep);
+  _G.inLine -= (!options.asmpeep);
 }
 
 /*-----------------------------------------------------------------*/
@@ -8673,7 +6402,7 @@ static void genInline (iCode *ic)
 static void genRRC (iCode *ic)
 {
   operand *left , *result ;
-  int size, offset = 0, same;
+  int size, same;
 
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -8681,31 +6410,27 @@ 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);
 
   same = pic16_sameRegs(AOP(result),AOP(left));
 
-  size = AOP_SIZE(result);    
+  size = AOP_SIZE(result);
 
   DEBUGpic16_emitcode ("; ***","%s  %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
 
   /* get the lsb and put it into the carry */
-  pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
-
-  offset = 0 ;
+  pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
 
   while(size--) {
 
     if(same) {
-      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
+      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),size));
     } else {
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size));
+      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size));
     }
-
-    offset++;
   }
 
   pic16_freeAsmop(left,NULL,ic,TRUE);
@@ -8716,7 +6441,7 @@ static void genRRC (iCode *ic)
 /* genRLC - generate code for rotate left with carry               */
 /*-----------------------------------------------------------------*/
 static void genRLC (iCode *ic)
-{    
+{
   operand *left , *result ;
   int size, offset = 0;
   int same;
@@ -8726,14 +6451,14 @@ 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);
 
   same = pic16_sameRegs(AOP(result),AOP(left));
 
   /* move it to the result */
-  size = AOP_SIZE(result);    
+  size = AOP_SIZE(result);
 
   /* get the msb and put it into the carry */
   pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
@@ -8760,7 +6485,7 @@ static void genRLC (iCode *ic)
 
 /* gpasm can get the highest order bit with HIGH/UPPER
  * so the following probably is not needed -- VR */
+
 /*-----------------------------------------------------------------*/
 /* genGetHbit - generates code get highest order bit               */
 /*-----------------------------------------------------------------*/
@@ -8833,41 +6558,43 @@ static void AccRol (int shCount)
 /*-----------------------------------------------------------------*/
 /* AccLsh - left shift accumulator by known count                  */
 /*-----------------------------------------------------------------*/
-static void AccLsh (int shCount)
-{
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       switch(shCount){
-               case 0 :
-                       return;
-                       break;
-               case 1 :
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 2 :
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 3 :
-                       pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 4 :
-                       pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 5 :
-                       pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 6 :
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 7 :
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-       }
-
-       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
+static void AccLsh (int shCount, int doMask)
+{
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        switch(shCount){
+                case 0 :
+                        return;
+                        break;
+                case 1 :
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 2 :
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 3 :
+                        pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 4 :
+                        pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 5 :
+                        pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 6 :
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 7 :
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+        }
+        if (doMask) {
+                /* no masking is required in genPackBits */
+                pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
+        }
 }
 
 /*-----------------------------------------------------------------*/
@@ -8875,74 +6602,46 @@ static void AccLsh (int shCount)
 /*-----------------------------------------------------------------*/
 static void AccRsh (int shCount, int andmask)
 {
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       switch(shCount){
-               case 0 :
-                       return; break;
-               case 1 :
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 2 :
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 3 :
-                       pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 4 :
-                       pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 5 :
-                       pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 6 :
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-               case 7 :
-                       pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
-                       break;
-       }
-       
-       if(andmask)
-               pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
-       else
-               DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
-}
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* AccSRsh - signed right shift accumulator by known count                 */
-/*-----------------------------------------------------------------*/
-static void AccSRsh (int shCount)
-{
-    symbol *tlbl ;
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(shCount != 0){
-        if(shCount == 1){
-            pic16_emitcode("mov","c,acc.7");
-            pic16_emitcode("rrc","a");
-        } else if(shCount == 2){
-            pic16_emitcode("mov","c,acc.7");
-            pic16_emitcode("rrc","a");
-            pic16_emitcode("mov","c,acc.7");
-            pic16_emitcode("rrc","a");
-        } else {
-            tlbl = newiTempLabel(NULL);
-            /* rotate right accumulator */
-            AccRol(8 - shCount);
-            /* and kill the higher order bits */
-            pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
-            pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
-            pic16_emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);
-            pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        assert ((shCount >= 0) && (shCount <= 8));
+        switch (shCount) {
+                case 0 :
+                        return; break;
+                case 1 :
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 2 :
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 3 :
+                        pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 4 :
+                        pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 5 :
+                        pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 6 :
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                case 7 :
+                        pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+                        break;
+                default:
+                        // Rotating by 8 is a NOP.
+                        break;
         }
-    }
+
+        if (andmask)
+                pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
+        else
+                DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
 }
-#endif
 
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
@@ -8954,103 +6653,82 @@ static void shiftR1Left2ResultSigned (operand *left, int offl,
   int same;
 
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  assert ((shCount >= 0) && (shCount <= 8));
 
   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
 
-  switch(shCount) {
-  case 1:
-    pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
-    if(same) 
-      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
-    else {
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+  /* Do NOT use result for intermediate results, it might be an SFR!. */
+  switch (shCount) {
+  case 0:
+    if (!same) {
+      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offl));
+      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     }
-
     break;
-  case 2:
 
-    pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
-    if(same) 
-      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
+  case 1:
+    pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), offl));
+    if (same)
+      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result), offr));
     else {
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left), offl));
+      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     }
-    pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
+    break;
 
+  case 2:
+    pic16_emitpcode(POC_RRNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RRNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x3f)); // keep sign bit in W<5>
+    pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_wreg), 5));
+    pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xc0)); // sign-extend
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   case 3:
-    if(same)
-      pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
-    else {
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
-    }
-
-    pic16_emitpcode(POC_RLNCFW,  pic16_popGet(AOP(result),offr));
-    //pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
-
-    pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
-    pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
-
-    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RLNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f)); // keep sign in W<4>
+    pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_wreg), 4));
+    pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0)); // sign-extend
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   case 4:
-    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x0f));
-    pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-    pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf0));
-    pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f)); // keep sign in W<3>
+    pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_wreg), 3));
+    pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0)); // sign-extend
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
+
   case 5:
-    if(same) {
-      pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(result),offr));
-    } else {
-      pic16_emitpcode(POC_SWAPFW,  pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
-    }
-    pic16_emitpcode(POC_RRCFW,   pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0x07));
-    pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
-    pic16_emitpcode(POC_IORLW,  pic16_popGetLit(0xf8));
-    pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RRNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07)); // keep sign in W<2>
+    pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_wreg), 2));
+    pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8)); // sign-extend
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   case 6:
-    if(same) {
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
-      pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
-      pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
-    } 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_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));
-    }
+    pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RLNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x03)); // keep sign bit in W<1>
+    pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_wreg), 1));
+    pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xfc)); // sign-extend
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   case 7:
-    if(same) {
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
-      pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
-    } 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_MOVLW, pic16_popGetLit(0x00));
+    pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), offl), 7));
+    pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
+    break;
 
   default:
+    pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offr));
     break;
   }
 }
@@ -9065,85 +6743,78 @@ static void shiftR1Left2Result (operand *left, int offl,
   int same;
 
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  assert ((shCount >= 0) && (shCount <= 8));
 
   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
 
   /* Copy the msb into the carry if signed. */
-  if(sign) {
-    shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
+  if (sign) {
+    shiftR1Left2ResultSigned(left, offl, result, offr, shCount);
     return;
   }
 
-
-
-  switch(shCount) {
-  case 1:
-    emitCLRC;
-    if(same) 
-      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
-    else {
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+  /* Do NOT use result for intermediate results, it might be an SFR!. */
+  switch (shCount) {
+  case 0:
+    if (!same) {
+      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offl));
+      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     }
     break;
-  case 2:
-    emitCLRC;
-    if(same) {
-      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
-    } else {
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
-    }
-    emitCLRC;
-    pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
 
-    break;
-  case 3:
-    if(same)
-      pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
-    else {
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+  case 1:
+    if (same) {
+      emitCLRC;
+      pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result), offr));
+    } else {
+      pic16_emitpcode(POC_RRNCFW, pic16_popGet(AOP(left), offl));
+      pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x7f));
+      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     }
+    break;
+
+  case 2:
+    pic16_emitpcode(POC_RRNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RRNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x3f));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
+    break;
 
-    pic16_emitpcode(POC_RLNCFW,  pic16_popGet(AOP(result),offr));
-    //pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offr));
+  case 3:
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RLNCFW, pic16_popCopyReg(&pic16_pc_wreg));
     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
-    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
-      
+
   case 4:
-    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
-    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   case 5:
-    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0e));
-    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
-    //emitCLRC;
-    pic16_emitpcode(POC_RRNCF, pic16_popGet(AOP(result),offr));
-
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RRNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
-  case 6:
 
-    pic16_emitpcode(POC_RLNCFW,  pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x81));
-    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
-    //pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_RLNCF,   pic16_popGet(AOP(result),offr));
+  case 6:
+    pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RLNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x03));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   case 7:
-
-    pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
-
+    pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x01));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   default:
+    pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offr));
     break;
   }
 }
@@ -9156,69 +6827,75 @@ static void shiftL1Left2Result (operand *left, int offl,
 {
   int same;
 
-  //    char *l;
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  assert ((shCount >= 0) && (shCount <= 8));
 
   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
-  DEBUGpic16_emitcode ("; ***","same =  %d",same);
-    //    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
-    //    MOVA(l);
-    /* shift left accumulator */
-    //AccLsh(shCount); // don't comment out just yet...
-  //    pic16_aopPut(AOP(result),"a",offr);
 
-  switch(shCount) {
+  /* Do NOT use result for intermediate results, it might be an SFR!. */
+  switch (shCount) {
+  case 0:
+    if (!same) {
+      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offl));
+      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
+    }
+    break;
+
   case 1:
-    /* Shift left 1 bit position */
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
-    if(same) {
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
+    if (same) {
+      emitCLRC;
+      pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left), offl));
     } else {
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), offl));
+      pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
+      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     }
     break;
+
   case 2:
-    pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
-    pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RLNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfc));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
+
   case 3:
-    pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
-    pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RRNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf8));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
+
   case 4:
-    pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
     pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
-    pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
+
   case 5:
-    pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
-    pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RLNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
+
   case 6:
-    pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
-    pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_RRNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_RRNCFW, pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
+
   case 7:
-    pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
-    pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
-    pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
+    pic16_emitpcode(POC_RRNCFW, pic16_popGet(AOP(left), offl));
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offr));
     break;
 
   default:
-    DEBUGpic16_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
+    pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offr));
+    break;
   }
-
 }
 
 /*-----------------------------------------------------------------*/
@@ -9227,18 +6904,10 @@ static void shiftL1Left2Result (operand *left, int offl,
 static void movLeft2Result (operand *left, int offl,
                             operand *result, int offr)
 {
-  char *l;
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
-    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
-
-    if (*l == '@' && (IS_AOP_PREG(result))) {
-      pic16_emitcode("mov","a,%s",l);
-      pic16_aopPut(AOP(result),"a",offr);
-    } else {
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
-    }
+  if (!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)) {
+    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
   }
 }
 
@@ -9260,7 +6929,7 @@ static void shiftL2Left2Result (operand *left, int offl,
          pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
        }
     } else { // just treat as different later on
-               same = 0;
+                same = 0;
     }
   }
 
@@ -9277,9 +6946,9 @@ static void shiftL2Left2Result (operand *left, int offl,
       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
 
       while(--shCount) {
-               emitCLRC;
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+                emitCLRC;
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
       }
 
       break;
@@ -9293,8 +6962,8 @@ static void shiftL2Left2Result (operand *left, int offl,
       pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
       if(shCount >=5) {
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
       }
       break;
     case 6:
@@ -9325,7 +6994,7 @@ static void shiftL2Left2Result (operand *left, int offl,
     case 2:
     case 3:
       /* note, use a mov/add for the shift since the mov has a
-        chance of getting optimized out */
+         chance of getting optimized out */
       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
@@ -9333,9 +7002,9 @@ static void shiftL2Left2Result (operand *left, int offl,
       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
 
       while(--shCount) {
-               emitCLRC;
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+                emitCLRC;
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
       }
       break;
 
@@ -9352,24 +7021,23 @@ static void shiftL2Left2Result (operand *left, int offl,
 
 
       if(shCount == 5) {
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
-               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
       }
       break;
     case 6:
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
-      pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
+      pic16_emitpcode(POC_RRNCFW, pic16_popGet(AOP(left),offl));
       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr));
-
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr+MSB16));
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),offr));
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
-      pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
-      pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
-      pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
-      pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
-      pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
+      pic16_emitpcode(POC_RRNCF,  pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_RRNCFW, pic16_popGet(AOP(left),offl+MSB16));
+      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offr+MSB16));
+      pic16_emitpcode(POC_RRNCF,  pic16_popGet(AOP(result),offr+MSB16));
+      pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xc0));
+      pic16_emitpcode(POC_ANDWF,  pic16_popGet(AOP(result),offr+MSB16));
+      pic16_emitpcode(POC_ANDFW,  pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_XORFW,  pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_IORWF,  pic16_popGet(AOP(result),offr+MSB16));
+      pic16_emitpcode(POC_XORWF,  pic16_popGet(AOP(result),offr));
       break;
     case 7:
       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
@@ -9399,7 +7067,7 @@ static void shiftR2Left2Result (operand *left, int offl,
          pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
        }
     } else { // just treat as different later on
-               same = 0;
+                same = 0;
     }
   }
 
@@ -9409,8 +7077,9 @@ static void shiftR2Left2Result (operand *left, int offl,
   case 1:
   case 2:
   case 3:
+    /* obtain sign from left operand */
     if(sign)
-      pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
+      pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),offr+MSB16));
     else
       emitCLRC;
 
@@ -9426,9 +7095,10 @@ static void shiftR2Left2Result (operand *left, int offl,
 
     while(--shCount) {
       if(sign)
-               pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
+        /* now get sign from already assigned result (avoid BANKSEL) */
+        pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
       else
-               emitCLRC;
+        emitCLRC;
       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
       pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
     }
@@ -9464,8 +7134,8 @@ static void shiftR2Left2Result (operand *left, int offl,
 
     if(sign) {
       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
-      pic16_emitpcode(POC_BTFSC, 
-               pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
+      pic16_emitpcode(POC_BTFSC,
+                pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
       pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
     }
 
@@ -9482,9 +7152,9 @@ static void shiftR2Left2Result (operand *left, int offl,
       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
       if(sign) {
-       pic16_emitpcode(POC_BTFSC, 
-                 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
-       pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
+        pic16_emitpcode(POC_BTFSC,
+                  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
+        pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
       }
       pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
@@ -9500,14 +7170,14 @@ static void shiftR2Left2Result (operand *left, int offl,
       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
       if(sign) {
-       pic16_emitpcode(POC_BTFSC, 
-                 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
-       pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
+        pic16_emitpcode(POC_BTFSC,
+                  pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
+        pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
       }
       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
       //pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr));
 
-       
+
     }
 
     break;
@@ -9519,7 +7189,7 @@ static void shiftR2Left2Result (operand *left, int offl,
     if(sign) {
       emitSKPNC;
       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
-    } else 
+    } else
       pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offr+MSB16));
   }
 }
@@ -9535,7 +7205,7 @@ static void shiftLLeftOrResult (operand *left, int offl,
 
     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
     /* shift left accumulator */
-    AccLsh(shCount);
+    AccLsh(shCount, 1);
     /* or with result */
     /* back to result */
     pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
@@ -9548,7 +7218,7 @@ static void shiftRLeftOrResult (operand *left, int offl,
                                 operand *result, int offr, int shCount)
 {
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    
+
     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
     /* shift right accumulator */
     AccRsh(shCount, 1);
@@ -9561,7 +7231,7 @@ static void shiftRLeftOrResult (operand *left, int offl,
 /* genlshOne - left shift a one byte quantity by known count       */
 /*-----------------------------------------------------------------*/
 static void genlshOne (operand *result, operand *left, int shCount)
-{       
+{
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     shiftL1Left2Result(left, LSB, result, LSB, shCount);
 }
@@ -9572,7 +7242,7 @@ static void genlshOne (operand *result, operand *left, int shCount)
 static void genlshTwo (operand *result,operand *left, int shCount)
 {
     int size;
-    
+
     DEBUGpic16_emitcode ("; ***","%s  %d shCount:%d",__FUNCTION__,__LINE__,shCount);
     size = pic16_getDataSize(result);
 
@@ -9583,17 +7253,17 @@ static void genlshTwo (operand *result,operand *left, int shCount)
         if (size > 1){
             if (shCount)
                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
-            else 
+            else
                 movLeft2Result(left, LSB, result, MSB16);
         }
-       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
     }
 
     /*  1 <= shCount <= 7 */
-    else {  
+    else {
         if(size == 1)
-            shiftL1Left2Result(left, LSB, result, LSB, shCount); 
-        else 
+            shiftL1Left2Result(left, LSB, result, LSB, shCount);
+        else
             shiftL2Left2Result(left, LSB, result, LSB, shCount);
     }
 }
@@ -9606,56 +7276,56 @@ static void shiftLLong (operand *left, operand *result, int offr )
 {
     int size = AOP_SIZE(result);
     int same = pic16_sameRegs(AOP(left),AOP(result));
-       int i;
+        int i;
 
     DEBUGpic16_emitcode ("; ***","%s  %d  offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
 
-       if (same && (offr == MSB16)) { //shift one byte
-               for(i=size-1;i>=MSB16;i--) {
-                       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
-                       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
-               }
-       } else {
-               pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
-       }
-       
+        if (same && (offr == MSB16)) { //shift one byte
+                for(i=size-1;i>=MSB16;i--) {
+                        pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
+                        pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
+                }
+        } else {
+                pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB));
+        }
+
     if (size > LSB+offr ){
-               if (same) {
-                       pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
-               } else {
-                       pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
-                       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
-               }
-        }
+                if (same) {
+                        pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
+                } else {
+                        pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
+                        pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
+                }
+         }
 
     if(size > MSB16+offr){
-               if (same) {
-                       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
-               } else {
-                       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
-                       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
-               }
+                if (same) {
+                        pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
+                } else {
+                        pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
+                        pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
+                }
     }
 
     if(size > MSB24+offr){
-               if (same) {
-                       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
-               } else {
-                       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
-                       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
-               }
+                if (same) {
+                        pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
+                } else {
+                        pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
+                        pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
+                }
     }
 
     if(size > MSB32+offr){
-               if (same) {
-                       pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
-               } else {
-                       pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
-                       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
-               }
+                if (same) {
+                        pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
+                } else {
+                        pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
+                        pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
+                }
     }
     if(offr != LSB)
-               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
 
 }
 
@@ -9679,9 +7349,9 @@ static void genlshFour (operand *result, operand *left, int shCount)
         else
             movLeft2Result(left, LSB, result, MSB32);
 
-               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
-               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
-               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
+                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
+                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
 
         return;
     }
@@ -9697,10 +7367,10 @@ static void genlshFour (operand *result, operand *left, int shCount)
             movLeft2Result(left, MSB16, result, MSB32);
             movLeft2Result(left, LSB, result, MSB24);
         }
-               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
-               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
+                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
         return;
-    }    
+    }
 
     /* if more than 1 byte */
     else if ( shCount >= 8 ) {
@@ -9717,7 +7387,7 @@ static void genlshFour (operand *result, operand *left, int shCount)
                 movLeft2Result(left, MSB24, result, MSB32);
                 movLeft2Result(left, MSB16, result, MSB24);
                 movLeft2Result(left, LSB, result, MSB16);
-                               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+                                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
             }
             else if(shCount == 1)
                 shiftLLong(left, result, MSB16);
@@ -9725,14 +7395,14 @@ static void genlshFour (operand *result, operand *left, int shCount)
                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
-                               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+                                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
             }
         }
     }
 
     /* 1 <= shCount <= 7 */
     else if(shCount <= 3)
-    { 
+    {
         shiftLLong(left, result, LSB);
         while(--shCount >= 1)
             shiftLLong(result, result, LSB);
@@ -9751,449 +7421,83 @@ static void genlshFour (operand *result, operand *left, int shCount)
 void pic16_genLeftShiftLiteral (operand *left,
                                  operand *right,
                                  operand *result,
-                                 iCode *ic)
-{    
-    int shCount = (int) abs(floatFromVal (AOP(right)->aopu.aop_lit));
-    int size;
-
-    FENTRY;
-    DEBUGpic16_emitcode ("; ***","shCount:%d", shCount);
-    pic16_freeAsmop(right,NULL,ic,TRUE);
-
-    pic16_aopOp(left,ic,FALSE);
-    pic16_aopOp(result,ic,FALSE);
-
-    size = getSize(operandType(result));
-
-#if VIEW_SIZE
-    pic16_emitcode("; shift left ","result %d, left %d",size,
-             AOP_SIZE(left));
-#endif
-
-    /* I suppose that the left size >= result size */
-    if(shCount == 0){
-        while(size--){
-            movLeft2Result(left, size, result, size);
-        }
-    }
-
-    else if(shCount >= (size * 8))
-        while(size--)
-            pic16_aopPut(AOP(result),zero,size);
-    else{
-        switch (size) {
-            case 1:
-                genlshOne (result,left,shCount);
-                break;
-
-            case 2:
-            case 3:
-                genlshTwo (result,left,shCount);
-                break;
-
-            case 4:
-                genlshFour (result,left,shCount);
-                break;
-        }
-    }
-    pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-
-/*-----------------------------------------------------------------*
- * genMultiAsm - repeat assembly instruction for size of register.
- * if endian == 1, then the high byte (i.e base address + size of 
- * register) is used first else the low byte is used first;
- *-----------------------------------------------------------------*/
-static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
-{
-
-  int offset = 0;
-
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  if(!reg)
-    return;
-
-  if(!endian) {
-    endian = 1;
-  } else {
-    endian = -1;
-    offset = size-1;
-  }
-
-  while(size--) {
-    pic16_emitpcode(poc,    pic16_popGet(AOP(reg),offset));
-    offset += endian;
-  }
-
-}
-
-#if !(USE_GENERIC_SIGNED_SHIFT)
-/*-----------------------------------------------------------------*/
-/* genLeftShift - generates code for left shifting                 */
-/*-----------------------------------------------------------------*/
-static void genLeftShift (iCode *ic)
-{
-  operand *left,*right, *result;
-  int size, offset;
-//  char *l;
-  symbol *tlbl , *tlbl1;
-  pCodeOp *pctemp;
-
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  right = IC_RIGHT(ic);
-  left  = IC_LEFT(ic);
-  result = IC_RESULT(ic);
-
-  pic16_aopOp(right,ic,FALSE);
-
-  /* if the shift count is known then do it 
-     as efficiently as possible */
-  if (AOP_TYPE(right) == AOP_LIT) {
-    pic16_genLeftShiftLiteral (left,right,result,ic);
-    return ;
-  }
-
-  /* shift count is unknown then we have to form
-   * a loop. Get the loop count in WREG : Note: we take
-   * only the lower order byte since shifting
-   * more than 32 bits make no sense anyway, ( the
-   * largest size of an object can be only 32 bits ) */
-  
-  pic16_aopOp(left,ic,FALSE);
-  pic16_aopOp(result,ic,FALSE);
-
-  /* now move the left to the result if they are not the
-   * same, and if size > 1,
-   * and if right is not same to result (!!!) -- VR */
-  if (!pic16_sameRegs(AOP(left),AOP(result))
-      && (AOP_SIZE(result) > 1)) {
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    size = AOP_SIZE(result);
-    offset=0;
-    while (size--) {
-
-#if 0
-      l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
-      if (*l == '@' && (IS_AOP_PREG(result))) {
-
-          pic16_emitcode("mov","a,%s",l);
-          pic16_aopPut(AOP(result),"a",offset);
-      } else
-#endif
-      {
-        /* we don't know if left is a literal or a register, take care -- VR */
-        mov2f(AOP(result), AOP(left), offset);
-      }
-      offset++;
-    }
-  }
-
-  size = AOP_SIZE(result);
-
-  /* if it is only one byte then */
-  if (size == 1) {
-    if(optimized_for_speed) {
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_RLCFW,   pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xfe));
-      pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
-    } else {
-
-      DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-      tlbl = newiTempLabel(NULL);
-
-#if 1
-      /* this is already done, why change it? */
-      if (!pic16_sameRegs(AOP(left),AOP(result))) {
-                mov2f(AOP(result), AOP(left), 0);
-      }
-#endif
-
-      pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
-      pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
-      pic16_emitpLabel(tlbl->key);
-      pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
-      emitSKPC;
-      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-    }
-    goto release ;
-  }
-    
-  if (pic16_sameRegs(AOP(left),AOP(result))) {
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    
-    tlbl = newiTempLabel(NULL);
-    pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
-    genMultiAsm(POC_RRCF, result, size,1);
-    pic16_emitpLabel(tlbl->key);
-    genMultiAsm(POC_RLCF, result, size,0);
-    pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
-    emitSKPC;
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-    goto release;
-  }
-
-  //tlbl = newiTempLabel(NULL);
-  //offset = 0 ;   
-  //tlbl1 = newiTempLabel(NULL);
-
-  //reAdjustPreg(AOP(result));    
-    
-  //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
-  //pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
-  //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
-  //MOVA(l);
-  //pic16_emitcode("add","a,acc");         
-  //pic16_aopPut(AOP(result),"a",offset++);
-  //while (--size) {
-  //  l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
-  //  MOVA(l);
-  //  pic16_emitcode("rlc","a");         
-  //  pic16_aopPut(AOP(result),"a",offset++);
-  //}
-  //reAdjustPreg(AOP(result));
-
-  //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
-  //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-
-
-  tlbl = newiTempLabel(NULL);
-  tlbl1= newiTempLabel(NULL);
-
-  size = AOP_SIZE(result);
-  offset = 1;
-
-  pctemp = pic16_popGetTempReg(1);  /* grab a temporary working register. */
-
-  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
-  /* offset should be 0, 1 or 3 */
-  
-  pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
-  emitSKPNZ;
-  pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
-
-  pic16_emitpcode(POC_MOVWF, pctemp);
-
-
-  pic16_emitpLabel(tlbl->key);
-
-  emitCLRC;
-  pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),0));
-  while(--size)
-    pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offset++));
-
-  pic16_emitpcode(POC_DECFSZ,  pctemp);
-  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-  pic16_emitpLabel(tlbl1->key);
-
-  pic16_popReleaseTempReg(pctemp,1);
-
-
- release:
-  pic16_freeAsmop (right,NULL,ic,TRUE);
-  pic16_freeAsmop(left,NULL,ic,TRUE);
-  pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-#endif
-
-
-#if 0
-#error old code (left here for reference)
-/*-----------------------------------------------------------------*/
-/* genLeftShift - generates code for left shifting                 */
-/*-----------------------------------------------------------------*/
-static void genLeftShift (iCode *ic)
-{
-  operand *left,*right, *result;
-  int size, offset;
-  char *l;
-  symbol *tlbl , *tlbl1;
-  pCodeOp *pctemp;
-
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  right = IC_RIGHT(ic);
-  left  = IC_LEFT(ic);
-  result = IC_RESULT(ic);
-
-  pic16_aopOp(right,ic,FALSE);
+                                 iCode *ic)
+{
+    int shCount = abs((int) ulFromVal (AOP(right)->aopu.aop_lit));
+    int size;
 
-  /* if the shift count is known then do it 
-     as efficiently as possible */
-  if (AOP_TYPE(right) == AOP_LIT) {
-    pic16_genLeftShiftLiteral (left,right,result,ic);
-    return ;
-  }
+    FENTRY;
+    DEBUGpic16_emitcode ("; ***","shCount:%d", shCount);
+    pic16_freeAsmop(right,NULL,ic,TRUE);
 
-  /* shift count is unknown then we have to form 
-     a loop get the loop count in B : Note: we take
-     only the lower order byte since shifting
-     more that 32 bits make no sense anyway, ( the
-     largest size of an object can be only 32 bits ) */  
+    pic16_aopOp(left,ic,FALSE);
+    pic16_aopOp(result,ic,TRUE);
 
-    
-  pic16_aopOp(left,ic,FALSE);
-  pic16_aopOp(result,ic,FALSE);
+    size = getSize(operandType(result));
 
-  /* now move the left to the result if they are not the
-     same */
-  if (!pic16_sameRegs(AOP(left),AOP(result)) && 
-      AOP_SIZE(result) > 1) {
+#if VIEW_SIZE
+    pic16_emitcode("; shift left ","result %d, left %d",size,
+             AOP_SIZE(left));
+#endif
 
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    /* I suppose that the left size >= result size */
+    if(shCount == 0){
+        while(size--){
+            movLeft2Result(left, size, result, size);
+        }
+    }
 
-    size = AOP_SIZE(result);
-    offset=0;
-    while (size--) {
-      l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
-      if (*l == '@' && (IS_AOP_PREG(result))) {
+    else if(shCount >= (size * 8))
+        while(size--)
+            pic16_aopPut(AOP(result),zero,size);
+    else{
+        switch (size) {
+            case 1:
+                genlshOne (result,left,shCount);
+                break;
 
-       pic16_emitcode("mov","a,%s",l);
-       pic16_aopPut(AOP(result),"a",offset);
-      } else {
+            case 2:
+            case 3:
+                genlshTwo (result,left,shCount);
+                break;
 
-        /* we don't know if left is a literal or a register, take care -- VR */
-        mov2f(AOP(result), AOP(left), offset);
-      }
-      offset++;
+            case 4:
+                genlshFour (result,left,shCount);
+                break;
+        }
     }
-  }
+    pic16_freeAsmop(left,NULL,ic,TRUE);
+    pic16_freeAsmop(result,NULL,ic,TRUE);
+}
 
-  size = AOP_SIZE(result);
+/*-----------------------------------------------------------------*
+ * genMultiAsm - repeat assembly instruction for size of register.
+ * if endian == 1, then the high byte (i.e base address + size of
+ * register) is used first else the low byte is used first;
+ *-----------------------------------------------------------------*/
+static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
+{
 
-  /* if it is only one byte then */
-  if (size == 1) {
-    if(optimized_for_speed) {
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_BTFSS,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_RLCFW,   pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xfe));
-      pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),0));
-    } else {
+  int offset = 0;
 
-      DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-      tlbl = newiTempLabel(NULL);
-      if (!pic16_sameRegs(AOP(left),AOP(result))) {
-                mov2f(AOP(result), AOP(left), 0);
-                
-//             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
-//             pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
-      }
+  if(!reg)
+    return;
 
-      pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
-      pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
-      pic16_emitpLabel(tlbl->key);
-      pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
-      emitSKPC;
-      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-    }
-    goto release ;
+  if(!endian) {
+    endian = 1;
+  } else {
+    endian = -1;
+    offset = size-1;
   }
-    
-  if (pic16_sameRegs(AOP(left),AOP(result))) {
 
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    
-    tlbl = newiTempLabel(NULL);
-    pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
-    genMultiAsm(POC_RRCF, result, size,1);
-    pic16_emitpLabel(tlbl->key);
-    genMultiAsm(POC_RLCF, result, size,0);
-    pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
-    emitSKPC;
-    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-    goto release;
+  while(size--) {
+    pic16_emitpcode(poc,    pic16_popGet(AOP(reg),offset));
+    offset += endian;
   }
 
-  //tlbl = newiTempLabel(NULL);
-  //offset = 0 ;   
-  //tlbl1 = newiTempLabel(NULL);
-
-  //reAdjustPreg(AOP(result));    
-    
-  //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
-  //pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
-  //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
-  //MOVA(l);
-  //pic16_emitcode("add","a,acc");         
-  //pic16_aopPut(AOP(result),"a",offset++);
-  //while (--size) {
-  //  l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
-  //  MOVA(l);
-  //  pic16_emitcode("rlc","a");         
-  //  pic16_aopPut(AOP(result),"a",offset++);
-  //}
-  //reAdjustPreg(AOP(result));
-
-  //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
-  //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-
-
-  tlbl = newiTempLabel(NULL);
-  tlbl1= newiTempLabel(NULL);
-
-  size = AOP_SIZE(result);
-  offset = 1;
-
-  pctemp = pic16_popGetTempReg(1);  /* grab a temporary working register. */
-
-  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
-  /* offset should be 0, 1 or 3 */
-  
-  pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
-  emitSKPNZ;
-  pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
-
-  pic16_emitpcode(POC_MOVWF, pctemp);
-
-
-  pic16_emitpLabel(tlbl->key);
-
-  emitCLRC;
-  pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),0));
-  while(--size)
-    pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(result),offset++));
-
-  pic16_emitpcode(POC_DECFSZ,  pctemp);
-  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-  pic16_emitpLabel(tlbl1->key);
-
-  pic16_popReleaseTempReg(pctemp,1);
-
-
- release:
-  pic16_freeAsmop (right,NULL,ic,TRUE);
-  pic16_freeAsmop(left,NULL,ic,TRUE);
-  pic16_freeAsmop(result,NULL,ic,TRUE);
 }
-#endif
 
 /*-----------------------------------------------------------------*/
 /* genrshOne - right shift a one byte quantity by known count      */
@@ -10217,21 +7521,16 @@ static void genrshTwo (operand *result,operand *left,
     shCount -= 8 ;
     if (shCount)
       shiftR1Left2Result(left, MSB16, result, LSB,
-                        shCount, sign);
+                         shCount, sign);
     else
       movLeft2Result(left, MSB16, result, LSB);
 
-    pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
-
-    if(sign) {
-      pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
-    }
+    pic16_addSign (result, 1, sign);
   }
 
   /*  1 <= shCount <= 7 */
   else
-    shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
+    shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
 }
 
 /*-----------------------------------------------------------------*/
@@ -10246,53 +7545,53 @@ static void shiftRLong (operand *left, int offl,
     int i;
     DEBUGpic16_emitcode ("; ***","%s  %d  offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
 
-       if (same && (offl == MSB16)) { //shift one byte right
-               for(i=MSB16;i<size;i++) {
-                       pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
-                       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
-               }
-       }
+        if (same && (offl == MSB16)) { //shift one byte right
+                for(i=MSB16;i<size;i++) {
+                        pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
+                        pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
+                }
+        }
 
     if(sign)
-               pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
-       else
-               emitCLRC;
-
-       if (same) {
-               if (offl == LSB)
-               pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
-       } else {
-       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
-       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
-       }
+                pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
+        else
+                emitCLRC;
+
+        if (same) {
+                if (offl == LSB)
+                pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
+        } else {
+        pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
+        }
 
     if(offl == MSB16) {
         /* add sign of "a" */
         pic16_addSign(result, MSB32, sign);
-       }
-
-       if (same) {
-       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
-       } else {
-       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
-       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
-       }
-       
-       if (same) {
-       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
-       } else {
-       pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
-       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
-       }
-
-       if (same) {
-       pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
-       } else {
-       if(offl == LSB){
-               pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
-               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
-       }
-       }
+        }
+
+        if (same) {
+        pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
+        } else {
+        pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
+        }
+
+        if (same) {
+        pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
+        } else {
+        pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
+        }
+
+        if (same) {
+        pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
+        } else {
+        if(offl == LSB){
+                pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
+                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
+        }
+        }
 }
 
 /*-----------------------------------------------------------------*/
@@ -10344,7 +7643,7 @@ static void genrshFour (operand *result, operand *left,
     if(shCount <= 2){
       shiftRLong(left, LSB, result, sign);
       if(shCount == 2)
-       shiftRLong(result, LSB, result, sign);
+        shiftRLong(result, LSB, result, sign);
     }
     else{
       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
@@ -10362,347 +7661,79 @@ static void genRightShiftLiteral (operand *left,
                                   operand *result,
                                   iCode *ic,
                                   int sign)
-{    
-  int shCount = (int) abs(floatFromVal (AOP(right)->aopu.aop_lit));
+{
+  int shCount = abs((int) ulFromVal (AOP(right)->aopu.aop_lit));
   int lsize,res_size;
 
   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));
 
 #if VIEW_SIZE
   pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
-                AOP_SIZE(left));
-#endif
-
-  lsize = pic16_getDataSize(left);
-  res_size = pic16_getDataSize(result);
-  /* test the LEFT size !!! */
-
-  /* I suppose that the left size >= result size */
-  if(shCount == 0){
-    while(res_size--)
-      movLeft2Result(left, lsize, result, res_size);
-  }
-
-  else if(shCount >= (lsize * 8)){
-
-    if(res_size == 1) {
-      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));
-      }
-    } else {
-
-      if(sign) {
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
-       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
-       while(res_size--)
-         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
-
-      } else {
-
-       while(res_size--)
-         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
-      }
-    }
-  } else {
-
-    switch (res_size) {
-    case 1:
-      genrshOne (result,left,shCount,sign);
-      break;
-
-    case 2:
-      genrshTwo (result,left,shCount,sign);
-      break;
-
-    case 4:
-      genrshFour (result,left,shCount,sign);
-      break;
-    default :
-      break;
-    }
-
-  }
-
-  pic16_freeAsmop(left,NULL,ic,TRUE);
-  pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-
-#if !(USE_GENERIC_SIGNED_SHIFT)
-/*-----------------------------------------------------------------*/
-/* genSignedRightShift - right shift of signed number              */
-/*-----------------------------------------------------------------*/
-static void genSignedRightShift (iCode *ic)
-{
-  operand *right, *left, *result;
-  int size, offset;
-  //  char *l;
-  symbol *tlbl, *tlbl1 ;
-  pCodeOp *pctemp;
-
-  //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
-
-  /* we do it the hard way put the shift count in b
-     and loop thru preserving the sign */
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  right = IC_RIGHT(ic);
-  left  = IC_LEFT(ic);
-  result = IC_RESULT(ic);
-
-  pic16_aopOp(right,ic,FALSE);  
-  pic16_aopOp(left,ic,FALSE);
-  pic16_aopOp(result,ic,FALSE);
-
-
-  if ( AOP_TYPE(right) == AOP_LIT) {
-    genRightShiftLiteral (left,right,result,ic,1);
-    return ;
-  }
-  /* shift count is unknown then we have to form 
-     a loop get the loop count in B : Note: we take
-     only the lower order byte since shifting
-     more that 32 bits make no sense anyway, ( the
-     largest size of an object can be only 32 bits ) */  
-
-  //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
-  //pic16_emitcode("inc","b");
-  //pic16_freeAsmop (right,NULL,ic,TRUE);
-  //pic16_aopOp(left,ic,FALSE);
-  //pic16_aopOp(result,ic,FALSE);
-
-  /* now move the left to the result if they are not the
-     same */
-  if (!pic16_sameRegs(AOP(left),AOP(result)) && 
-      AOP_SIZE(result) > 1) {
-
-    size = AOP_SIZE(result);
-    offset=0;
-    while (size--) { 
-      /*
-       l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
-       if (*l == '@' && IS_AOP_PREG(result)) {
-
-       pic16_emitcode("mov","a,%s",l);
-       pic16_aopPut(AOP(result),"a",offset);
-       } else
-       pic16_aopPut(AOP(result),l,offset);
-      */
-      pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),offset));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),offset));
-
-      offset++;
-    }
-  }
-
-  /* mov the highest order bit to OVR */    
-  tlbl = newiTempLabel(NULL);
-  tlbl1= newiTempLabel(NULL);
-
-  size = AOP_SIZE(result);
-  offset = size - 1;
-
-  pctemp = pic16_popGetTempReg(1);  /* grab a temporary working register. */
-
-  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
-  /* offset should be 0, 1 or 3 */
-  pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
-  emitSKPNZ;
-  pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl1->key));
-
-  pic16_emitpcode(POC_MOVWF, pctemp);
-
-
-  pic16_emitpLabel(tlbl->key);
-
-  pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(result),offset));
-  pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),offset));
-
-  while(--size) {
-    pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(result),--offset));
-  }
-
-  pic16_emitpcode(POC_DECFSZ,  pctemp);
-  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-  pic16_emitpLabel(tlbl1->key);
-
-  pic16_popReleaseTempReg(pctemp,1);
-#if 0
-  size = AOP_SIZE(result);
-  offset = size - 1;
-  pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-  pic16_emitcode("rlc","a");
-  pic16_emitcode("mov","ov,c");
-  /* if it is only one byte then */
-  if (size == 1) {
-    l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
-    MOVA(l);
-    pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
-    pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-    pic16_emitcode("mov","c,ov");
-    pic16_emitcode("rrc","a");
-    pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
-    pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-    pic16_aopPut(AOP(result),"a",0);
-    goto release ;
-  }
-
-  reAdjustPreg(AOP(result));
-  pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
-  pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
-  pic16_emitcode("mov","c,ov");
-  while (size--) {
-    l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
-    MOVA(l);
-    pic16_emitcode("rrc","a");         
-    pic16_aopPut(AOP(result),"a",offset--);
-  }
-  reAdjustPreg(AOP(result));
-  pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
-  pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-
- release:
-#endif
-
-  pic16_freeAsmop(left,NULL,ic,TRUE);
-  pic16_freeAsmop(result,NULL,ic,TRUE);
-  pic16_freeAsmop(right,NULL,ic,TRUE);
-}
+                 AOP_SIZE(left));
 #endif
 
-#if !(USE_GENERIC_SIGNED_SHIFT)
-#warning This implementation of genRightShift() is incomplete!
-/*-----------------------------------------------------------------*/
-/* genRightShift - generate code for right shifting                */
-/*-----------------------------------------------------------------*/
-static void genRightShift (iCode *ic)
-{
-    operand *right, *left, *result;
-    sym_link *letype ;
-    int size, offset;
-    char *l;
-    symbol *tlbl, *tlbl1 ;
-
-    /* if signed then we do it the hard way preserve the
-    sign bit moving it inwards */
-    letype = getSpec(operandType(IC_LEFT(ic)));
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    if (!SPEC_USIGN(letype)) {
-        genSignedRightShift (ic);
-        return ;
-    }
-
-    /* signed & unsigned types are treated the same : i.e. the
-    signed is NOT propagated inwards : quoting from the
-    ANSI - standard : "for E1 >> E2, is equivalent to division
-    by 2**E2 if unsigned or if it has a non-negative value,
-    otherwise the result is implementation defined ", MY definition
-    is that the sign does not get propagated */
-
-    right = IC_RIGHT(ic);
-    left  = IC_LEFT(ic);
-    result = IC_RESULT(ic);
-
-    pic16_aopOp(right,ic,FALSE);
-
-    /* if the shift count is known then do it 
-    as efficiently as possible */
-    if (AOP_TYPE(right) == AOP_LIT) {
-        genRightShiftLiteral (left,right,result,ic, 0);
-        return ;
-    }
-
-    /* shift count is unknown then we have to form 
-    a loop get the loop count in B : Note: we take
-    only the lower order byte since shifting
-    more that 32 bits make no sense anyway, ( the
-    largest size of an object can be only 32 bits ) */  
-
-    pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
-    pic16_emitcode("inc","b");
-    pic16_aopOp(left,ic,FALSE);
-    pic16_aopOp(result,ic,FALSE);
-
-    /* now move the left to the result if they are not the
-    same */
-    if (!pic16_sameRegs(AOP(left),AOP(result)) && 
-        AOP_SIZE(result) > 1) {
-
-        size = AOP_SIZE(result);
-        offset=0;
-        while (size--) {
-            l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
-            if (*l == '@' && IS_AOP_PREG(result)) {
-
-                pic16_emitcode("mov","a,%s",l);
-                pic16_aopPut(AOP(result),"a",offset);
-            } else
-                pic16_aopPut(AOP(result),l,offset);
-            offset++;
-        }
-    }
-
-    tlbl = newiTempLabel(NULL);
-    tlbl1= newiTempLabel(NULL);
-    size = AOP_SIZE(result);
-    offset = size - 1;
-
-    /* if it is only one byte then */
-    if (size == 1) {
+  lsize = pic16_getDataSize(left);
+  res_size = pic16_getDataSize(result);
+  /* test the LEFT size !!! */
 
-      tlbl = newiTempLabel(NULL);
-      if (!pic16_sameRegs(AOP(left),AOP(result))) {
-       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
-       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
+  /* I suppose that the left size >= result size */
+  if (shCount == 0) {
+    assert (res_size <= lsize);
+    while (res_size--) {
+      pic16_mov2f (AOP(result), AOP(left), res_size);
+    } // for
+  } else if (shCount >= (lsize * 8)) {
+    if (sign) {
+      /*
+       * Do NOT use
+       *    CLRF    result
+       *    BTFSC   left, 7
+       *    SETF    result
+       * even for 8-bit operands; result might be an SFR.
+       */
+      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
+      pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), lsize-1), 7));
+      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
+      while (res_size--) {
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), res_size));
+      }
+    } else { // unsigned
+      while (res_size--) {
+        pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), res_size));
       }
-
-      pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(right),0));
-      pic16_emitpcode(POC_RLCF,    pic16_popGet(AOP(result),0));
-      pic16_emitpLabel(tlbl->key);
-      pic16_emitpcode(POC_RRCF,    pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_ADDLW,  pic16_popGetLit(1));
-      emitSKPC;
-      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
-
-      goto release ;
     }
+  } else { // 0 < shCount < 8*lsize
+    switch (res_size) {
+    case 1:
+      genrshOne (result,left,shCount,sign);
+      break;
 
-    reAdjustPreg(AOP(result));
-    pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
-    pic16_emitcode("","%05d_DS_:",tlbl->key+100);    
-    CLRC;
-    while (size--) {
-        l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
-        MOVA(l);
-        pic16_emitcode("rrc","a");         
-        pic16_aopPut(AOP(result),"a",offset--);
-    }
-    reAdjustPreg(AOP(result));
+    case 2:
+      genrshTwo (result,left,shCount,sign);
+      break;
 
-    pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
-    pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
+    case 4:
+      genrshFour (result,left,shCount,sign);
+      break;
+    default :
+      break;
+    }
+  }
 
-release:
-    pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_freeAsmop (right,NULL,ic,TRUE);
-    pic16_freeAsmop(result,NULL,ic,TRUE);
+  pic16_freeAsmop(left,NULL,ic,TRUE);
+  pic16_freeAsmop(result,NULL,ic,TRUE);
 }
-#endif
 
-#if (USE_GENERIC_SIGNED_SHIFT)
 /*-----------------------------------------------------------------*/
 /* genGenericShift - generates code for left or right shifting     */
 /*-----------------------------------------------------------------*/
-static void genGenericShift (iCode *ic, int isShiftLeft) {
+static void genGenericShift (iCode *ic, int isShiftLeft)
+{
   operand *left,*right, *result;
   int offset;
   int sign, signedCount;
@@ -10717,15 +7748,15 @@ 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));
 
-  /* if the shift count is known then do it 
+  /* if the shift count is known then do it
      as efficiently as possible */
   if (AOP_TYPE(right) == AOP_LIT) {
-    long lit = (long)floatFromVal(AOP(right)->aopu.aop_lit);
+    long lit = (long) ulFromVal (AOP(right)->aopu.aop_lit);
     if (signedCount && lit < 0) { lit = -lit; isShiftLeft = !isShiftLeft; }
     // we should modify right->aopu.aop_lit here!
     // Instead we use abs(shCount) in genXXXShiftLiteral()...
@@ -10745,7 +7776,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) {
    * Note: we perform arithmetic shifts if the left operand is
    * signed and we do an (effective) right shift, i. e. we
    * shift in the sign bit from the left. */
-   
+
   label_complete = newiTempLabel ( NULL );
   label_loop_pos = newiTempLabel ( NULL );
   label_loop_neg = NULL;
@@ -10763,7 +7794,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)
@@ -10787,11 +7818,11 @@ static void genGenericShift (iCode *ic, int isShiftLeft) {
   pic16_mov2w (AOP(right), 0);
   pic16_emitpcode (POC_BZ, pic16_popGetLabel (label_complete->key));
   if (signedCount) pic16_emitpcode (POC_BN, pic16_popGetLabel (label_negative->key));
-  
+
 #if 0
   // perform a shift by one (shift count is positive)
   // cycles used for shifting {unsigned,signed} values on n bytes by [unsigned,signed] shift count c>0:
-  // 2n+[2,3]+({1,3}+n+3)c-2+[0,2]=({4,6}+n)c+2n+[0,3]         ({5,7}c+[2,5] / {6,8}c+[4, 7] / {8,10}c+[ 8,11])
+  // 2n+[2,3]+({1,3}+n+3)c-2+[0,2]=({4,6}+n)c+2n+[0,3]          ({5,7}c+[2,5] / {6,8}c+[4, 7] / {8,10}c+[ 8,11])
   pic16_emitpLabel (label_loop_pos->key);
   emitCLRC;
   if (sign && (pos_shift == POC_RRCF)) {
@@ -10804,7 +7835,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) {
 #else
   // perform a shift by one (shift count is positive)
   // cycles used for shifting {unsigned,signed} values on n bytes by [unsigned,signed] shift count c>0:
-  // 2n+[2,3]+2+({0,2}+n+3)c-1+[0,2]=({3,5}+n)c+2n+[3,6]       ({4,6}c+[5,8] / {5,7}c+[7,10] / {7, 9}c+[11,14])
+  // 2n+[2,3]+2+({0,2}+n+3)c-1+[0,2]=({3,5}+n)c+2n+[3,6]        ({4,6}c+[5,8] / {5,7}c+[7,10] / {7, 9}c+[11,14])
   // This variant is slower for 0<c<3, equally fast for c==3, and faster for 3<c.
   pic16_emitpcode (POC_NEGF, pic16_popCopyReg (&pic16_pc_wreg));
   emitCLRC;
@@ -10824,7 +7855,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) {
 
     pic16_emitpLabel (label_negative->key);
     // perform a shift by -1 (shift count is negative)
-    // 2n+4+1+({0,2}+n+3)*c-1=({3,5}+n)c+2n+4                  ({4,6}c+6 / {5,7}c+8 / {7,9}c+12)
+    // 2n+4+1+({0,2}+n+3)*c-1=({3,5}+n)c+2n+4                   ({4,6}c+6 / {5,7}c+8 / {7,9}c+12)
     emitCLRC;
     pic16_emitpLabel (label_loop_neg->key);
     if (sign && (neg_shift == POC_RRCF)) {
@@ -10852,236 +7883,270 @@ static void genLeftShift (iCode *ic) {
 static void genRightShift (iCode *ic) {
   genGenericShift (ic, 0);
 }
-#endif
 
 
-void pic16_loadFSR0(operand *op)
+/* load FSR0 with address of/from op according to pic16_isLitOp() or if lit is 1 */
+void pic16_loadFSR0(operand *op, int lit)
+{
+  if((IS_SYMOP(op) && OP_SYMBOL(op)->remat) || pic16_isLitOp( op )) {
+    if (AOP_TYPE(op) == AOP_LIT) {
+      /* handle 12 bit integers correctly */
+      unsigned int val = (unsigned int) ulFromVal (AOP(op)->aopu.aop_lit);
+      if ((val & 0x0fff) != val) {
+        fprintf (stderr, "WARNING: Accessing memory at 0x%x truncated to 0x%x.\n",
+                val, (val & 0x0fff) );
+        val &= 0x0fff;
+      }
+      pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetLit12(val)));
+    } else {
+      pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+    }
+  } else {
+    assert (!IS_SYMOP(op) || !OP_SYMBOL(op)->remat);
+    // set up FSR0 with address of result
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
+  }
+}
+
+/*----------------------------------------------------------------*/
+/* pic16_derefPtr - move one byte from the location ptr points to */
+/*                  to WREG (doWrite == 0) or one byte from WREG   */
+/*                  to the location ptr points to (doWrite != 0)   */
+/*----------------------------------------------------------------*/
+static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_setup)
 {
-       pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+  if (!IS_PTR(operandType(ptr)))
+  {
+    if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(ptr), 0));
+    else pic16_mov2w (AOP(ptr), 0);
+    return;
+  }
+
+  //assert (IS_DECL(operandType(ptr)) && (p_type == DCL_TYPE(operandType(ptr))));
+  /* We might determine pointer type right here: */
+  p_type = DCL_TYPE(operandType(ptr));
+
+  switch (p_type) {
+    case POINTER:
+    case FPOINTER:
+    case IPOINTER:
+    case PPOINTER:
+      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?)
+        mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(ptr), 0);
+        mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(ptr), 1);
+        pic16_mov2w(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;
+
+    case CPOINTER:
+      /* XXX: Writing to CPOINTERs not (yet) implemented. */
+      assert ( !doWrite && "Cannot write into __code space!" );
+      if( (AOP_TYPE(ptr) == AOP_PCODE)
+              && ((AOP(ptr)->aopu.pcop->type == PO_IMMEDIATE)
+                  || (AOP(ptr)->aopu.pcop->type == PO_DIR)))
+      {
+          pic16_emitpcode(POC_MOVLW, pic16_popGet     (AOP (ptr), 0));
+          pic16_emitpcode(POC_MOVWF, pic16_popCopyReg (&pic16_pc_tblptrl));
+          pic16_emitpcode(POC_MOVLW, pic16_popGet     (AOP (ptr), 1));
+          pic16_emitpcode(POC_MOVWF, pic16_popCopyReg (&pic16_pc_tblptrh));
+          pic16_emitpcode(POC_MOVLW, pic16_popGet     (AOP (ptr), 2));
+          pic16_emitpcode(POC_MOVWF, pic16_popCopyReg (&pic16_pc_tblptru));
+      } else {
+          mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(ptr), 0);
+          mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(ptr), 1);
+          mov2fp(pic16_popCopyReg(&pic16_pc_tblptru), AOP(ptr), 2);
+      } // if
+
+      pic16_emitpcodeNULLop (POC_TBLRD_POSTINC);
+      pic16_emitpcode (POC_MOVFW, pic16_popCopyReg (&pic16_pc_tablat));
+      break;
+
+    default:
+      assert (0 && "invalid pointer type specified");
+      break;
+  }
 }
 
 /*-----------------------------------------------------------------*/
 /* genUnpackBits - generates code for unpacking bits               */
 /*-----------------------------------------------------------------*/
 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
-{    
+{
   int shCnt ;
-  int rlen = 0 ;
   sym_link *etype, *letype;
   int blen=0, bstr=0;
   int lbstr;
-  int offset = 0 ;
+  int same;
+  pCodeOp *op;
 
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    etype = getSpec(operandType(result));
-    letype = getSpec(operandType(left));
-    
-//    if(IS_BITFIELD(etype)) {
-      blen = SPEC_BLEN(etype);
-      bstr = SPEC_BSTR(etype);
-//    }
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  etype = getSpec(operandType(result));
+  letype = getSpec(operandType(left));
 
-    lbstr = SPEC_BSTR( letype );
+  //    if(IS_BITFIELD(etype)) {
+  blen = SPEC_BLEN(etype);
+  bstr = SPEC_BSTR(etype);
+  //    }
 
-#if 1
-    if((blen == 1) && (bstr < 8)) {
-      /* it is a single bit, so use the appropriate bit instructions */
-      DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__);
+  lbstr = SPEC_BSTR( letype );
 
-      pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
-      
-      if((ptype == POINTER) && (result)) {
-        /* workaround to reduce the extra lfsr instruction */
-        pic16_emitpcode(POC_BTFSC,
-              pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
-      } else {
-        pic16_emitpcode(POC_BTFSC,
-              pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
-      }
-       
-      pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
+  DEBUGpic16_emitcode ("; ***","%s  %d - reading %s bitfield int %s destination",__FUNCTION__,__LINE__,
+      SPEC_USIGN(OP_SYM_ETYPE(left)) ? "an unsigned" : "a signed", SPEC_USIGN(OP_SYM_TYPE(result)) ? "an unsigned" : "a signed");
 
-      pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 ));      
-      return;
+#if 1
+  if((blen == 1) && (bstr < 8)
+      && (!IS_PTR(operandType(left)) || IS_DIRECT(left) || PIC_IS_DATA_PTR(operandType(left)))) {
+    /* it is a single bit, so use the appropriate bit instructions */
+    DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__);
+
+    same = pic16_sameRegs(AOP(left),AOP(result));
+    op = (same ? pic16_popCopyReg(&pic16_pc_wreg) : pic16_popGet (AOP(result),0));
+    pic16_emitpcode(POC_CLRF, op);
+
+    if(!IS_PTR(operandType(left)) || IS_DIRECT(left)) {
+      /* workaround to reduce the extra lfsr instruction */
+      pic16_emitpcode(POC_BTFSC,
+          pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
+    } else {
+      assert (PIC_IS_DATA_PTR (operandType(left)));
+      pic16_loadFSR0 (left, 0);
+      pic16_emitpcode(POC_BTFSC,
+          pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
+    }
+
+    if (SPEC_USIGN(OP_SYM_ETYPE(left))) {
+      /* unsigned bitfields result in either 0 or 1 */
+      pic16_emitpcode(POC_INCF, op);
+    } else {
+      /* signed bitfields result in either 0 or -1 */
+      pic16_emitpcode(POC_DECF, op);
     }
+    if (same) {
+      pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 ));
+    }
+
+    pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result)));
+    return;
+  }
 
 #endif
 
-        /* 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 we have bitdisplacement then it fits   */
-       /* into this byte completely or if length is */
-       /* less than a byte                          */
-       if ((shCnt = SPEC_BSTR(etype)) || 
-               (SPEC_BLEN(etype) <= 8))  {
-
-               /* shift right acc */
-               AccRsh(shCnt, 0);
-
-               pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
-                       (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
-
-/* VR -- normally I would use the following, but since we use the hack,
- * to avoid the masking from AccRsh, why not mask it right now? */
+  if (!IS_PTR(operandType(left)) || IS_DIRECT(left)) {
+    // 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 */
+  /* less than a byte                          */
+  if ((shCnt = SPEC_BSTR(etype)) || (SPEC_BLEN(etype) <= 8))  {
 
-/*
-               pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
-*/
+    /* shift right acc */
+    AccRsh(shCnt, 0);
+
+    pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
+          (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
 
-               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
-         return ;
-       }
-
-
-
-       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);
-
-    /* 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);          
-    }
-    
+    /* VR -- normally I would use the following, but since we use the hack,
+     * to avoid the masking from AccRsh, why not mask it right now? */
+
+    /*
+       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
+     */
+
+    /* extend signed bitfields to 8 bits */
+    if (!SPEC_USIGN(OP_SYM_ETYPE(left)) && (bstr + blen < 8))
+    {
+      assert (blen + bstr > 0);
+      pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr + blen - 1));
+      pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xFF << (bstr + blen)));
+    }
+
+    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+    pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result)));
     return ;
+  }
+
+  fprintf(stderr, "SDCC pic16 port error: the port currently does not support *reading*\n");
+  fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
+  exit(EXIT_FAILURE);
+
+  return ;
 }
 
 
-static void genDataPointerGet(operand *left,
-                             operand *result,
-                             iCode *ic)
+static void genDataPointerGet(operand *left, operand *result, iCode *ic)
 {
   int size, offset = 0, leoffset=0 ;
 
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       pic16_aopOp(result, ic, FALSE);
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        pic16_aopOp(result, ic, TRUE);
 
-       size = AOP_SIZE(result);
-//     fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
+        FENTRY;
 
+        size = AOP_SIZE(result);
+//      fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
 
-#if 0
-       /* The following tests may save a redudant movff instruction when
-        * accessing unions */
-        
-       /* if they are the same */
-       if (operandsEqu (left, result)) {
-               DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
-               goto release;
-       }
-#endif
-
-#if 0
-       /* if they are the same registers */
-       if (pic16_sameRegs(AOP(left),AOP(result))) {
-               DEBUGpic16_emitcode("; ***", "left and result registers are same");
-               goto release;
-       }
-#endif
 
 #if 1
-       if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
-               pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
-               DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
-               goto release;
-       }
+        if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
+                pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
+                DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
+                goto release;
+        }
 #endif
 
+        if(AOP(left)->aopu.pcop->type == PO_DIR)
+                leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
 
-#if 0
-       if ( AOP_TYPE(left) == AOP_PCODE) {
-               fprintf(stderr,"genDataPointerGet   %s, %d\n",
-                               AOP(left)->aopu.pcop->name,
-                               (AOP(left)->aopu.pcop->type == PO_DIR)?
-                               PCOR(AOP(left)->aopu.pcop)->instance:
-                               PCOI(AOP(left)->aopu.pcop)->offset);
-       }
-#endif
-
-       if(AOP(left)->aopu.pcop->type == PO_DIR)
-               leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
+        DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
 
-       DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
+        while (size--) {
+                DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
 
-       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_mov2w(AOP(left), offset); // patch 8
-                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
-               } else {
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                               pic16_popGet(AOP(left), offset), //patch 8
-                               pic16_popGet(AOP(result), offset)));
-               }
+//              pic16_DumpOp("(result)",result);
+                if(pic16_isLitAop(AOP(result))) {
+                        pic16_mov2w(AOP(left), offset); // patch 8
+                        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+                } else {
+                        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                pic16_popGet(AOP(left), offset), //patch 8
+                                pic16_popGet(AOP(result), offset)));
+                }
 
-               offset++;
-               leoffset++;
-       }
+                offset++;
+                leoffset++;
+        }
 
 release:
     pic16_freeAsmop(result,NULL,ic,TRUE);
@@ -11092,20 +8157,22 @@ release:
 /*-----------------------------------------------------------------*/
 /* genNearPointerGet - pic16_emitcode for near pointer fetch             */
 /*-----------------------------------------------------------------*/
-static void genNearPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
+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);
 
 //    pic16_DumpOp("(left)",left);
@@ -11115,7 +8182,7 @@ static void genNearPointerGet (operand *left,
      * result is not bit variable type and
      * the left is pointer to data space i.e
      * lower 128 bytes of space */
-    
+
     if (AOP_TYPE(left) == AOP_PCODE
       && !IS_BITFIELD(retype)
       && DCL_TYPE(ltype) == POINTER) {
@@ -11124,15 +8191,15 @@ static void genNearPointerGet (operand *left,
         pic16_freeAsmop(left, NULL, ic, TRUE);
         return ;
     }
-    
+
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    pic16_aopOp (result,ic,FALSE);
-    
+    pic16_aopOp (result,ic,TRUE);
+
     DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result);
 
 #if 1
     if(IS_BITFIELD( retype )
-      && (SPEC_BLEN(operandType(result))==1)
+      && (SPEC_BLEN(retype)==1)
     ) {
       iCode *nextic;
       pCodeOp *jop;
@@ -11152,17 +8219,18 @@ static void genNearPointerGet (operand *left,
         if((nextic->op == IFX)
           && (result == IC_COND(nextic))
           && (OP_LIVETO(result) == nextic->seq)
+          && (OP_SYMBOL(left)->remat)   // below fails for "if (p->bitfield)"
           ) {
             /* everything is ok then */
             /* find a way to optimize the genIfx iCode */
 
-            bytestrt = SPEC_BSTR(operandType(result))/8;
-            bitstrt = SPEC_BSTR(operandType(result))%8;
-            
+            bytestrt = SPEC_BSTR(retype)/8;
+            bitstrt = SPEC_BSTR(retype)%8;
+
             jop = pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bitstrt);
 
             genIfxpCOpJump(nextic, jop);
-            
+
             pic16_freeAsmop(left, NULL, ic, TRUE);
             pic16_freeAsmop(result, NULL, ic, TRUE);
             return;
@@ -11170,42 +8238,18 @@ static void genNearPointerGet (operand *left,
     }
 #endif
 
-
-    /* if the value is already in a pointer register
-     * then don't need anything more */
-    if (1 || !AOP_INPREG(AOP(left))) {  // AOP_INPREG(AOP(left)) is not always correct...
-      /* otherwise get a free pointer register */
-      DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               
-      /* VR -- the whole concept is to load FSR0 with the address of the symbol */
-      /* bitfields will be handled by genUnpackBits */
-      if(!IS_BITFIELD(retype)) {
-
-        if(is_LitAOp( AOP(left) )) {
-          pic16_loadFSR0( left );
-        } else {
-            // set up FSR0 with address from left
-            pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
-            pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
-        }
-      }
-    }
-
     /* if bitfield then unpack the bits */
-    if (IS_BITFIELD(retype)) 
+    if (IS_BITFIELD(letype))
       genUnpackBits (result, left, NULL, POINTER);
     else {
       /* we have can just get the values */
       int size = AOP_SIZE(result);
-      int offset = 0;  
-       
+      int offset = 0;
+
       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),
@@ -11215,306 +8259,36 @@ 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 */
       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
       pic16_freeAsmop(NULL,aop,ic,TRUE);
-    } else { 
+    } 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 
+       * we have to point it back to where it
        * belongs */
       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
       if (AOP_SIZE(result) > 1
-        && !OP_SYMBOL(left)->remat
-        && ( OP_SYMBOL(left)->liveTo > ic->seq
-            || ic->depth )) {
-//        int size = AOP_SIZE(result) - 1;
-//        while (size--)
-//          pic16_emitcode("dec","%s",rname);
-       }
-    }
-
-    /* done */
-    pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-
-/*-----------------------------------------------------------------*/
-/* genPagedPointerGet - pic16_emitcode for paged pointer fetch           */
-/*-----------------------------------------------------------------*/
-static void genPagedPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
-{
-    asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname ;
-    sym_link *rtype, *retype;    
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    rtype = operandType(result);
-    retype= getSpec(rtype);
-    
-    pic16_aopOp(left,ic,FALSE);
-
-  /* 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 */
-       aop = newAsmop(0);
-       preg = getFreePtr(ic,&aop,FALSE);
-       pic16_emitcode("mov","%s,%s",
-               preg->name,
-               pic16_aopGet(AOP(left),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
-    
-    pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_aopOp (result,ic,FALSE);
-
-    /* if bitfield then unpack the bits */
-    if (IS_BITFIELD(retype)) 
-       genUnpackBits (result,left,rname,PPOINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(result);
-       int offset = 0 ;        
-       
-       while (size--) {
-           
-           pic16_emitcode("movx","a,@%s",rname);
-           pic16_aopPut(AOP(result),"a",offset);
-           
-           offset++ ;
-           
-           if (size)
-               pic16_emitcode("inc","%s",rname);
-       }
-    }
-
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* 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 */
-       if (AOP_SIZE(result) > 1 &&
-           !OP_SYMBOL(left)->remat &&
-           ( OP_SYMBOL(left)->liveTo > ic->seq ||
-             ic->depth )) {
-           int size = AOP_SIZE(result) - 1;
-           while (size--)
-               pic16_emitcode("dec","%s",rname);
-       }
-    }
-
-    /* done */
-    pic16_freeAsmop(result,NULL,ic,TRUE);
-    
-       
-}
-
-/*-----------------------------------------------------------------*/
-/* genFarPointerGet - gget value from far space                    */
-/*-----------------------------------------------------------------*/
-static void genFarPointerGet (operand *left,
-                              operand *result, iCode *ic)
-{
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(result));
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    pic16_aopOp(left,ic,FALSE);
-
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(left) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(left) == AOP_IMMD)
-            pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
-            pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
-            }
-        }
-    }
-    /* so dptr know contains the address */
-    pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_aopOp(result,ic,FALSE);
-
-    /* if bit then unpack */
-    if (IS_BITFIELD(retype)) 
-        genUnpackBits(result,left,"dptr",FPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
-
-        while (size--) {
-            pic16_emitcode("movx","a,@dptr");
-            pic16_aopPut(AOP(result),"a",offset++);
-            if (size)
-                pic16_emitcode("inc","dptr");
-        }
-    }
-
-    pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* genCodePointerGet - get value from code space                  */
-/*-----------------------------------------------------------------*/
-static void genCodePointerGet (operand *left,
-                                operand *result, iCode *ic)
-{
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(result));
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    pic16_aopOp(left,ic,FALSE);
-
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(left) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(left) == AOP_IMMD)
-            pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
-            pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
-            }
-        }
-    }
-    /* so dptr know contains the address */
-    pic16_freeAsmop(left,NULL,ic,TRUE);
-    pic16_aopOp(result,ic,FALSE);
-
-    /* if bit then unpack */
-    if (IS_BITFIELD(retype)) 
-        genUnpackBits(result,left,"dptr",CPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
-
-        while (size--) {
-            pic16_emitcode("clr","a");
-            pic16_emitcode("movc","a,@a+dptr");
-            pic16_aopPut(AOP(result),"a",offset++);
-            if (size)
-                pic16_emitcode("inc","dptr");
+        && !OP_SYMBOL(left)->remat
+        && ( OP_SYMBOL(left)->liveTo > ic->seq
+            || ic->depth )) {
+//        int size = AOP_SIZE(result) - 1;
+//        while (size--)
+//          pic16_emitcode("dec","%s",rname);
         }
     }
-
-    pic16_freeAsmop(result,NULL,ic,TRUE);
-}
 #endif
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* genGenPointerGet - gget value from generic pointer space        */
-/*-----------------------------------------------------------------*/
-static void genGenPointerGet (operand *left,
-                              operand *result, iCode *ic)
-{
-  int size, offset, lit;
-  sym_link *retype = getSpec(operandType(result));
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       pic16_aopOp(left,ic,FALSE);
-       pic16_aopOp(result,ic,FALSE);
-       size = AOP_SIZE(result);
-
-       DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
-
-       if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
-
-               lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
-               // load FSR0 from immediate
-               pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
-
-//             pic16_loadFSR0( left );
-
-               offset = 0;
-               while(size--) {
-                       if(size) {
-                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
-                       } else {
-                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
-                       }
-                       offset++;
-               }
-               goto release;
-
-       }
-       else { /* we need to get it byte by byte */
-               // 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--) {
-                       if(size) {
-                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
-                       } else {
-                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
-                       }
-                       offset++;
-               }
-               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);
-
+    /* done */
+    pic16_freeAsmop(left,NULL,ic,TRUE);
+    pic16_freeAsmop(result,NULL,ic,TRUE);
 }
-#endif
-
 
 /*-----------------------------------------------------------------*/
 /* genGenPointerGet - gget value from generic pointer space        */
@@ -11522,74 +8296,29 @@ static void genGenPointerGet (operand *left,
 static void genGenPointerGet (operand *left,
                               operand *result, iCode *ic)
 {
-  int size, offset, lit;
-  sym_link *retype = getSpec(operandType(result));
-  char fgptrget[32];
-
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    pic16_aopOp(left,ic,FALSE);
-    pic16_aopOp(result,ic,FALSE);
-    size = AOP_SIZE(result);
-
-    DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
-
-    if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
-
-      lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
-      // load FSR0 from immediate
-      pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
-
-      werror(W_POSSBUG2, __FILE__, __LINE__);
-
-      offset = 0;
-      while(size--) {
-        if(size) {
-         pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
-       } else {
-          pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
-        }
-        offset++;
-      }
+  int size;
+  sym_link *letype = getSpec(operandType(left));
 
-      goto release;
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  pic16_aopOp(left,ic,FALSE);
+  pic16_aopOp(result,ic,TRUE);
+  size = AOP_SIZE(result);
 
-    } else { /* we need to get it byte by byte */
-
-      /* set up WREG:PRODL:FSR0L 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_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 ));
-      
-      assignResultValue(result, 1);
-      
-      {
-        symbol *sym;
+  DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
 
-          sym = newSymbol( fgptrget, 0 );
-          strcpy(sym->rname, fgptrget);
-          checkAddSym(&externs, sym);
+  /* if bit then unpack */
+  if (IS_BITFIELD(letype)) {
+    genUnpackBits(result,left,"BAD",GPOINTER);
+    goto release;
+  }
 
-//          fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
-      }
-              
-      goto release;
-    }
+  /* set up WREG:PRODL:FSR0L with address from left */
+  mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(left), 0);
+  mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(left), 1);
+  pic16_mov2w(AOP(left), 2);
+  pic16_callGenericPointerRW(0, size);
 
-  /* if bit then unpack */
-    if (IS_BITFIELD(retype)) 
-      genUnpackBits(result,left,"BAD",GPOINTER);
+  assignResultValue(result, size, 1);
 
 release:
   pic16_freeAsmop(left,NULL,ic,TRUE);
@@ -11600,12 +8329,12 @@ release:
 /* genConstPointerGet - get value from const generic pointer space */
 /*-----------------------------------------------------------------*/
 static void genConstPointerGet (operand *left,
-                               operand *result, iCode *ic)
+                                operand *result, iCode *ic)
 {
   //sym_link *retype = getSpec(operandType(result));
-  // symbol *albl = newiTempLabel(NULL);       // patch 15
-  // symbol *blbl = newiTempLabel(NULL);       //
-  // PIC_OPCODE poc;                           // patch 15
+  // symbol *albl = newiTempLabel(NULL);        // patch 15
+  // symbol *blbl = newiTempLabel(NULL);        //
+  // PIC_OPCODE poc;                            // patch 15
   int size;
   int offset = 0;
 
@@ -11614,12 +8343,18 @@ static void genConstPointerGet (operand *left,
   pic16_aopOp(result,ic,TRUE);
   size = AOP_SIZE(result);
 
+  /* if bit then unpack */
+  if (IS_BITFIELD(getSpec (operandType (left)))) {
+    genUnpackBits(result,left,"BAD",GPOINTER);
+    goto release;
+  } // if
+
   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
 
   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
 
   // set up table pointer
-  if( (AOP_TYPE(left) == AOP_PCODE) 
+  if( (AOP_TYPE(left) == AOP_PCODE)
       && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
           || (AOP(left)->aopu.pcop->type == PO_DIR)))
     {
@@ -11630,9 +8365,9 @@ static void genConstPointerGet (operand *left,
       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)));
+    mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(left), 0);
+    mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(left), 1);
+    mov2fp(pic16_popCopyReg(&pic16_pc_tblptru), AOP(left), 2);
   }
 
   while(size--) {
@@ -11640,7 +8375,8 @@ static void genConstPointerGet (operand *left,
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
     offset++;
   }
-    
+
+release:
   pic16_freeAsmop(left,NULL,ic,TRUE);
   pic16_freeAsmop(result,NULL,ic,TRUE);
 }
@@ -11656,7 +8392,7 @@ static void genPointerGet (iCode *ic)
   int p_type;
 
     FENTRY;
-    
+
     left = IC_LEFT(ic);
     result = IC_RESULT(ic) ;
 
@@ -11673,7 +8409,7 @@ static void genPointerGet (iCode *ic)
       DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
 
     /* if left is of type of pointer then it is simple */
-    if (IS_PTR(type) && !IS_FUNC(type->next)) 
+    if (IS_PTR(type) && !IS_FUNC(type->next))
       p_type = DCL_TYPE(type);
     else {
       /* we have to go by the storage class */
@@ -11683,11 +8419,11 @@ static void genPointerGet (iCode *ic)
 
       if (SPEC_OCLS(etype)->codesp ) {
         DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
-        //p_type = CPOINTER ;  
+        //p_type = CPOINTER ;
       } else
       if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) {
         DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
-        /*p_type = FPOINTER ;*/ 
+        /*p_type = FPOINTER ;*/
       } else
       if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) {
         DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
@@ -11705,37 +8441,31 @@ static void genPointerGet (iCode *ic)
     /* now that we have the pointer type we assign
     the pointer values */
     switch (p_type) {
-      case POINTER:    
+      case POINTER:
+      case FPOINTER:
       case IPOINTER:
-       genNearPointerGet (left,result,ic);
-       break;
-
       case PPOINTER:
-       genPagedPointerGet(left,result,ic);
-       break;
-
-      case FPOINTER:
-       genFarPointerGet (left,result,ic);
-       break;
+        genNearPointerGet (left,result,ic);
+        break;
 
       case CPOINTER:
-       genConstPointerGet (left,result,ic);
-       //pic16_emitcodePointerGet (left,result,ic);
-       break;
+        genConstPointerGet (left,result,ic);
+        //pic16_emitcodePointerGet (left,result,ic);
+        break;
 
       case GPOINTER:
 #if 0
       if (IS_PTR_CONST(type))
-       genConstPointerGet (left,result,ic);
+        genConstPointerGet (left,result,ic);
       else
 #endif
-       genGenPointerGet (left,result,ic);
+        genGenPointerGet (left,result,ic);
       break;
 
     default:
-      werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
-             "genPointerGet: illegal pointer type");
-    
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+              "genPointerGet: illegal pointer type");
+
     }
 }
 
@@ -11749,338 +8479,289 @@ static void genPackBits (sym_link    *etype , operand *result,
   int shCnt = 0 ;
   int offset = 0  ;
   int rLen = 0 ;
-  int blen, bstr ;   
+  int blen, bstr ;
+  int shifted_and_masked = 0;
+  unsigned long lit = (unsigned long)-1;
   sym_link *retype;
-  char *l ;
 
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       blen = SPEC_BLEN(etype);
-       bstr = SPEC_BSTR(etype);
-
-       retype = getSpec(operandType(right));
-
-       if(AOP_TYPE(right) == AOP_LIT) {
-               if((blen == 1) && (bstr < 8)) {
-                 unsigned long lit;
-                       /* it is a single bit, so use the appropriate bit instructions */
-
-                       DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
-
-                       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-//                     pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-                       if((p_type == POINTER) && (result)) {
-                               /* workaround to reduce the extra lfsr instruction */
-                               if(lit) {
-                                       pic16_emitpcode(POC_BSF,
-                                               pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
-                               } else {
-                                       pic16_emitpcode(POC_BCF,
-                                               pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
-                               }
-                       } else {
-                                pic16_loadFSR0( result );
-                               if(lit) {
-                                       pic16_emitpcode(POC_BSF,
-                                               pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
-                               } else {
-                                       pic16_emitpcode(POC_BCF,
-                                               pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
-                               }
-                       }
-       
-                 return;
-               }
-
-               pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
-               offset++;
-       } else
-       if(IS_BITFIELD(retype) 
-         && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR)
-         && (blen == 1)) {
-         int rblen, rbstr;
-
-           rblen = SPEC_BLEN( retype );
-           rbstr = SPEC_BSTR( retype );
-           
-
-            if(IS_BITFIELD(etype)) {
-              pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0));
-              pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
-            } else {
-              pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
-            }
-            
-           pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr));
-           
-           if(IS_BITFIELD(etype)) {
-             pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
-            } else {
-              pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
-            }
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  blen = SPEC_BLEN(etype);
+  bstr = SPEC_BSTR(etype);
 
-            pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0));
-            
-            return;
-        } else
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
-
-       /* if the bit length is less than or   */
-       /* it exactly fits a byte then         */
-       if((shCnt=SPEC_BSTR(etype))
-               || SPEC_BLEN(etype) <= 8 )  {
-               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));
-
-                 /* shift left acc */
-                 AccLsh(shCnt);
-
-                 /* using PRODH as a temporary register here */
-                 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
-
-                 /* get old value */
-                 switch (p_type) {
-                       case FPOINTER:
-                       case POINTER:
-                               pic16_loadFSR0( result );
-                               fsr0_setup = 1;
-                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-//                             pic16_emitcode ("mov","b,a");
-//                             pic16_emitcode("mov","a,@%s",rname);
-                               break;
-
-                       case GPOINTER:
-                               if (AOP(result)->aopu.aop_reg[2]) {
-                                 // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?)
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl)));
-                                 pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2));
-                                 pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrget1"));
-                                 {
-                                   symbol *sym;
-                                   sym = newSymbol( "__gptrget1", 0 );
-                                   strcpy(sym->rname, "__gptrget1");
-                                   checkAddSym(&externs, sym);
-                                 }
-                               } else {
-                                 // data pointer (just 2 byte given)
-                                 pic16_loadFSR0( result );
-                                 fsr0_setup = 1;
-                                 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-                               }
-                               
-                               // warnings will be emitted below
-                               //pic16_emitpcomment ("; =?= genPackBits, GPOINTER...");
-                                //werror(W_POSSBUG2, __FILE__, __LINE__);
-                               break;
-
-                       default:
-                               assert (0 && "invalid pointer type specified");
-                               break;
-                 }
-#if 1
-                 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_prodh));
-               } // if (blen != 8 || bstr != 0)
-
-               /* write new value back */
-               switch (p_type) {
-                       case FPOINTER:
-                       case POINTER:
-                               if (!fsr0_setup) pic16_loadFSR0( result );
-                               pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
-                               break;
-
-                       case GPOINTER:
-                               if (AOP(result)->aopu.aop_reg[2]) {
-                                 // prepare call to __gptrset1, this is actually genGenPointerSet(WREG, result, ?ic?)
-                                 pic16_emitpcode (POC_MOVWF, pic16_popCopyReg (pic16_stack_postdec/*pic16_pc_postdec1*/));
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
-                                 pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl)));
-                                 pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2));
-                                 pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrput1"));
-                                 {
-                                   symbol *sym;
-                                   sym = newSymbol( "__gptrput1", 0 );
-                                   strcpy(sym->rname, "__gptrput1");
-                                   checkAddSym(&externs, sym);
-                                 }
-                               } else {
-                                 // data pointer (just 2 byte given)
-                                 if (!fsr0_setup) pic16_loadFSR0( result );
-                                 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
-                               }
-                               
-                               // this should work in all cases (as soon as gptrget/gptrput work on EEPROM and PROGRAM MEMORY)
-                               //pic16_emitpcomment ("; =?= genPackBits, GPOINTER access");
-                                werror(W_POSSBUG2, __FILE__, __LINE__);
-                               break;
-
-                       default:
-                               assert (0 && "invalid pointer type specified");
-                               break;
-               }
-#endif
+  retype = getSpec(operandType(right));
+
+  if(AOP_TYPE(right) == AOP_LIT) {
+    lit = ulFromVal (AOP(right)->aopu.aop_lit);
 
-         return;
-       }
+    if((blen == 1) && (bstr < 8)) {
+      /* it is a single bit, so use the appropriate bit instructions */
 
+      DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
 
-       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);
+      if(!IS_PTR(operandType(result)) || IS_DIRECT(result)) {
+        /* workaround to reduce the extra lfsr instruction */
+        if(lit) {
+          pic16_emitpcode(POC_BSF,
+              pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
+        } else {
+          pic16_emitpcode(POC_BCF,
+              pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
+        }
+      } else {
+        if (PIC_IS_DATA_PTR(operandType(result))) {
+          pic16_loadFSR0(result, 0);
+          pic16_emitpcode(lit ? POC_BSF : POC_BCF,
+              pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
+        } else {
+          /* get old value */
+          pic16_derefPtr (result, p_type, 0, NULL);
+          pic16_emitpcode(lit ? POC_BSF : POC_BCF,
+              pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
+          /* write back new value */
+          pic16_derefPtr (result, p_type, 1, NULL);
+        }
+      }
 
+      return;
+    }
+    /* IORLW below is more efficient */
+    //pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & ((1UL << blen) - 1)) << bstr));
+    lit = (lit & ((1UL << blen) - 1)) << bstr;
+    shifted_and_masked = 1;
+    offset++;
+  } else
+    if (IS_DIRECT(result) && !IS_PTR(operandType(result))
+        && IS_BITFIELD(retype)
+        && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR)
+        && (blen == 1)) {
+      int rblen, rbstr;
+
+      rblen = SPEC_BLEN( retype );
+      rbstr = SPEC_BSTR( retype );
+
+      if(IS_BITFIELD(etype)) {
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0));
+        pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
+      } else {
+        pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+      }
 
-    /* if we r done */
-    if ( SPEC_BLEN(etype) <= 8 )
-        return ;
+      pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr));
 
-    pic16_emitcode("inc","%s",rname);
-    rLen = SPEC_BLEN(etype) ;     
+      if(IS_BITFIELD(etype)) {
+        pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
+      } else {
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
+      }
 
+      pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0));
 
+      return;
+    } else {
+      /* move right to W */
+      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
+    }
 
-    /* now generate for lengths greater than one byte */
-    while (1) {
+  /* if the bit length is less than or   */
+  /* it exactly fits a byte then         */
+  if((shCnt=SPEC_BSTR(etype))
+      || SPEC_BLEN(etype) <= 8 )  {
+    int fsr0_setup = 0;
 
-        l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
+    if (blen != 8 || (bstr % 8) != 0) {
+      // we need to combine the value with the old value
+      if(!shifted_and_masked)
+      {
+        pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
 
-        rLen -= 8 ;
-        if (rLen <= 0 )
-            break ;
+        DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt,
+            SPEC_BSTR(etype), SPEC_BLEN(etype));
 
-        switch (p_type) {
-            case POINTER:
-                if (*l == '@') {
-                    MOVA(l);
-                    pic16_emitcode("mov","@%s,a",rname);
-                } else
-                    pic16_emitcode("mov","@%s,%s",rname,l);
-                break;
+        /* shift left acc, do NOT mask the result again */
+        AccLsh(shCnt, 0);
 
-            case FPOINTER:
-                MOVA(l);
-                pic16_emitcode("movx","@dptr,a");
-                break;
+        /* using PRODH as a temporary register here */
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
+      }
 
-            case GPOINTER:
-                MOVA(l);
-                DEBUGpic16_emitcode(";lcall","__gptrput");
-                break;  
-        }   
-        pic16_emitcode ("inc","%s",rname);
+      if ((IS_SYMOP(result) && !IS_PTR(operandType (result)))
+        || IS_DIRECT(result)) {
+        /* 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(
+            (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
+                            (unsigned char)(0xff >> (8-bstr))) ));
+      if (!shifted_and_masked) {
+        pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh));
+      } else {
+        /* We have the shifted and masked (literal) right value in `lit' */
+        if (lit != 0)
+          pic16_emitpcode(POC_IORLW, pic16_popGetLit(lit));
+      }
+    } else { // if (blen == 8 && (bstr % 8) == 0)
+        if (shifted_and_masked) {
+            // move right (literal) to WREG (only case where right is not yet in WREG)
+            pic16_mov2w(AOP(right), (bstr / 8));
+        }
     }
 
-    MOVA(l);
+    /* write new value back */
+    if ((IS_SYMOP(result) && !IS_PTR(operandType(result)))
+        || IS_DIRECT(result)) {
+      pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0));
+    } else {
+      pic16_derefPtr (result, p_type, 1, &fsr0_setup);
+    }
+#endif
 
-    /* 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);
-                break;
+    return;
+  }
 
-            case FPOINTER:
-                pic16_emitcode ("mov","b,a");
-                pic16_emitcode("movx","a,@dptr");
-                break;
 
-            case GPOINTER:
-                pic16_emitcode ("push","b");
-                pic16_emitcode ("push","acc");
-                pic16_emitcode ("lcall","__gptrget");
-                pic16_emitcode ("pop","b");
-                break;
-        }
+#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(EXIT_FAILURE);
+#endif
+
+
+  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) {
+    rLen -= 8 ;
+    if (rLen <= 0 ) {
+      mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), offset);
+      break ;
+    }
+
+    switch (p_type) {
+      case POINTER:
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
+        break;
+
+        /*
+           case FPOINTER:
+           MOVA(l);
+           pic16_emitcode("movx","@dptr,a");
+           break;
 
-        pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
-        pic16_emitcode ("orl","a,b");
+           case GPOINTER:
+           MOVA(l);
+           DEBUGpic16_emitcode(";lcall","__gptrput");
+           break;
+         */
+      default:
+        assert(0);
     }
 
-    if (p_type == GPOINTER)
-        pic16_emitcode("pop","b");
 
+    pic16_mov2w(AOP(right), offset++);
+  }
+
+  /* last last was not complete */
+  if (rLen)   {
+    /* save the byte & read byte */
     switch (p_type) {
+      case POINTER:
+        //                pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
+        pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
+        break;
 
-    case POINTER:
-       pic16_emitcode("mov","@%s,a",rname);
-       break;
-       
-    case FPOINTER:
-       pic16_emitcode("movx","@dptr,a");
-       break;
-       
-    case GPOINTER:
-       DEBUGpic16_emitcode(";lcall","__gptrput");
-       break;                  
+        /*
+           case FPOINTER:
+           pic16_emitcode ("mov","b,a");
+           pic16_emitcode("movx","a,@dptr");
+           break;
+
+           case GPOINTER:
+           pic16_emitcode ("push","b");
+           pic16_emitcode ("push","acc");
+           pic16_emitcode ("lcall","__gptrget");
+           pic16_emitcode ("pop","b");
+           break;
+         */
+      default:
+        assert(0);
     }
+    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");
+
+  switch (p_type) {
+
+    case POINTER:
+      pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+      //        pic16_emitcode("mov","@%s,a",rname);
+      break;
+      /*
+         case FPOINTER:
+         pic16_emitcode("movx","@dptr,a");
+         break;
+
+         case GPOINTER:
+         DEBUGpic16_emitcode(";lcall","__gptrput");
+         break;
+       */
+    default:
+      assert(0);
+  }
+
+  //    pic16_freeAsmop(right, NULL, ic, TRUE);
 }
+
 /*-----------------------------------------------------------------*/
 /* genDataPointerSet - remat pointer to data space                 */
 /*-----------------------------------------------------------------*/
 static void genDataPointerSet(operand *right,
-                             operand *result,
-                             iCode *ic)
+                              operand *result,
+                              iCode *ic)
 {
-    int size, offset = 0, resoffset=0 ;
+  int size, offset = 0, resoffset=0 ;
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     pic16_aopOp(right,ic,FALSE);
 
     size = AOP_SIZE(right);
 
-//     fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
+//      fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
 
 #if 0
     if ( AOP_TYPE(result) == AOP_PCODE) {
       fprintf(stderr,"genDataPointerSet   %s, %d\n",
-             AOP(result)->aopu.pcop->name,
-               (AOP(result)->aopu.pcop->type == PO_DIR)?
-             PCOR(AOP(result)->aopu.pcop)->instance:
-             PCOI(AOP(result)->aopu.pcop)->offset);
+              AOP(result)->aopu.pcop->name,
+                (AOP(result)->aopu.pcop->type == PO_DIR)?
+              PCOR(AOP(result)->aopu.pcop)->instance:
+              PCOI(AOP(result)->aopu.pcop)->offset);
     }
 #endif
 
-       if(AOP(result)->aopu.pcop->type == PO_DIR)
-               resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
-
-       while (size--) {
-               if (AOP_TYPE(right) == AOP_LIT) {
-                 unsigned int lit;
-
-                   if(!IS_FLOAT(operandType( right )))
-                     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->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(IC_RIGHT(ic))->aopu.aop_lit);
-                        lit = info.lit_int;
-                    }
+    if(AOP(result)->aopu.pcop->type == PO_DIR)
+      resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
 
-                    lit = lit >> (8*offset);
-                    if(lit&0xff) {
-                      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
-                      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
-                    } else {
-                      pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
-                    }
-                } else {
-                  pic16_mov2w(AOP(right), offset);
-                  pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
-                }
-               offset++;
-               resoffset++;
-       }
+    while (size--) {
+      if (AOP_TYPE(right) == AOP_LIT) {
+        unsigned int lit = pic16aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset);
+        pic16_movLit2f(pic16_popGet(AOP(result), offset), lit);
+      } else {
+        pic16_mov2w(AOP(right), offset);
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); // patch 8
+      }
+      offset++;
+      resoffset++;
+    }
 
     pic16_freeAsmop(right,NULL,ic,TRUE);
 }
@@ -12091,405 +8772,113 @@ static void genDataPointerSet(operand *right,
 /* genNearPointerSet - pic16_emitcode for near pointer put         */
 /*-----------------------------------------------------------------*/
 static void genNearPointerSet (operand *right,
-                               operand *result, 
+                               operand *result,
                                iCode *ic)
 {
   asmop *aop = NULL;
-  char *l;
   sym_link *retype;
   sym_link *ptype = operandType(result);
   sym_link *resetype;
-    
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       retype= getSpec(operandType(right));
-       resetype = getSpec(operandType(result));
-  
-       pic16_aopOp(result,ic,FALSE);
-    
-       /* if the result is rematerializable &
-        * in data space & not a bit variable */
-       
-       /* and result is not a bit variable */
-       if (AOP_TYPE(result) == AOP_PCODE
-//             && AOP_TYPE(result) == AOP_IMMD
-               && DCL_TYPE(ptype) == POINTER
-               && !IS_BITFIELD(retype)
-               && !IS_BITFIELD(resetype)) {
-
-               genDataPointerSet (right,result,ic);
-               pic16_freeAsmop(result,NULL,ic,TRUE);
-         return;
-       }
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       pic16_aopOp(right,ic,FALSE);
-       DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
-
-       /* if the value is already in a pointer register
-        * then don't need anything more */
-       if (1 || !AOP_INPREG(AOP(result))) {  // AOP_INPREG(AOP(result)) is not always correct...
-               /* otherwise get a free pointer register */
-               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-//             if( (AOP_TYPE(result) == AOP_PCODE) 
-//                     && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
-//                             || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
-                if(is_LitAOp( AOP(result) ))
-               {
-                 if(!IS_BITFIELD(resetype))
-                       pic16_loadFSR0( result );  // patch 10
-               } else {
-                 if(!IS_BITFIELD(resetype)) {
-                       // set up FSR0 with address of result
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
-                  }
-               }
-
-       }
-//     else
-//     rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-//     pic16_loadFSR0( result );
-
-       /* if bitfield then unpack the bits */
-       if (IS_BITFIELD(resetype)) {
-               genPackBits (resetype, result, right, NULL, POINTER);
-       } else {
-               /* we have can just get the values */
-         int size = AOP_SIZE(right);
-         int offset = 0 ;    
-
-               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               while (size--) {
-                       l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
-                       if (*l == '@' ) {
-                               //MOVA(l);
-                               //pic16_emitcode("mov","@%s,a",rname);
-                               pic16_emitcode("movf","indf0,w ;1");
-                       } else {
-
-                               if (AOP_TYPE(right) == AOP_LIT) {
-                                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
-                                       if (size) {
-                                               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);
-       } 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);
-               }
-       }
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       /* done */
-//release:
-       pic16_freeAsmop(right,NULL,ic,TRUE);
-       pic16_freeAsmop(result,NULL,ic,TRUE);
-}
 
-/*-----------------------------------------------------------------*/
-/* genPagedPointerSet - pic16_emitcode for Paged pointer put             */
-/*-----------------------------------------------------------------*/
-static void genPagedPointerSet (operand *right,
-                              operand *result, 
-                              iCode *ic)
-{
-    asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname , *l;
-    sym_link *retype;
-       
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
     retype= getSpec(operandType(right));
-    
+    resetype = getSpec(operandType(result));
+
     pic16_aopOp(result,ic,FALSE);
-    
-    /* 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 */
-       aop = newAsmop(0);
-       preg = getFreePtr(ic,&aop,FALSE);
-       pic16_emitcode("mov","%s,%s",
-               preg->name,
-               pic16_aopGet(AOP(result),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
-    
-    pic16_freeAsmop(result,NULL,ic,TRUE);
-    pic16_aopOp (right,ic,FALSE);
 
-    /* if bitfield then unpack the bits */
-    if (IS_BITFIELD(retype)) 
-       genPackBits (retype,result,right,rname,PPOINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(right);
-       int offset = 0 ;        
-       
-       while (size--) {
-           l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
-           
-           MOVA(l);
-           pic16_emitcode("movx","@%s,a",rname);
-
-           if (size)
-               pic16_emitcode("inc","%s",rname);
-
-           offset++;
-       }
-    }
-    
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* 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 */
-       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("dec","%s",rname);
-       }
-    }
+    /* if the result is rematerializable &
+     * in data space & not a bit variable */
 
-    /* done */
-    pic16_freeAsmop(right,NULL,ic,TRUE);
-    
-       
-}
+    /* and result is not a bit variable */
+    if (AOP_TYPE(result) == AOP_PCODE
+      && DCL_TYPE(ptype) == POINTER
+      && !IS_BITFIELD(retype)
+      && !IS_BITFIELD(resetype)) {
 
-/*-----------------------------------------------------------------*/
-/* genFarPointerSet - set value from far space                     */
-/*-----------------------------------------------------------------*/
-static void genFarPointerSet (operand *right,
-                              operand *result, iCode *ic)
-{
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(right));
+        genDataPointerSet (right,result,ic);
+        pic16_freeAsmop(result,NULL,ic,TRUE);
+      return;
+    }
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    pic16_aopOp(result,ic,FALSE);
+    pic16_aopOp(right,ic,FALSE);
+    DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(result) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(result) == AOP_IMMD)
-            pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
-            pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
+    /* if bitfield then unpack the bits */
+    if (IS_BITFIELD(resetype)) {
+      genPackBits (resetype, result, right, NULL, POINTER);
+    } else {
+      /* we have can just get the values */
+      int size = AOP_SIZE(right);
+      int offset = 0 ;
+
+        pic16_loadFSR0(result, 0);
+
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        while (size--) {
+          if (pic16_isLitOp(right)) {
+            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++;
         }
     }
-    /* so dptr know contains the address */
-    pic16_freeAsmop(result,NULL,ic,TRUE);
-    pic16_aopOp(right,ic,FALSE);
 
-    /* if bit then unpack */
-    if (IS_BITFIELD(retype)) 
-        genPackBits(retype,result,right,"dptr",FPOINTER);
-    else {
-        size = AOP_SIZE(right);
-        offset = 0 ;
+    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);
+    } 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 )) {
 
-        while (size--) {
-            char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
-            MOVA(l);
-            pic16_emitcode("movx","@dptr,a");
-            if (size)
-                pic16_emitcode("inc","dptr");
-        }
+          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 */
+//release:
     pic16_freeAsmop(right,NULL,ic,TRUE);
+    pic16_freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genGenPointerSet - set value from generic pointer space         */
 /*-----------------------------------------------------------------*/
-#if 0
-static void genGenPointerSet (operand *right,
-                              operand *result, iCode *ic)
-{
-       int i, size, offset, lit;
-       sym_link *retype = getSpec(operandType(right));
-
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-       pic16_aopOp(result,ic,FALSE);
-       pic16_aopOp(right,ic,FALSE);
-       size = AOP_SIZE(right);
-       offset = 0;
-
-       DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
-
-       /* if the operand is already in dptr 
-               then we do nothing else we move the value to dptr */
-       if (AOP_TYPE(result) != AOP_STR) {
-               /* if this is remateriazable */
-               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               // WARNING: anythig until "else" is untested!
-               if (AOP_TYPE(result) == AOP_IMMD) {
-                       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-                       lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
-                       // load FSR0 from immediate
-                       pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
-                       offset = 0;
-                       while(size--) {
-                               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++;
-                       }
-                       goto release;
-               }
-               else { /* we need to get it byte by byte */
-                       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-                       //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
-
-                       // set up FSR0 with address of result
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
-                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
-
-                       /* hack hack! see if this the FSR. If so don't load W */
-                       if(AOP_TYPE(right) != AOP_ACC) {
-
-                               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-                               if(AOP_TYPE(right) == AOP_LIT)
-                               {
-                                       // copy literal
-                                       // note: pic16_popGet handles sign extension
-                                       for(i=0;i<size;i++) {
-                                               pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
-                                               if(i < size-1)
-                                                       pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
-                                               else
-                                                       pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
-                                       }
-                               } else {
-                                       // copy regs
-
-                                       for(i=0;i<size;i++) {
-                                               if(i < size-1)
-                                                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
-                                                                       pic16_popCopyReg(&pic16_pc_postinc0)));
-                                               else
-                                                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
-                                                                       pic16_popCopyReg(&pic16_pc_indf0)));
-                                       }
-                               }
-                               goto release;
-                       } 
-                       // right = ACC
-                       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-                       pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
-                       goto release;
-       } // if (AOP_TYPE(result) != AOP_IMMD)
-
-       } // if (AOP_TYPE(result) != AOP_STR)
-       /* so dptr know contains the address */
-
-
-       /* if bit then unpack */
-       if (IS_BITFIELD(retype)) 
-               genPackBits(retype,result,right,"dptr",GPOINTER);
-       else {
-               size = AOP_SIZE(right);
-               offset = 0 ;
-
-               DEBUGpic16_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
-
-               // set up FSR0 with address of result
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
-       
-               while (size--) {
-                       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++;
-               }
-       }
-
-       release:
-       pic16_freeAsmop(right,NULL,ic,TRUE);
-       pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-#endif
-
 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__);
 
@@ -12512,11 +8901,10 @@ 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
-     * by the support function this restoring the stack. The important
+     * by the support function thus restoring the stack. The important
      * thing is that there is no need to manually restore stack pointer
      * here */
     pushaop(AOP(right), 0);
@@ -12524,35 +8912,15 @@ static void genGenPointerSet (operand *right,
     if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
     if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
     if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
-    
+
     /* load address to write to in WREG:FSR0H:FSR0L */
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0),
                                 pic16_popCopyReg(&pic16_pc_fsr0l)));
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1),
                                 pic16_popCopyReg(&pic16_pc_prodl)));
     pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
-    
-
-    /* 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);
@@ -12563,7 +8931,7 @@ release:
 /* genPointerSet - stores the value into a pointer location        */
 /*-----------------------------------------------------------------*/
 static void genPointerSet (iCode *ic)
-{    
+{
   operand *right, *result ;
   sym_link *type, *etype;
   int p_type;
@@ -12577,52 +8945,47 @@ 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);
     }
     else {
-       /* we have to go by the storage class */
-       p_type = PTR_TYPE(SPEC_OCLS(etype));
-
-/*     if (SPEC_OCLS(etype)->codesp ) { */
-/*         p_type = CPOINTER ;  */
-/*     } */
-/*     else */
-/*         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/*             p_type = FPOINTER ; */
-/*         else */
-/*             if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/*                 p_type = PPOINTER ; */
-/*             else */
-/*                 if (SPEC_OCLS(etype) == idata ) */
-/*                     p_type = IPOINTER ; */
-/*                 else */
-/*                     p_type = POINTER ; */
+        /* we have to go by the storage class */
+        p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+/*      if (SPEC_OCLS(etype)->codesp ) { */
+/*          p_type = CPOINTER ;  */
+/*      } */
+/*      else */
+/*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/*              p_type = FPOINTER ; */
+/*          else */
+/*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/*                  p_type = PPOINTER ; */
+/*              else */
+/*                  if (SPEC_OCLS(etype) == idata ) */
+/*                      p_type = IPOINTER ; */
+/*                  else */
+/*                      p_type = POINTER ; */
     }
 
     /* now that we have the pointer type we assign
     the pointer values */
     switch (p_type) {
       case POINTER:
+      case FPOINTER:
       case IPOINTER:
+      case PPOINTER:
         genNearPointerSet (right,result,ic);
         break;
 
-      case PPOINTER:
-        genPagedPointerSet (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__, 
+        werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
           "genPointerSet: illegal pointer type");
     }
 }
@@ -12652,7 +9015,7 @@ static void genIfx (iCode *ic, iCode *popIc)
       genIpop(popIc);
 
     /* if the condition is  a bit variable */
-    if (isbit && IS_ITEMP(cond) && 
+    if (isbit && IS_ITEMP(cond) &&
         SPIL_LOC(cond)) {
       genIfxJump(ic,"c");
       DEBUGpic16_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
@@ -12672,7 +9035,7 @@ static void genAddrOf (iCode *ic)
 {
   operand *result, *left;
   int size;
-  symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
+  symbol *sym;  // = OP_SYMBOL(IC_LEFT(ic));
   pCodeOp *pcop0, *pcop1, *pcop2;
 
     FENTRY;
@@ -12680,48 +9043,50 @@ static void genAddrOf (iCode *ic)
     pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
     sym = OP_SYMBOL( IC_LEFT(ic) );
-    
+
     if(sym->onStack) {
       /* 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
       // starting at 2 for arguments and growing from 0 downwards for
       // local variables (index == 0 is not assigned so we add one here)
       {
-       int soffs = OP_SYMBOL( IC_LEFT(ic))->stack;
-       if (soffs <= 0) {
-         assert (soffs < 0);
-         soffs++;
-       } // 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_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_framepnt_hi));
-       pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1));
+        int soffs = OP_SYMBOL( IC_LEFT(ic))->stack;
+
+          if (soffs <= 0) {
+            assert (soffs < 0);
+            soffs++;
+          } // 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_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_framepnt_hi));
+          pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1));
       }
 
       goto release;
     }
-       
-//     if(pic16_debug_verbose) {
-//             fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
-//                     __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
-//     }
-       
+
+//      if(pic16_debug_verbose) {
+//              fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
+//                      __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
+//      }
+
     pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
     size = AOP_SIZE(IC_RESULT(ic));
 
     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))));
-       
+
     if (size == 3) {
       pic16_emitpcode(POC_MOVLW, pcop0);
       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
@@ -12746,248 +9111,264 @@ release:
 }
 
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* genFarFarAssign - assignment when both are in far space         */
-/*-----------------------------------------------------------------*/
-static void genFarFarAssign (operand *result, operand *right, iCode *ic)
-{
-    int size = AOP_SIZE(right);
-    int offset = 0;
-    char *l ;
-    /* first push the right side on to the stack */
-    while (size--) {
-       l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
-       MOVA(l);
-       pic16_emitcode ("push","acc");
-    }
-    
-    pic16_freeAsmop(right,NULL,ic,FALSE);
-    /* now assign DPTR to result */
-    pic16_aopOp(result,ic,FALSE);
-    size = AOP_SIZE(result);
-    while (size--) {
-       pic16_emitcode ("pop","acc");
-       pic16_aopPut(AOP(result),"a",--offset);
-    }
-    pic16_freeAsmop(result,NULL,ic,FALSE);
-       
-}
-#endif
-
 /*-----------------------------------------------------------------*/
 /* genAssign - generate code for assignment                        */
 /*-----------------------------------------------------------------*/
 static void genAssign (iCode *ic)
 {
   operand *result, *right;
+  sym_link *restype, *rtype;
   int size, offset,know_W;
   unsigned long lit = 0L;
 
-  result = IC_RESULT(ic);
-  right  = IC_RIGHT(ic) ;
+    result = IC_RESULT(ic);
+    right  = IC_RIGHT(ic) ;
 
-  FENTRY;
-  
-  /* if they are the same */
-  if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
-    return ;
+    FENTRY;
 
-  /* reversed order operands are aopOp'ed so that result operand
-   * is effective in case right is a stack symbol. This maneauver
-   * allows to use the _G.resDirect flag later */
-  pic16_aopOp(result,ic,TRUE);
-  pic16_aopOp(right,ic,FALSE);
+    /* if they are the same */
+    if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
+      return ;
 
-  DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
+    /* reversed order operands are aopOp'ed so that result operand
+     * is effective in case right is a stack symbol. This maneauver
+     * allows to use the _G.resDirect flag later */
+     pic16_aopOp(result,ic,TRUE);
+    pic16_aopOp(right,ic,FALSE);
 
-  /* if they are the same registers */
-  if (pic16_sameRegs(AOP(right),AOP(result)))
-    goto release;
+    DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
-  /* if the result is a bit */
-  if (AOP_TYPE(result) == AOP_CRY) {
-    /* if the right size is a literal then
-       we know what the value is */
-    if (AOP_TYPE(right) == AOP_LIT) {
-         
-      pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
-                 pic16_popGet(AOP(result),0));
-
-      if (((int) operandLitValue(right))) 
-       pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
-                      AOP(result)->aopu.aop_dir,
-                      AOP(result)->aopu.aop_dir);
-      else
-       pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
-                      AOP(result)->aopu.aop_dir,
-                      AOP(result)->aopu.aop_dir);
+    /* if they are the same registers */
+    if (pic16_sameRegs(AOP(right),AOP(result)))
       goto release;
-    }
 
-    /* the right is also a bit variable */
-    if (AOP_TYPE(right) == AOP_CRY) {
+    /* if the result is a bit */
+    if (AOP_TYPE(result) == AOP_CRY) {
+      /* if the right size is a literal then
+         we know what the value is */
+      if (AOP_TYPE(right) == AOP_LIT) {
+
+        pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+            pic16_popGet(AOP(result),0));
+
+        if (((int) operandLitValue(right)))
+          pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
+              AOP(result)->aopu.aop_dir,
+              AOP(result)->aopu.aop_dir);
+        else
+          pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
+              AOP(result)->aopu.aop_dir,
+              AOP(result)->aopu.aop_dir);
+
+        goto release;
+      }
+
+      /* the right is also a bit variable */
+      if (AOP_TYPE(right) == AOP_CRY) {
+        pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
+        pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+        pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
+
+        goto release ;
+      }
+
+      /* we need to or */
       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+      pic16_toBoolean(right);
+      emitSKPZ;
       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
-
-      pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
-                    AOP(result)->aopu.aop_dir,
-                    AOP(result)->aopu.aop_dir);
-      pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
-                    AOP(right)->aopu.aop_dir,
-                    AOP(right)->aopu.aop_dir);
-      pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
-                    AOP(result)->aopu.aop_dir,
-                    AOP(result)->aopu.aop_dir);
+      //pic16_aopPut(AOP(result),"a",0);
       goto release ;
     }
 
-    /* we need to or */
-    pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
-    pic16_toBoolean(right);
-    emitSKPZ;
-    pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
-    //pic16_aopPut(AOP(result),"a",0);
-    goto release ;
-  }
+    /* bit variables done */
+    /* general case */
+    size = AOP_SIZE(result);
+    offset = 0 ;
 
   /* bit variables done */
   /* general case */
   size = AOP_SIZE(result);
+  restype = operandType(result);
+  rtype = operandType(right);
   offset = 0 ;
 
   if(AOP_TYPE(right) == AOP_LIT) {
-       if(!IS_FLOAT(operandType( right )))
-               lit = (unsigned long)floatFromVal(AOP(right)->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(right)->aopu.aop_lit);
-               lit = info.lit_int;
-       }
+    if(!(IS_FLOAT(operandType( right )) || IS_FIXED(operandType(right))))
+    {
+      lit = ulFromVal (AOP(right)->aopu.aop_lit);
+
+      /* patch tag for literals that are cast to pointers */
+      if (IS_CODEPTR(restype)) {
+        //fprintf (stderr, "%s:%u: INFO: `(__code*)literal'\n", ic->filename, ic->lineno);
+        lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
+      } else {
+        if (IS_GENPTR(restype))
+        {
+          if (IS_CODEPTR(rtype)) {
+            //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __code*)'\n", ic->filename, ic->lineno);
+            lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
+          } else if (PIC_IS_DATA_PTR(rtype)) {
+            //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __data*)'\n", ic->filename, ic->lineno);
+            lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
+          } else if (!IS_PTR(rtype) || IS_GENPTR(rtype)) {
+            //fprintf (stderr, "%s:%u: INFO: `(generic*)literal' -- accepting specified tag %02x\n", ic->filename, ic->lineno, (unsigned char)(lit >> 16));
+          } else if (IS_PTR(rtype)) {
+            fprintf (stderr, "%s:%u: WARNING: `(generic*)literal' -- assuming __data space\n", ic->filename, ic->lineno);
+            lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
+          }
+        }
+      }
+    } else {
+      union {
+        unsigned long lit_int;
+        float lit_float;
+      } info;
+
+
+      if(IS_FIXED16X16(operandType(right))) {
+        lit = (unsigned long)fixed16x16FromDouble( floatFromVal( AOP(right)->aopu.aop_lit));
+      } else {
+        /* take care if literal is a float */
+        info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
+        lit = info.lit_int;
+      }
+    }
   }
 
 //  fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
-//                     sizeof(unsigned long int), sizeof(float));
+//                      sizeof(unsigned long int), sizeof(float));
 
 
-  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;
-  }
+    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;
+    }
 
-  if(AOP_TYPE(right) != AOP_LIT
-       && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
-       && !IS_FUNC(OP_SYM_TYPE(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);
-
-       // set up table pointer
-       if(is_LitOp(right)) {
-//             fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
-               pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
-               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
-               pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
-               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
-               pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
-               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
-       } else {
-//             fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
-                               pic16_popCopyReg(&pic16_pc_tblptrl)));
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
-                               pic16_popCopyReg(&pic16_pc_tblptrh)));
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
-                               pic16_popCopyReg(&pic16_pc_tblptru)));
-       }
-
-       size = min(getSize(OP_SYM_ETYPE(right)), AOP_SIZE(result));
-       while(size--) {
-               pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
-                       pic16_popGet(AOP(result),offset)));
-               offset++;
-       }
-
-       size = getSize(OP_SYM_ETYPE(right));
-       if(AOP_SIZE(result) > size) {
-               size = AOP_SIZE(result) - size;
-               while(size--) {
-                       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
-                       offset++;
-               }
-       }
-       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_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);
+
+      // set up table pointer
+      if(pic16_isLitOp(right)) {
+//      fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
+        pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
+        pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
+        pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
+        pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
+        pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
+        pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
+      } else {
+//      fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
+        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
+            pic16_popCopyReg(&pic16_pc_tblptrl)));
+        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
+            pic16_popCopyReg(&pic16_pc_tblptrh)));
+        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
+            pic16_popCopyReg(&pic16_pc_tblptru)));
+      }
 
+      /* 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),
+            pic16_popGet(AOP(result),offset)));
+        offset++;
+      }
 
+      /* 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++;
+        }
+      }
+      goto release;
+    }
 
 #if 0
-/* VR - What is this?! */
-  if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(aopIdx(AOP(result),0) == 4) {
-
-      /* this is a workaround to save value of right into wreg too,
-       * value of wreg is going to be used later */
+    /* VR - What is this?! */
+    if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-      goto release;
-    } else
-//     assert(0);
+
+      if(aopIdx(AOP(result),0) == 4) {
+        /* this is a workaround to save value of right into wreg too,
+         * value of wreg is going to be used later */
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+        goto release;
+      } else
+//      assert(0);
       DEBUGpic16_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
-  }
+    }
 #endif
 
-  know_W=-1;
-  while (size--) {
-  DEBUGpic16_emitcode ("; ***","%s  %d size %d",__FUNCTION__,__LINE__, size);
-    if(AOP_TYPE(right) == AOP_LIT) {
-      if(lit&0xff) {
-       if(know_W != (lit&0xff))
-         pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
-       know_W = lit&0xff;
-       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-      } else
-       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+    size = AOP_SIZE(right);
+    if (size > AOP_SIZE(result)) size = AOP_SIZE(result);
+    know_W=-1;
+    while (size--) {
+      DEBUGpic16_emitcode ("; ***","%s  %d size %d",__FUNCTION__,__LINE__, size);
+      if(AOP_TYPE(right) == AOP_LIT) {
+        if(lit&0xff) {
+          if(know_W != (lit&0xff))
+            pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
+          know_W = lit&0xff;
+          pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+        } else
+          pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+
+        lit >>= 8;
 
-      lit >>= 8;
+      } else if (AOP_TYPE(right) == AOP_CRY) {
+        pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+        if(offset == 0) {
+          //debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
+          pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+          pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+        }
+      } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
+        pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
+        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+      } else {
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    } else if (AOP_TYPE(right) == AOP_CRY) {
-      pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
-      if(offset == 0) {
-        //debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
-       pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+        if(!_G.resDirect) {                                             /* use this aopForSym feature */
+          if(AOP_TYPE(result) == AOP_ACC) {
+            pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset));
+          } else
+            if(AOP_TYPE(right) == AOP_ACC) {
+              pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+            } else {
+              pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+            }
+        }
       }
-    } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
-       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
-       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-    } else {
-      DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-      if(!_G.resDirect)                /* use this aopForSym feature */
-        pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+      offset++;
     }
-           
-    offset++;
-  }
-  
- release:
-  pic16_freeAsmop (right,NULL,ic,FALSE);
+    pic16_addSign(result, AOP_SIZE(right), !IS_UNSIGNED(operandType(right)));
+
+release:
   pic16_freeAsmop (result,NULL,ic,TRUE);
-}   
+  pic16_freeAsmop (right,NULL,ic,FALSE);
+}
 
 /*-----------------------------------------------------------------*/
 /* genJumpTab - generates code for jump table                       */
@@ -13062,17 +9443,18 @@ 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 */
     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
          jtab = setNextItem(IC_JTLABELS(ic))) {
 //        pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
-       pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
-       
+        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
+
     }
     pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_END, ""));
 
@@ -13083,10 +9465,10 @@ static void genJumpTab (iCode *ic)
 /*-----------------------------------------------------------------*/
 /*
   TSD - Written for the PIC port - but this unfortunately is buggy.
-  This routine is good in that it is able to efficiently promote 
+  This routine is good in that it is able to efficiently promote
   types to different (larger) sizes. Unfortunately, the temporary
   variables that are optimized out by this routine are sometimes
-  used in other places. So until I know how to really parse the 
+  used in other places. So until I know how to really parse the
   iCode tree, I'm going to not be using this routine :(.
 */
 static int genMixedOperation (iCode *ic)
@@ -13122,7 +9504,7 @@ static int genMixedOperation (iCode *ic)
 
     operand *t = right;
     right = nextright;
-    nextright = t; 
+    nextright = t;
 
     pic16_emitcode(";remove right +","");
 
@@ -13130,7 +9512,7 @@ static int genMixedOperation (iCode *ic)
 /*
     operand *t = right;
     right = nextleft;
-    nextleft = t; 
+    nextleft = t;
 */
     pic16_emitcode(";remove left +","");
   } else
@@ -13151,45 +9533,45 @@ static int genMixedOperation (iCode *ic)
       pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
 
       if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
-       pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
-       pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
+        pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
+        pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
       } else
-       pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
+        pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
 
       offset = 0;
       while(--big) {
 
-       offset++;
+        offset++;
 
-       if(--small) {
-         if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
-           pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-           pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
-         }
+        if(--small) {
+          if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
+            pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+            pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+          }
 
-         pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-         emitSKPNC;
-         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                  AOP(IC_RIGHT(nextic))->aopu.aop_dir,
-                  AOP(IC_RIGHT(nextic))->aopu.aop_dir);
-         pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-         pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
+          pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+          emitSKPNC;
+          pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+                   AOP(IC_RIGHT(nextic))->aopu.aop_dir,
+                   AOP(IC_RIGHT(nextic))->aopu.aop_dir);
+          pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+          pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
 
-       } else {
-         pic16_emitcode("rlf","known_zero,w");
+        } else {
+          pic16_emitcode("rlf","known_zero,w");
 
-         /*
-           if right is signed
-             btfsc  right,7
+          /*
+            if right is signed
+              btfsc  right,7
                addlw ff
-         */
-         if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
-           pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-           pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
-         } else {
-           pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
-         }
-       }
+          */
+          if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
+            pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+            pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+          } else {
+            pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+          }
+        }
       }
       ret = 1;
     }
@@ -13224,269 +9606,299 @@ static void genCast (iCode *ic)
 
     FENTRY;
 
-       /* if they are equivalent then do nothing */
-//     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
-//             return ;
+        /* if they are equivalent then do nothing */
+//      if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
+//              return ;
+
+        pic16_aopOp(result,ic,FALSE);
+        pic16_aopOp(right,ic,FALSE) ;
 
-       pic16_aopOp(right,ic,FALSE) ;
-       pic16_aopOp(result,ic,FALSE);
+        DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
-       DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
+        /* if the result is a bit */
+        if (AOP_TYPE(result) == AOP_CRY) {
 
-       /* if the result is a bit */
-       if (AOP_TYPE(result) == AOP_CRY) {
-       
-               /* if the right size is a literal then
-                * we know what the value is */
-               DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+                /* if the right size is a literal then
+                 * we know what the value is */
+                DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-               if (AOP_TYPE(right) == AOP_LIT) {
-                       pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
-                               pic16_popGet(AOP(result),0));
+                if (AOP_TYPE(right) == AOP_LIT) {
+                        pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+                                pic16_popGet(AOP(result),0));
 
-                       if (((int) operandLitValue(right))) 
-                               pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
-                                       AOP(result)->aopu.aop_dir,
-                                       AOP(result)->aopu.aop_dir);
-                       else
-                               pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
-                                       AOP(result)->aopu.aop_dir,
-                                       AOP(result)->aopu.aop_dir);
-                       goto release;
-               }
+                        if (((int) operandLitValue(right)))
+                                pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+                                        AOP(result)->aopu.aop_dir,
+                                        AOP(result)->aopu.aop_dir);
+                        else
+                                pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
+                                        AOP(result)->aopu.aop_dir,
+                                        AOP(result)->aopu.aop_dir);
+                        goto release;
+                }
+
+                /* the right is also a bit variable */
+                if (AOP_TYPE(right) == AOP_CRY) {
+                        emitCLRC;
+                        pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+
+                        pic16_emitcode("clrc","");
+                        pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+                                AOP(right)->aopu.aop_dir,
+                                AOP(right)->aopu.aop_dir);
+                        pic16_aopPut(AOP(result),"c",0);
+                        goto release ;
+                }
 
-               /* the right is also a bit variable */
-               if (AOP_TYPE(right) == AOP_CRY) {
-                       emitCLRC;
-                       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+                /* we need to or */
+                if (AOP_TYPE(right) == AOP_REG) {
+                        pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
+                        pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
+                        pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
+                }
+                pic16_toBoolean(right);
+                pic16_aopPut(AOP(result),"a",0);
+                goto release ;
+        }
 
-                       pic16_emitcode("clrc","");
-                       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                               AOP(right)->aopu.aop_dir,
-                               AOP(right)->aopu.aop_dir);
-                       pic16_aopPut(AOP(result),"c",0);
-                       goto release ;
-               }
+        if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
+          int offset = 1;
 
-               /* we need to or */
-               if (AOP_TYPE(right) == AOP_REG) {
-                       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
-                       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
-                       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
-               }
-               pic16_toBoolean(right);
-               pic16_aopPut(AOP(result),"a",0);
-               goto release ;
-       }
+                size = AOP_SIZE(result);
 
-       if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
-         int offset = 1;
+                DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-               size = AOP_SIZE(result);
+                pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
+                pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+                pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
 
-               DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+                while (size--)
+                        pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
 
-               pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
-               pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
-               pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
+                goto release;
+        }
 
-               while (size--)
-                       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
+        if(IS_BITFIELD(getSpec(restype))
+          && IS_BITFIELD(getSpec(rtype))) {
+          DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__);
+        }
 
-               goto release;
-       }
+        /* port from pic14 to cope with generic pointers */
+        if (PIC_IS_TAGGED(restype))
+        {
+          operand *result = IC_RESULT(ic);
+          //operand *left = IC_LEFT(ic);
+          operand *right = IC_RIGHT(ic);
+          int tag = 0xff;
+
+          /* copy common part */
+          int max, size = AOP_SIZE(result);
+          if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
+          DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+          max = size;
+          while (size--)
+          {
+            pic16_mov2w (AOP(right), size);
+            pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size));
+          } // while
+
+          /* upcast into generic pointer type? */
+          if (IS_GENPTR(restype)
+              && !PIC_IS_TAGGED(rtype)
+              && (AOP_SIZE(result) > max))
+          {
+            /* determine appropriate tag for right */
+            if (PIC_IS_DATA_PTR(rtype))
+              tag = GPTR_TAG_DATA;
+            else if (IS_CODEPTR(rtype))
+              tag = GPTR_TAG_CODE;
+            else if (PIC_IS_DATA_PTR(ctype)) {
+              //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__data*)(non-pointer)'\n", ic->filename, ic->lineno);
+              tag = GPTR_TAG_DATA;
+            } else if (IS_CODEPTR(ctype)) {
+              //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__code*)(non-pointer)'\n", ic->filename, ic->lineno);
+              tag = GPTR_TAG_CODE;
+            } else if (IS_PTR(rtype)) {
+              PERFORM_ONCE(weirdcast,
+              fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(unknown*)' -- assuming __data space\n", ic->filename, ic->lineno);
+              );
+              tag = GPTR_TAG_DATA;
+            } else {
+              PERFORM_ONCE(weirdcast,
+              fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(non-pointer)' -- assuming __data space\n", ic->filename, ic->lineno);
+              );
+              tag = GPTR_TAG_DATA;
+            }
 
-       if(IS_BITFIELD(getSpec(restype))
-         && IS_BITFIELD(getSpec(rtype))) {
-         DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__);
+            assert (AOP_SIZE(result) == 3);
+            /* zero-extend address... */
+            for (size = max; size < AOP_SIZE(result)-1; size++)
+              pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
+            /* ...and add tag */
+            pic16_movLit2f(pic16_popGet(AOP(result), AOP_SIZE(result)-1), tag);
+          } else if (IS_CODEPTR(restype) && AOP_SIZE(result) > max) {
+            //fprintf (stderr, "%s:%u: INFO: code pointer\n", ic->filename, ic->lineno);
+            for (size = max; size < AOP_SIZE(result)-1; size++)
+              pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), size));
+            /* add __code tag */
+            pic16_movLit2f (pic16_popGet(AOP(result), AOP_SIZE(result)-1), GPTR_TAG_CODE);
+          } else if (AOP_SIZE(result) > max) {
+            /* extend non-pointers */
+            //fprintf (stderr, "%s:%u: zero-extending value cast to pointer\n", ic->filename, ic->lineno);
+            pic16_addSign(result, max, 0);
+          } // if
+          goto release;
         }
 
-       /* if they are the same size : or less */
-       if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+        /* if they are the same size : or less */
+        if (AOP_SIZE(result) <= AOP_SIZE(right)) {
 
-               /* if they are in the same place */
-               if (pic16_sameRegs(AOP(right),AOP(result)))
-                       goto release;
+                /* if they are in the same place */
+                if (pic16_sameRegs(AOP(right),AOP(result)))
+                        goto release;
 
-               DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+                DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
 #if 0
-               if (IS_PTR_CONST(rtype))
+                if (IS_PTR_CONST(rtype))
 #else
-               if (IS_CODEPTR(rtype))
+                if (IS_CODEPTR(rtype))
 #endif
-                       DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
+                        DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
 
 #if 0
-               if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+                if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
 #else
-               if (IS_CODEPTR(operandType(IC_RESULT(ic))))
+                if (IS_CODEPTR(operandType(IC_RESULT(ic))))
 #endif
-                       DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
+                        DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
+
+                if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+                        pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
+                        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+
+                        if(AOP_SIZE(result) < 2) {
+                          fprintf(stderr,"%d -- casting a ptr to a char\n",__LINE__);
+                        } else {
+                          pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
+                          pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+                        }
+                } else {
+                        /* if they in different places then copy */
+                        size = AOP_SIZE(result);
+                        offset = 0 ;
+                        while (size--) {
+                                pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+                                offset++;
+                        }
+                }
+                goto release;
+        }
 
-#if 0
-               if(AOP_TYPE(right) == AOP_IMMD) {
-                 pCodeOp *pcop0, *pcop1, *pcop2;
-                 symbol *sym = OP_SYMBOL( right );
-
-                       size = AOP_SIZE(result);
-                       /* low */
-                       pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
-                       /* high */
-                       pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
-                       /* upper */
-                       pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
-       
-                       if (size == 3) {
-                               pic16_emitpcode(POC_MOVLW, pcop0);
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
-                               pic16_emitpcode(POC_MOVLW, pcop1);
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
-                               pic16_emitpcode(POC_MOVLW, pcop2);
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
-                       } else
-                       if (size == 2) {
-                               pic16_emitpcode(POC_MOVLW, pcop0);
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-                               pic16_emitpcode(POC_MOVLW, pcop1);
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
-                       } else {
-                               pic16_emitpcode(POC_MOVLW, pcop0);
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-                       }
-               } else
-#endif
-               if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
-                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
-                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
-                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
-                       if(AOP_SIZE(result) <2)
-                               fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
-               } else {
-                       /* if they in different places then copy */
-                       size = AOP_SIZE(result);
-                       offset = 0 ;
-                       while (size--) {
-                               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-                               offset++;
-                       }
-               }
-               goto release;
-       }
-
-       /* if the result is of type pointer */
-       if (IS_PTR(ctype)) {
-         int p_type;
-         sym_link *type = operandType(right);
-         sym_link *etype = getSpec(type);
-
-               DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
-
-               /* pointer to generic pointer */
-               if (IS_GENPTR(ctype)) {
-                 char *l = zero;
-           
-                       if (IS_PTR(type)) 
-                               p_type = DCL_TYPE(type);
-                       else {
-               /* we have to go by the storage class */
-               p_type = PTR_TYPE(SPEC_OCLS(etype));
-
-/*             if (SPEC_OCLS(etype)->codesp )  */
-/*                 p_type = CPOINTER ;  */
-/*             else */
-/*                 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/*                     p_type = FPOINTER ; */
-/*                 else */
-/*                     if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/*                         p_type = PPOINTER; */
-/*                     else */
-/*                         if (SPEC_OCLS(etype) == idata ) */
-/*                             p_type = IPOINTER ; */
-/*                         else */
-/*                             p_type = POINTER ; */
-           }
-               
-           /* the first two bytes are known */
+        /* if the result is of type pointer */
+        if (IS_PTR(ctype)) {
+          int p_type;
+          sym_link *type = operandType(right);
+          sym_link *etype = getSpec(type);
+
+                DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
+
+                /* pointer to generic pointer */
+                if (IS_GENPTR(ctype)) {
+
+                        if (IS_PTR(type))
+                                p_type = DCL_TYPE(type);
+                        else {
+                /* we have to go by the storage class */
+                p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+/*              if (SPEC_OCLS(etype)->codesp )  */
+/*                  p_type = CPOINTER ;  */
+/*              else */
+/*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/*                      p_type = FPOINTER ; */
+/*                  else */
+/*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/*                          p_type = PPOINTER; */
+/*                      else */
+/*                          if (SPEC_OCLS(etype) == idata ) */
+/*                              p_type = IPOINTER ; */
+/*                          else */
+/*                              p_type = POINTER ; */
+            }
+
+            /* the first two bytes are known */
       DEBUGpic16_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
-           size = GPTRSIZE - 1; 
-           offset = 0 ;
-           while (size--) {
-             if(offset < AOP_SIZE(right)) {
+            size = GPTRSIZE - 1;
+            offset = 0 ;
+            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) {
-                 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
-                 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-               } else { 
-                 
-                 pic16_aopPut(AOP(result),
-                        pic16_aopGet(AOP(right),offset,FALSE,FALSE),
-                        offset);
-               }
+                if ((AOP_TYPE(right) == AOP_PCODE) &&
+                    AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+                  pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
+                  pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+                } else {
+
+                  pic16_aopPut(AOP(result),
+                         pic16_aopGet(AOP(right),offset,FALSE,FALSE),
+                         offset);
+                }
 */
-             } else 
-               pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
-             offset++;
-           }
-           /* the last byte depending on type */
-           switch (p_type) {
-           case IPOINTER:
-           case POINTER:
-               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
-//             pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
-               break;
-
-           case CPOINTER:
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
-               break;
-
-           case FPOINTER:
-             pic16_emitcode(";BUG!? ","%d",__LINE__);
-               l = one;
-               break;
-           case PPOINTER:
-             pic16_emitcode(";BUG!? ","%d",__LINE__);
-               l = "#0x03";
-               break;
+              } else
+                pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
+              offset++;
+            }
+            /* the last byte depending on type */
+            switch (p_type) {
+            case POINTER:
+            case FPOINTER:
+            case IPOINTER:
+            case PPOINTER:
+                pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
+                break;
+
+            case CPOINTER:
+                pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
+                break;
 
             case GPOINTER:
-               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));
-               }
+                if (GPTRSIZE > AOP_SIZE(right)) {
+                  // assume __data pointer... THIS MIGHT BE WRONG!
+                  pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
+                } else {
+                  pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
+                }
               break;
-              
-           default:
-               /* this should never happen */
-               werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                      "got unknown pointer type");
-               exit(1);
-           }
-           //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);            
-           goto release ;
-       }
-       
-       /* just copy the pointers */
-       size = AOP_SIZE(result);
-       offset = 0 ;
-       while (size--) {
-           pic16_aopPut(AOP(result),
-                  pic16_aopGet(AOP(right),offset,FALSE,FALSE),
-                  offset);
-           offset++;
-       }
-       goto release ;
-    }
-    
+
+            default:
+                /* this should never happen */
+                werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+                       "got unknown pointer type");
+                exit(1);
+            }
+            //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
+            goto release ;
+        }
+
+
+        assert( 0 );
+        /* just copy the pointers */
+        size = AOP_SIZE(result);
+        offset = 0 ;
+        while (size--) {
+            pic16_aopPut(AOP(result),
+                   pic16_aopGet(AOP(right),offset,FALSE,FALSE),
+                   offset);
+            offset++;
+        }
+        goto release ;
+    }
+
 
 
     /* so we now know that the size of destination is greater
@@ -13498,12 +9910,14 @@ static void genCast (iCode *ic)
       goto release;
 
     DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
-    
+
     /* 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++;
     }
 
@@ -13512,27 +9926,27 @@ static void genCast (iCode *ic)
     /* if unsigned or not an integral type */
     if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
       while (size--)
-       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
+        pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
     } else {
       /* we need to extend the sign :( */
 
       if(size == 1) {
-       /* 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));
+        /* 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_SETF,   pic16_popGet(AOP(result),offset));
       } else {
         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
 
-       if(offset)
-         pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-       else
-         pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-       
-       pic16_emitpcode(POC_MOVLW,   pic16_popGetLit(0xff));
+        if(offset)
+          pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+        else
+          pic16_emitpcode(POC_BTFSC,   pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+
+        pic16_emitpcode(POC_MOVLW,   pic16_popGetLit(0xff));
 
         while (size--)
-         pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset++));
+          pic16_emitpcode(POC_MOVWF,   pic16_popGet(AOP(result),offset++));
       }
     }
 
@@ -13551,49 +9965,36 @@ static int genDjnz (iCode *ic, iCode *ifx)
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     if (!ifx)
-       return 0;
-    
+        return 0;
+
     /* if the if condition has a false label
        then we cannot save */
     if (IC_FALSE(ifx))
-       return 0;
+        return 0;
 
-    /* if the minus is not of the form 
+    /* if the minus is not of the form
        a = a - 1 */
     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
-       !IS_OP_LITERAL(IC_RIGHT(ic)))
-       return 0;
+        !IS_OP_LITERAL(IC_RIGHT(ic)))
+        return 0;
 
     if (operandLitValue(IC_RIGHT(ic)) != 1)
-       return 0;
+        return 0;
 
     /* if the size of this greater than one then no
        saving */
     if (getSize(operandType(IC_RESULT(ic))) > 1)
-       return 0;
+        return 0;
 
     /* otherwise we can save BIG */
     lbl = newiTempLabel(NULL);
     lbl1= newiTempLabel(NULL);
 
     pic16_aopOp(IC_RESULT(ic),ic,FALSE);
-    
-    if (IS_AOP_PREG(IC_RESULT(ic))) {
-       pic16_emitcode("dec","%s",
-                pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-       pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-       pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
-    } else {   
 
+    pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
+    pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
 
-      pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
-      pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-
-      pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-      pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
-
-    }
-    
     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
     ifx->generated = 1;
     return 1;
@@ -13603,7 +10004,7 @@ static int genDjnz (iCode *ic, iCode *ifx)
 /* genReceive - generate code for a receive iCode                  */
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode *ic)
-{    
+{
 
   FENTRY;
 
@@ -13629,7 +10030,7 @@ static void genReceive (iCode *ic)
 
       DEBUGpic16_emitcode ("; ***","1 %s  %d",__FUNCTION__,__LINE__);
 
-      pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
+      pic16_aopOp(IC_RESULT(ic),ic,FALSE);
       size = AOP_SIZE(IC_RESULT(ic));
       offset = 0;
       while (size--) {
@@ -13639,14 +10040,16 @@ static void genReceive (iCode *ic)
   } else {
     DEBUGpic16_emitcode ("; ***","2 %s  %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) ));
     _G.accInUse++;
-    pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
+    pic16_aopOp(IC_RESULT(ic),ic,FALSE);
     _G.accInUse--;
 
     /* set pseudo stack pointer to where it should be - dw*/
     GpsuedoStkPtr = ic->parmBytes;
 
     /* setting GpsuedoStkPtr has side effects here: */
-    assignResultValue(IC_RESULT(ic), 0);
+    /* FIXME: What's the correct size of the return(ed) value?
+     *        For now, assuming '4' as before... */
+    assignResultValue(IC_RESULT(ic), 4, 0);
   }
 
   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
@@ -13659,7 +10062,6 @@ static void
 genDummyRead (iCode * ic)
 {
   operand *op;
-  int i;
 
   op = IC_RIGHT(ic);
   if (op && IS_SYMOP(op)) {
@@ -13668,12 +10070,7 @@ genDummyRead (iCode * ic)
       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_mov2w_volatile(AOP(op));
     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__);
@@ -13718,95 +10115,96 @@ void genpic16Code (iCode *lic)
         if ( options.debug ) {
           debugFile->writeCLine (ic);
         }
-        
+
         if(!options.noCcodeInAsm) {
-          pic16_addpCode2pBlock(pb, pic16_newpCodeCSource(ic->lineno, ic->filename, 
+          pic16_addpCode2pBlock(pb, pic16_newpCodeCSource(ic->lineno, ic->filename,
               printCLine(ic->filename, ic->lineno)));
         }
 
         cln = ic->lineno ;
       }
-       
+
       if(options.iCodeInAsm) {
-        char *l;
+        const char *iLine;
 
-          /* insert here code to print iCode as comment */
-          l = Safe_strdup(printILine(ic));
-          pic16_emitpcomment("ic:%d: %s", ic->seq, l);
+        /* insert here code to print iCode as comment */
+        iLine = printILine(ic);
+        pic16_emitpcomment("ic:%d: %s", ic->seq, iLine);
+        dbuf_free(iLine);
       }
-       
+
       /* if the result is marked as
        * spilt and rematerializable or code for
        * this has already been generated then
        * do nothing */
-      if (resultRemat(ic) || ic->generated ) 
+      if (resultRemat(ic) || ic->generated )
         continue ;
-       
+
       /* depending on the operation */
       switch (ic->op) {
         case '!' :
           pic16_genNot(ic);
           break;
-           
+
         case '~' :
           pic16_genCpl(ic);
           break;
-           
+
         case UNARYMINUS:
           genUminus (ic);
           break;
-           
+
         case IPUSH:
           genIpush (ic);
           break;
-           
+
         case IPOP:
-          /* IPOP happens only when trying to restore a 
-          * spilt live range, if there is an ifx statement
-          * following this pop then the if statement might
-          * be using some of the registers being popped which
-          * would destroy the contents of the register so
-          * we need to check for this condition and handle it */
-          if (ic->next
-            && ic->next->op == IFX
-            && regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
-              genIfx (ic->next,ic);
+          /* IPOP happens only when trying to restore a
+           * spilt live range, if there is an ifx statement
+           * following this pop then the if statement might
+           * be using some of the registers being popped which
+           * would destroy the contents of the register so
+           * we need to check for this condition and handle it */
+           if (ic->next
+             && ic->next->op == IFX
+             && regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
+               genIfx (ic->next,ic);
           else
             genIpop (ic);
-          break; 
-           
+          break;
+
         case CALL:
           genCall (ic);
           break;
-           
+
         case PCALL:
           genPcall (ic);
           break;
-           
+
         case FUNCTION:
           genFunction (ic);
           break;
-           
+
         case ENDFUNCTION:
           genEndFunction (ic);
           break;
-           
+
         case RETURN:
           genRet (ic);
           break;
-           
+
         case LABEL:
           genLabel (ic);
           break;
-           
+
         case GOTO:
           genGoto (ic);
           break;
-           
+
         case '+' :
           pic16_genPlus (ic) ;
           break;
-           
+
         case '-' :
           if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
             pic16_genMinus (ic);
@@ -13815,23 +10213,23 @@ void genpic16Code (iCode *lic)
         case '*' :
           genMult (ic);
           break;
-           
+
         case '/' :
           genDiv (ic) ;
           break;
-           
+
         case '%' :
           genMod (ic);
           break;
-           
+
         case '>' :
-          genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                  
+          genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
           break;
-           
+
         case '<' :
           genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
           break;
-           
+
         case LE_OP:
         case GE_OP:
         case NE_OP:
@@ -13843,83 +10241,83 @@ void genpic16Code (iCode *lic)
 
         case EQ_OP:
           genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
-          break;           
-           
+          break;
+
         case AND_OP:
           genAndOp (ic);
           break;
-           
+
         case OR_OP:
           genOrOp (ic);
           break;
-           
+
         case '^' :
           genXor (ic,ifxForOp(IC_RESULT(ic),ic));
           break;
-           
+
         case '|' :
           genOr (ic,ifxForOp(IC_RESULT(ic),ic));
           break;
-           
+
         case BITWISEAND:
           genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
           break;
-           
+
         case INLINEASM:
           genInline (ic);
           break;
-           
+
         case RRC:
           genRRC (ic);
           break;
-           
+
         case RLC:
           genRLC (ic);
           break;
-           
+
         case GETHBIT:
           genGetHbit (ic);
           break;
-           
+
         case LEFT_OP:
           genLeftShift (ic);
           break;
-           
+
         case RIGHT_OP:
           genRightShift (ic);
           break;
-           
+
         case GET_VALUE_AT_ADDRESS:
           genPointerGet(ic);
           break;
-           
+
         case '=' :
           if (POINTER_SET(ic))
             genPointerSet(ic);
           else
             genAssign(ic);
           break;
-           
+
         case IFX:
           genIfx (ic,NULL);
           break;
-           
+
         case ADDRESS_OF:
           genAddrOf (ic);
           break;
-           
+
         case JUMPTABLE:
           genJumpTab (ic);
           break;
-           
+
         case CAST:
           genCast (ic);
           break;
-           
+
         case RECEIVE:
           genReceive(ic);
           break;
-           
+
         case SEND:
           addSet(&_G.sendSet,ic);
           break;
@@ -13940,7 +10338,7 @@ void genpic16Code (iCode *lic)
       peepHole (&lineHead);
 
     /* now do the actual printing */
-    printLine (lineHead, codeOutFile);
+    printLine (lineHead, codeOutBuf);
 
 #ifdef PCODE_DEBUG
     DFPRINTF((stderr,"printing pBlock\n\n"));
@@ -13949,4 +10347,3 @@ void genpic16Code (iCode *lic)
 
     return;
 }
-