Applied patch #2762516
[fw/sdcc] / src / pic / gen.c
index 73f965e270952736712b3193804c028fdebdebd1..a2482345d8cf644255cb770a7ffb6c44b8de79f4 100644 (file)
@@ -1,91 +1,78 @@
 /*-------------------------------------------------------------------------
-  SDCCgen51.c - source file for code generation for 8051
-  
+  gen.c - source file for code generation for pic
+
   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
-  
+    cont'd   -  Raphael Neider <rneider AT web.de> (2005)
+
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   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 <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "SDCCglobl.h"
-#include "newalloc.h"
-
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
-#else
-#ifdef HAVE_MACHINE_ENDIAN_H
-#include <machine/endian.h>
-#else
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#else
-#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
-#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
-#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
-#endif
-#endif
-#endif
-#endif
+/*
+ * 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.
+ */
 
-#include "common.h"
-#include "SDCCpeeph.h"
-#include "ralloc.h"
-#include "pcode.h"
 #include "gen.h"
+#include "glue.h"
+
+/*
+ * Imports
+ */
+extern struct dbuf_s *codeOutBuf;
+extern set *externs;
 
-static int labelOffset=0;
-static int debug_verbose=1;
-static int optimized_for_speed = 0;
 
-unsigned int pic14aopLiteral (value *val, int offset);
+static pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
+static pCodeOp *popRegFromString(char *str, int size, int offset);
+static int aop_isLitLike(asmop *aop);
 
-/* 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 */
+/* The PIC port(s) need not differentiate between POINTER and FPOINTER. */
+#define PIC_IS_DATA_PTR(x)  (IS_DATA_PTR(x) || IS_FARPTR(x))
 
-static char *zero = "#0x00";
-static char *one  = "#0x01";
+/*
+ * 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.
+ */
+static int max_key = 0;
+static int labelOffset = 0;
+static int GpsuedoStkPtr = 0;
+static int pic14_inISR = 0;
+
+static char *zero = "0x00";
+static char *one  = "0x01";
 static char *spname = "sp";
 
-char *fReturnpic14[] = {"FSR","dph","b","a" };
-//char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
+static char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
 static char **fReturn = fReturnpic14;
 
-static char *accUse[] = {"a","b"};
-
-//static short rbank = -1;
-
 static struct {
-    short r0Pushed;
-    short r1Pushed;
     short accInUse;
     short inLine;
     short debugLine;
@@ -93,20 +80,20 @@ static struct {
     set *sendSet;
 } _G;
 
-extern int pic14_ptrRegReq ;
-extern int pic14_nRegs;
-extern FILE *codeOutFile;
-static void saverbank (int, iCode *,bool);
+/*
+ * 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;
 
 static lineNode *lineHead = NULL;
 static lineNode *lineCurr = NULL;
-
-static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
-0xE0, 0xC0, 0x80, 0x00};
-static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
-0x07, 0x03, 0x01, 0x00};
-
-static  pBlock *pb;
+static pBlock *pb;
 
 /*-----------------------------------------------------------------*/
 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
@@ -119,188 +106,202 @@ static  pBlock *pb;
 /*-----------------------------------------------------------------*/
 static int my_powof2 (unsigned long num)
 {
-  if(num) {
-    if( (num & (num-1)) == 0) {
-      int nshifts = -1;
-      while(num) {
-       num>>=1;
-       nshifts++;
-      }
-      return nshifts;
+    if(num) {
+        if( (num & (num-1)) == 0) {
+            int nshifts = -1;
+            while(num) {
+                num>>=1;
+                nshifts++;
+            }
+            return nshifts;
+        }
     }
-  }
 
-  return -1;
+    return -1;
 }
 
-static void emitpLabel(int key)
+void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
 {
-  addpCode2pBlock(pb,newpCodeLabel(key));
+
+    DEBUGpic14_emitcode ("; ","line = %d result %s=%s, size=%d, left %s=%s, size=%d, right %s=%s, size=%d",
+        line_no,
+        ((result) ? AopType(AOP_TYPE(result)) : "-"),
+        ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
+        ((result) ? AOP_SIZE(result) : 0),
+        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
+        ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
+        ((left)   ? AOP_SIZE(left) : 0),
+        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
+        ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
+        ((right)  ? AOP_SIZE(right) : 0));
+
 }
 
-void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+static void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
 {
 
-  addpCode2pBlock(pb,newpCode(poc,pcop));
+    DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
+        line_no,
+        ((result) ? AopType(AOP_TYPE(result)) : "-"),
+        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
+        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
+        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
+        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
+        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
 
 }
-/*-----------------------------------------------------------------*/
-/* pic14_emitcode - writes the code into a file : for now it is simple    */
-/*-----------------------------------------------------------------*/
-void pic14_emitcode (char *inst,char *fmt, ...)
+
+void DEBUGpic14_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;
 
-    va_start(ap,fmt);   
+    if(!debug_verbose && !options.debug)
+        return;
+
+    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)));
+        connectLine(lineCurr,newLineNode(lb)) :
+    (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
 
-    if(debug_verbose)
-      addpCode2pBlock(pb,newpCodeCharP(lb));
+    addpCode2pBlock(pb,newpCodeCharP(lb));
 
     va_end(ap);
 }
 
-void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
+static void Safe_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
+{
+#if defined (HAVE_VSNPRINTF)
+  vsnprintf (buf, size, fmt, ap);
+#elif defined (HAVE_VSPRINTF)
+  vsprintf (buf, size, fmt, ap);
+  if (strlen (buf) >= size)
+  {
+    fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
+  }
+#elif defined (HAVE_SNPRINTF)
+  snprintf (buf, size, "vs(n)printf required");
+#elif defined (HAVE_SRINTF)
+  sprintf (buf, "vs(n)printf required");
+  if (strlen (buf) >= size)
+  {
+    fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
+  }
+#else
+  assert ( !"neither vsnprintf nor vsprintf is present -- unable to proceed" );
+#endif
+}
+
+void emitpComment (const char *fmt, ...)
+{
+  va_list va;
+  char buffer[4096];
+
+  va_start (va, fmt);
+  if (pb) {
+    Safe_vsnprintf (buffer, 4096, fmt, va);
+    //fprintf (stderr, "%s\n" ,buffer);
+    addpCode2pBlock (pb, newpCodeCharP (buffer));
+  }
+  va_end (va);
+}
+
+void emitpLabel(int key)
+{
+    addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
+}
+
+/* gen.h defines a macro emitpcode that should be used to call emitpcode
+ * as this allows for easy debugging (ever asked the question: where was
+ * this instruction geenrated? Here is the answer... */
+void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
+{
+    if(pcop)
+        addpCode2pBlock(pb,newpCode(poc,pcop));
+    else {
+        static int has_warned = 0;
+
+        DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
+        if (!has_warned) {
+            has_warned = 1;
+            fprintf( stderr, "WARNING: encountered NULL pcop--this is probably a compiler bug...\n" );
+        }
+    }
+}
+
+static void emitpcodeNULLop(PIC_OPCODE poc)
+{
+    addpCode2pBlock(pb,newpCode(poc,NULL));
+}
+
+/*-----------------------------------------------------------------*/
+/* pic14_emitcode - writes the code into a file : for now it is simple    */
+/*-----------------------------------------------------------------*/
+void pic14_emitcode (char *inst,char *fmt, ...)
 {
     va_list ap;
-    char lb[INITIAL_INLINEASM];  
+    char lb[INITIAL_INLINEASM];
     char *lbp = lb;
 
-    if(!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)));
+        connectLine(lineCurr,newLineNode(lb)) :
+    (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
+    lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':');
 
-    addpCode2pBlock(pb,newpCodeCharP(lb));
+    if(debug_verbose)
+        addpCode2pBlock(pb,newpCodeCharP(lb));
 
     va_end(ap);
 }
 
-
 /*-----------------------------------------------------------------*/
-/* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
+/* pic14_emitDebuggerSymbol - associate the current code location  */
+/*   with a debugger symbol                                        */
 /*-----------------------------------------------------------------*/
-static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
+void
+pic14_emitDebuggerSymbol (char * debugSym)
 {
-    bool r0iu = FALSE , r1iu = FALSE;
-    bool r0ou = FALSE , r1ou = FALSE;
-
-    /* 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 = pic14_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 = pic14_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) {
-            pic14_emitcode ("push","%s",
-                      pic14_regWithIdx(R0_IDX)->dname);
-            _G.r0Pushed++ ;
-        }
-        
-        ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
-        (*aopp)->type = AOP_R0;
-
-        return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
-    }
-
-    /* if r1 not used then */
-
-    if (!r1iu) {
-        /* push it if not already pushed */
-        if (!_G.r1Pushed) {
-            pic14_emitcode ("push","%s",
-                      pic14_regWithIdx(R1_IDX)->dname);
-            _G.r1Pushed++ ;
-        }
-        
-        ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
-        (*aopp)->type = AOP_R1;
-        return pic14_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);
+    _G.debugLine = 1;
+    pic14_emitcode ("", ";%s ==.", debugSym);
+    _G.debugLine = 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* newAsmop - creates a new asmOp                                  */
 /*-----------------------------------------------------------------*/
-asmop *newAsmop (short type)
+static asmop *newAsmop (short type)
 {
     asmop *aop;
 
@@ -309,27 +310,32 @@ asmop *newAsmop (short type)
     return aop;
 }
 
-static void genSetDPTR(int n)
-{
-    if (!n)
-    {
-        pic14_emitcode(";", "Select standard DPTR");
-        pic14_emitcode("mov", "dps, #0x00");
-    }
-    else
-    {
-        pic14_emitcode(";", "Select alternate DPTR");
-        pic14_emitcode("mov", "dps, #0x01");
-    }
-}
-
 /*-----------------------------------------------------------------*/
-/* pointerCode - returns the code for a pointer type               */
+/* resolveIfx - converts an iCode ifx into a form more useful for  */
+/*              generating code                                    */
 /*-----------------------------------------------------------------*/
-static int pointerCode (sym_link *etype)
+static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
 {
+    if(!resIfx)
+        return;
+
+    //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+    resIfx->condition = 1;  /* assume that the ifx is true */
+    resIfx->generated = 0;  /* indicate that the ifx has not been used */
+
+    if(!ifx) {
+        resIfx->lbl = NULL; /* this is wrong: newiTempLabel(NULL);  / * oops, there is no ifx. so create a label */
+    } else {
+        if(IC_TRUE(ifx)) {
+            resIfx->lbl = IC_TRUE(ifx);
+        } else {
+            resIfx->lbl = IC_FALSE(ifx);
+            resIfx->condition = 0;
+        }
+    }
 
-    return PTR_TYPE(SPEC_OCLS(etype));
+    //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
 
 }
 
@@ -346,148 +352,117 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
     if (sym->aop)
         return sym->aop;
 
-    /* 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 && !options.stack10bit) || sym->iaccess) {
-        sym->aop = aop = newAsmop(0);
-        aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
-        aop->size = getSize(sym->type);
-
-        /* now assign the address of the variable to 
-        the pointer register */
-        if (aop->type != AOP_STK) {
-
-            if (sym->onStack) {
-                    if ( _G.accInUse )
-                        pic14_emitcode("push","acc");
-
-                    pic14_emitcode("mov","a,_bp");
-                    pic14_emitcode("add","a,#0x%02x",
-                             ((sym->stack < 0) ?
-                             ((char)(sym->stack - _G.nRegsSaved )) :
-                             ((char)sym->stack)) & 0xff);
-                    pic14_emitcode("mov","%s,a",
-                             aop->aopu.aop_ptr->name);
-
-                    if ( _G.accInUse )
-                        pic14_emitcode("pop","acc");
-            } else
-                pic14_emitcode("mov","%s,#%s",
-                         aop->aopu.aop_ptr->name,
-                         sym->rname);
-            aop->paged = space->paged;
-        } else
-            aop->aopu.aop_stk = sym->stack;
-        return aop;
-    }
-    
-    if (sym->onStack && options.stack10bit)
-    {
-        /* It's on the 10 bit stack, which is located in
-         * far data space.
-         */
-         
-      //DEBUGpic14_emitcode(";","%d",__LINE__);
-
-        if ( _G.accInUse )
-               pic14_emitcode("push","acc");
-
-        pic14_emitcode("mov","a,_bp");
-        pic14_emitcode("add","a,#0x%02x",
-                 ((sym->stack < 0) ?
-                   ((char)(sym->stack - _G.nRegsSaved )) :
-                   ((char)sym->stack)) & 0xff);
-        
-        genSetDPTR(1);
-        pic14_emitcode ("mov","dpx1,#0x40");
-        pic14_emitcode ("mov","dph1,#0x00");
-        pic14_emitcode ("mov","dpl1, a");
-        genSetDPTR(0);
-       
-        if ( _G.accInUse )
-            pic14_emitcode("pop","acc");
-            
-        sym->aop = aop = newAsmop(AOP_DPTR2);
-       aop->size = getSize(sym->type); 
-       return aop;
-    }
-
     //DEBUGpic14_emitcode(";","%d",__LINE__);
-    /* if in bit space */
-    if (IN_BITSPACE(space)) {
-        sym->aop = aop = newAsmop (AOP_CRY);
-        aop->aopu.aop_dir = sym->rname ;
-        aop->size = getSize(sym->type);
-       DEBUGpic14_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);
-       DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+        DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
         return aop;
     }
 
     /* special case for a function */
-    if (IS_FUNC(sym->type)) {   
-        sym->aop = aop = newAsmop(AOP_IMMD);    
-        //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
-       aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
-        strcpy(aop->aopu.aop_immd,sym->rname);
-        aop->size = FPTRSIZE; 
+    if (IS_FUNC(sym->type)) {
+
+        sym->aop = aop = newAsmop(AOP_PCODE);
+        aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
+        PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+        PCOI(aop->aopu.pcop)->_function = 1;
+        PCOI(aop->aopu.pcop)->index = 0;
+        aop->size = FPTRSIZE;
+        DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
         return aop;
     }
 
+    if (IS_ARRAY(sym->type)) {
+        sym->aop = aop = newAsmop(AOP_PCODE);
+        aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
+        PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+        PCOI(aop->aopu.pcop)->_function = 0;
+        PCOI(aop->aopu.pcop)->index = 0;
+        aop->size = getSize(sym->etype) * DCL_ELEM(sym->type);
+
+        DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+        return aop;
+    }
 
     /* only remaining is far space */
     /* in which case DPTR gets the address */
-    sym->aop = aop = newAsmop(AOP_DPTR);
-    pic14_emitcode ("mov","dptr,#%s", sym->rname);
-    aop->size = getSize(sym->type);
+    sym->aop = aop = newAsmop(AOP_PCODE);
+
+    aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
+    PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+    PCOI(aop->aopu.pcop)->index = 0;
+
+    DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+        __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+
+    allocDirReg (IC_LEFT(ic));
+
+    aop->size = FPTRSIZE;
 
-    DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
     /* if it is in code space */
     if (IN_CODESPACE(space))
         aop->code = 1;
 
-    return aop;     
+    return aop;
 }
 
 /*-----------------------------------------------------------------*/
 /* aopForRemat - rematerialzes an object                           */
 /*-----------------------------------------------------------------*/
-static asmop *aopForRemat (symbol *sym)
+static asmop *aopForRemat (operand *op) // x symbol *sym)
 {
-    iCode *ic = sym->rematiCode;
-    asmop *aop = newAsmop(AOP_IMMD);
+    symbol *sym = OP_SYMBOL(op);
+    iCode *ic = NULL;
+    asmop *aop = newAsmop(AOP_PCODE);
     int val = 0;
+    int offset = 0;
+
+    ic = sym->rematiCode;
+
     DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
+    if(IS_OP_POINTER(op)) {
+        DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
+    }
     for (;;) {
-       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;
-    }
-
-    if (val)
-       sprintf(buffer,"(%s %c 0x%04x)",
-               OP_SYMBOL(IC_LEFT(ic))->rname, 
-               val >= 0 ? '+' : '-',
-               abs(val) & 0xffff);
-    else
-       strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
+        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;
+    aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
+    PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
+    PCOI(aop->aopu.pcop)->index = val;
+
+    DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+        __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
+        val, IS_PTR_CONST(operandType(op)));
+
+    //  DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
+
+    allocDirReg (IC_LEFT(ic));
+
+    return aop;
+}
+
+static int aopIdx (asmop *aop, int offset)
+{
+    if(!aop)
+        return -1;
+
+    if(aop->type !=  AOP_REG)
+        return -2;
+
+    return aop->aopu.aop_reg[offset]->rIdx;
 
-    //DEBUGpic14_emitcode(";","%s",buffer);
-    aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
-    strcpy(aop->aopu.aop_immd,buffer);    
-    return aop;        
 }
 
 /*-----------------------------------------------------------------*/
@@ -540,30 +515,31 @@ static bool operandsEqu ( operand *op1, operand *op2)
     sym2 = OP_SYMBOL(op2);
 
     /* if both are itemps & one is spilt
-       and the other is not then false */
+    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)
         return TRUE ;
 
-    if (strcmp(sym1->rname,sym2->rname) == 0)
+    if (sym1->rname[0] && sym2->rname[0]
+        && strcmp (sym1->rname, sym2->rname) == 0)
         return TRUE;
 
 
     /* 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))
         return TRUE;
 
-    if (IS_ITEMP(op2)  && 
+    if (IS_ITEMP(op2)  &&
         !IS_ITEMP(op1) &&
         sym2->isspilt  &&
-       sym1->level > 0 &&
+        sym1->level > 0 &&
         (sym2->usl.spillLoc == sym1))
         return TRUE ;
 
@@ -571,7 +547,7 @@ static bool operandsEqu ( operand *op1, operand *op2)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_sameRegs - two asmops have the same registers                   */
+/* pic14_sameRegs - two asmops have the same registers             */
 /*-----------------------------------------------------------------*/
 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
 {
@@ -592,7 +568,7 @@ bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
             aop2->aopu.aop_reg[i] )
             return FALSE ;
 
-    return TRUE ;
+        return TRUE ;
 }
 
 /*-----------------------------------------------------------------*/
@@ -607,30 +583,34 @@ void aopOp (operand *op, iCode *ic, bool result)
     if (!op)
         return ;
 
-    DEBUGpic14_emitcode(";","%d",__LINE__);
     /* if this a literal */
     if (IS_OP_LITERAL(op)) {
         op->aop = aop = newAsmop(AOP_LIT);
         aop->aopu.aop_lit = op->operand.valOperand;
         aop->size = getSize(operandType(op));
-      DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
         return;
     }
 
+    {
+        sym_link *type = operandType(op);
+        if(IS_PTR_CONST(type))
+            DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
+    }
+
     /* if already has a asmop then continue */
     if (op->aop)
         return ;
 
     /* if the underlying symbol has a aop */
     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
-      DEBUGpic14_emitcode(";","%d",__LINE__);
+        DEBUGpic14_emitcode(";","%d",__LINE__);
         op->aop = OP_SYMBOL(op)->aop;
         return;
     }
 
     /* if this is a true symbol */
-    if (IS_TRUE_SYMOP(op)) {    
-      DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
+    if (IS_TRUE_SYMOP(op)) {
+        //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
         op->aop = aopForSym(ic,OP_SYMBOL(op),result);
         return ;
     }
@@ -639,8 +619,8 @@ void 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);
@@ -648,56 +628,97 @@ void aopOp (operand *op, iCode *ic, bool result)
 
     /* if the type is a conditional */
     if (sym->regType == REG_CND) {
-      DEBUGpic14_emitcode(";","%d",__LINE__);
         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
         aop->size = 0;
         return;
     }
 
     /* if it is spilt then two situations
-    a) is rematerialize 
+    a) is rematerialize
     b) has a spill location */
     if (sym->isspilt || sym->nRegs == 0) {
 
-      DEBUGpic14_emitcode(";","%d",__LINE__);
+        DEBUGpic14_emitcode(";","%d",__LINE__);
         /* rematerialize it NOW */
         if (sym->remat) {
-            sym->aop = op->aop = aop =
-                                      aopForRemat (sym);
+
+            sym->aop = op->aop = aop = aopForRemat (op);
             aop->size = getSize(sym->type);
-           DEBUGpic14_emitcode(";","%d",__LINE__);
+            //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
             return;
         }
 
-       if (sym->accuse) {
-           int i;
-            aop = op->aop = sym->aop = newAsmop(AOP_ACC);
-            aop->size = getSize(sym->type);
-            for ( i = 0 ; i < 2 ; i++ )
-                aop->aopu.aop_str[i] = accUse[i];
-           DEBUGpic14_emitcode(";","%d",__LINE__);
-            return;  
-       }
-
         if (sym->ruonly ) {
-            unsigned i;
-            aop = op->aop = sym->aop = newAsmop(AOP_STR);
+            if(sym->isptr) {    // && sym->uptr
+                aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
+                aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
+
+                //PCOI(aop->aopu.pcop)->_const = 0;
+                //PCOI(aop->aopu.pcop)->index = 0;
+                /*
+                DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+                __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+                */
+                //allocDirReg (IC_LEFT(ic));
+
+                aop->size = getSize(sym->type);
+                DEBUGpic14_emitcode(";","%d",__LINE__);
+                return;
+
+            } else {
+
+                unsigned i;
+
+                aop = op->aop = sym->aop = newAsmop(AOP_STR);
+                aop->size = getSize(sym->type);
+                for ( i = 0 ; i < fReturnSizePic ; i++ )
+                    aop->aopu.aop_str[i] = fReturn[i];
+
+                DEBUGpic14_emitcode(";","%d",__LINE__);
+                return;
+            }
+        }
+
+        /* else spill location  */
+        if (sym->usl.spillLoc)
+        {
+            asmop *oldAsmOp = NULL;
+
+            if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+            {
+                /* force a new aop if sizes differ */
+                oldAsmOp = sym->usl.spillLoc->aop;
+                sym->usl.spillLoc->aop = NULL;
+            }
+            DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
+                __FUNCTION__,__LINE__,
+                sym->usl.spillLoc->rname,
+                sym->rname, sym->usl.spillLoc->offset);
+
+            sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+            if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+            {
+                /* Don't reuse the new aop, go with the last one */
+                sym->usl.spillLoc->aop = oldAsmOp;
+            }
+            //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
+            aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
+                getSize(sym->type),
+                sym->usl.spillLoc->offset);
             aop->size = getSize(sym->type);
-            for ( i = 0 ; i < fReturnSizePic ; i++ )
-             aop->aopu.aop_str[i] = fReturn[i];
-           DEBUGpic14_emitcode(";","%d",__LINE__);
+
             return;
         }
+    }
 
-        /* else spill location  */
-       DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
-        sym->aop = op->aop = aop = 
-                                  aopForSym(ic,sym->usl.spillLoc,result);
-        aop->size = getSize(sym->type);
-        return;
+    {
+        sym_link *type = operandType(op);
+        if(IS_PTR_CONST(type))
+            DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
     }
 
     /* must be in a register */
+    DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
     sym->aop = op->aop = aop = newAsmop(AOP_REG);
     aop->size = sym->nRegs;
     for ( i = 0 ; i < sym->nRegs ;i++)
@@ -708,104 +729,58 @@ void aopOp (operand *op, iCode *ic, bool result)
 /* freeAsmop - free up the asmop given to an operand               */
 /*----------------------------------------------------------------*/
 void 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; 
-
     aop->freed = 1;
 
-    /* depending on the asmop type only three cases need work AOP_RO
-       , AOP_R1 && AOP_STK */
-    switch (aop->type) {
-        case AOP_R0 :
-            if (_G.r0Pushed ) {
-                if (pop) {
-                    pic14_emitcode ("pop","ar0");     
-                    _G.r0Pushed--;
-                }
-            }
-            bitVectUnSetBit(ic->rUsed,R0_IDX);
-            break;
-
-        case AOP_R1 :
-            if (_G.r1Pushed ) {
-                if (pop) {
-                    pic14_emitcode ("pop","ar1");
-                    _G.r1Pushed--;
-                }
-            }
-            bitVectUnSetBit(ic->rUsed,R1_IDX);          
-            break;
-
-        case AOP_STK :
-        {
-            int sz = aop->size;    
-            int stk = aop->aopu.aop_stk + aop->size;
-            bitVectUnSetBit(ic->rUsed,R0_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");
-            }
-            
-            if (stk) {
-                pic14_emitcode ("mov","a,_bp");
-                pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
-                pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
-            } else {
-                pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
-            }
-
-            while (sz--) {
-                pic14_emitcode("pop","acc");
-                pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
-                if (!sz) break;
-                pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
-            }
-            op->aop = aop;
-            freeAsmop(op,NULL,ic,TRUE);
-            if (_G.r0Pushed) {
-                pic14_emitcode("pop","ar0");
-                _G.r0Pushed--;
-            }
-
-            if (_G.r1Pushed) {
-                pic14_emitcode("pop","ar1");
-                _G.r1Pushed--;
-            }       
-        }
-    }
-
-dealloc:
     /* all other cases just dealloc */
-    if (op ) {
+    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;
         }
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* pic14aopLiteral - string from a literal value                   */
+/*-----------------------------------------------------------------*/
+static unsigned int pic14aopLiteral (value *val, int offset)
+{
+        union {
+                float f;
+                unsigned char c[4];
+        } fl;
+
+        /* if it is a float then it gets tricky */
+        /* otherwise it is fairly simple */
+        if (!IS_FLOAT(val->type)) {
+                unsigned long v = ulFromVal (val);
+
+                return ( (v >> (offset * 8)) & 0xff);
+        }
+
+        /* it is type float */
+        fl.f = (float) floatFromVal(val);
+#ifdef WORDS_BIGENDIAN
+        return fl.c[3-offset];
+#else
+        return fl.c[offset];
+#endif
+}
+
 /*-----------------------------------------------------------------*/
 /* aopGet - for fetching value of the aop                          */
 /*-----------------------------------------------------------------*/
@@ -817,238 +792,276 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* offset is greater than
     size then zero */
+    assert(aop);
     if (offset > (aop->size - 1) &&
         aop->type != AOP_LIT)
         return zero;
 
     /* depending on type */
     switch (aop->type) {
-       
-    case AOP_R0:
-    case AOP_R1:
-        DEBUGpic14_emitcode(";","%d",__LINE__);
-       /* if we need to increment it */       
-       while (offset > aop->coff) {        
-           pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
-           aop->coff++;
-       }
-       
-       while (offset < aop->coff) {
-           pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
-           aop->coff--;
-       }
-       
-       aop->coff = offset ;
-       if (aop->paged) {
-           pic14_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;
-       
-    case AOP_DPTR:
-    case AOP_DPTR2:
-        DEBUGpic14_emitcode(";","%d",__LINE__);
-    if (aop->type == AOP_DPTR2)
-    {
-        genSetDPTR(1);
-    }
-    
-       while (offset > aop->coff) {
-           pic14_emitcode ("inc","dptr");
-           aop->coff++;
-       }
-       
-       while (offset < aop->coff) {        
-           pic14_emitcode("lcall","__decdptr");
-           aop->coff--;
-       }
-       
-       aop->coff = offset;
-       if (aop->code) {
-           pic14_emitcode("clr","a");
-           pic14_emitcode("movc","a,@a+dptr");
-        }
-    else {
-           pic14_emitcode("movx","a,@dptr");
-    }
-           
-    if (aop->type == AOP_DPTR2)
-    {
-        genSetDPTR(0);
-    }
-           
-    return (dname ? "acc" : "a");
-       
-       
+
     case AOP_IMMD:
-      DEBUGpic14_emitcode(";","%d",__LINE__);
-       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);
-       rs = Safe_calloc(1,strlen(s)+1);
-       strcpy(rs,s);   
-       return rs;
-       
+        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);
+            DEBUGpic14_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);
-       else
-           sprintf(s,"%s",aop->aopu.aop_dir);
-       rs = Safe_calloc(1,strlen(s)+1);
-       strcpy(rs,s);   
-       return rs;
-       
+        if (offset) {
+            sprintf(s,"(%s + %d)",
+                aop->aopu.aop_dir,
+                offset);
+            DEBUGpic14_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;
+
     case AOP_REG:
-      DEBUGpic14_emitcode(";","%d",__LINE__);
-       if (dname) 
-           return aop->aopu.aop_reg[offset]->dname;
-       else
-           return aop->aopu.aop_reg[offset]->name;
-       
+        //if (dname)
+        //    return aop->aopu.aop_reg[offset]->dname;
+        //else
+        return aop->aopu.aop_reg[offset]->name;
+
     case AOP_CRY:
-      pic14_emitcode(";","%d",__LINE__);
-      //pic14_emitcode("clr","a");
-      //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
-      //pic14_emitcode("rlc","a") ;
-      //return (dname ? "acc" : "a");
-      return aop->aopu.aop_dir;
-       
-    case AOP_ACC:
-        DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
-       //if (!offset && dname)
-       //    return "acc";
-       //return aop->aopu.aop_str[offset];
-       return "AOP_accumulator_bug";
+        //pic14_emitcode(";","%d",__LINE__);
+        return aop->aopu.aop_dir;
 
     case AOP_LIT:
-        DEBUGpic14_emitcode(";","%d",__LINE__);
-       sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
-       rs = Safe_calloc(1,strlen(s)+1);
-       strcpy(rs,s);   
-       return rs;
-       
+        sprintf(s, "0x%02x", pic14aopLiteral (aop->aopu.aop_lit, offset));
+        rs = Safe_strdup(s);
+        return rs;
+
     case AOP_STR:
-        DEBUGpic14_emitcode(";","%d",__LINE__);
-       aop->coff = offset ;
-       if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
-           dname)
-           return "acc";
-       
-       return aop->aopu.aop_str[offset];
-       
-    }
+        aop->coff = offset ;
+        if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
+            dname)
+            return "acc";
+        DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
 
-    werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-           "aopget got unsupported aop->type");
-    exit(0);
-}
+        return aop->aopu.aop_str[offset];
 
-/*-----------------------------------------------------------------*/
-/* popGetLabel - create a new pCodeOp of type PO_LABEL             */
-/*-----------------------------------------------------------------*/
-pCodeOp *popGetLabel(unsigned int key)
-{
-  return newpCodeOpLabel(key+100+labelOffset);
+    case AOP_PCODE:
+        {
+            pCodeOp *pcop = aop->aopu.pcop;
+            DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
+            if(pcop->name) {
+                if (pcop->type == PO_IMMEDIATE) {
+                    offset += PCOI(pcop)->index;
+                }
+                if (offset) {
+                    DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
+                    sprintf(s,"(%s+%d)", pcop->name,offset);
+                } else {
+                    DEBUGpic14_emitcode(";","%s",pcop->name);
+                    sprintf(s,"%s", pcop->name);
+                }
+            } else
+                sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
+
+        }
+        rs = Safe_calloc(1,strlen(s)+1);
+        strcpy(rs,s);
+        return rs;
+
+  }
+
+  werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+      "aopget got unsupported aop->type");
+  exit(0);
 }
 
 /*-----------------------------------------------------------------*/
-/* popCopyReg - copy a pcode operator                              */
+/* popGetTempReg - create a new temporary pCodeOp                  */
 /*-----------------------------------------------------------------*/
-pCodeOp *popCopyReg(pCodeOpReg *pc)
+static pCodeOp *popGetTempReg(void)
 {
-  pCodeOpReg *pcor;
 
-  pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
-  pcor->pcop.type = pc->pcop.type;
-  if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
-    fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
-  pcor->r = pc->r;
-  pcor->rIdx = pc->rIdx;
+    pCodeOp *pcop;
+
+    pcop = 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;
+    }
+
+    return pcop;
+}
+
+/*-----------------------------------------------------------------*/
+/* popReleaseTempReg - create a new temporary pCodeOp                  */
+/*-----------------------------------------------------------------*/
+static void popReleaseTempReg(pCodeOp *pcop)
+{
 
+    if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
+        PCOR(pcop)->r->isFree = 1;
 
-  return PCOP(pcor);
 }
 
 /*-----------------------------------------------------------------*/
-/* popCopy - copy a pcode operator                                 */
+/* popGetLabel - create a new pCodeOp of type PO_LABEL             */
 /*-----------------------------------------------------------------*/
-pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
+pCodeOp *popGetLabel(unsigned int key)
 {
-  pCodeOp *pcop;
 
-  pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
-  pcop->type = PO_BIT;
-  if(!(pcop->name = Safe_strdup(pc->name)))
-    fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
-  ((pCodeOpBit *)pcop)->bit = bitval;
+    DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
 
-  ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
+    if(key>(unsigned int)max_key)
+        max_key = key;
+
+    return newpCodeOpLabel(NULL,key+100+labelOffset);
+}
 
-  return pcop;
+/*-------------------------------------------------------------------*/
+/* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
+/*-------------------------------------------------------------------*/
+static pCodeOp *popGetHighLabel(unsigned int key)
+{
+    pCodeOp *pcop;
+    pcop = popGetLabel(key);
+    PCOLAB(pcop)->offset = 1;
+    return pcop;
 }
 
 /*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion              */
+/* popGetLit - asm operator to pcode operator conversion               */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetLit(unsigned int lit)
 {
 
-  return newpCodeOpLit(lit);
+    return newpCodeOpLit((unsigned char)lit);
+}
+
+/*-----------------------------------------------------------------*/
+/* popGetImmd - asm operator to pcode immediate conversion         */
+/*-----------------------------------------------------------------*/
+static pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
+{
+
+    return newpCodeOpImmd(name, offset,index, 0, is_func);
+}
+
+/*-----------------------------------------------------------------*/
+/* popGetWithString - asm operator to pcode operator conversion            */
+/*-----------------------------------------------------------------*/
+static pCodeOp *popGetWithString(char *str, int isExtern)
+{
+    pCodeOp *pcop;
+
+
+    if(!str) {
+        fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
+        exit (1);
+    }
+
+    pcop = newpCodeOp(str,PO_STR);
+    PCOS(pcop)->isPublic = isExtern ? 1 : 0;
+
+    return pcop;
 }
 
+pCodeOp *popGetExternal (char *str, int isReg)
+{
+    pCodeOp *pcop;
+
+    if (isReg) {
+        pcop = newpCodeOpRegFromStr(str);
+    } else {
+        pcop = popGetWithString (str, 1);
+    }
+
+    if (str) {
+      symbol *sym;
+
+      for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
+      {
+        if (!strcmp (str, sym->rname)) break;
+      }
+
+      if (!sym)
+      {
+        sym = newSymbol(str, 0);
+        strncpy(sym->rname, str, SDCC_NAME_MAX);
+        addSet (&externs, sym);
+      } // if
+      sym->used++;
+    }
+    return pcop;
+}
 
 /*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion              */
+/* popRegFromString -                                              */
 /*-----------------------------------------------------------------*/
-pCodeOp *popGetWithString(char *str)
+static pCodeOp *popRegFromString(char *str, int size, int offset)
 {
-  pCodeOp *pcop;
 
+    pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+    pcop->type = PO_DIR;
 
-  if(!str) {
-    fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
-    exit (1);
-  }
+    DEBUGpic14_emitcode(";","%d",__LINE__);
 
-  pcop = newpCodeOp(str,PO_STR);
+    if(!str)
+        str = "BAD_STRING";
+
+    pcop->name = Safe_calloc(1,strlen(str)+1);
+    strcpy(pcop->name,str);
+
+    //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
+
+    PCOR(pcop)->r = dirregWithName(pcop->name);
+    if(PCOR(pcop)->r == NULL) {
+        //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
+        PCOR(pcop)->r = allocRegByName (pcop->name,size);
+        DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
+    } else {
+        DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
+    }
+    PCOR(pcop)->instance = offset;
 
-  return pcop;
+    return pcop;
 }
 
-pCodeOp *popRegFromString(char *str)
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static pCodeOp *popRegFromIdx(int rIdx)
 {
+    pCodeOp *pcop;
 
-  pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-  pcop->type = PO_GPR_REGISTER;
+    DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
+        __FUNCTION__,__LINE__,rIdx);
 
-  PCOR(pcop)->rIdx = -1;
-  PCOR(pcop)->r = NULL;
+    pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
 
-  DEBUGpic14_emitcode(";","%d",__LINE__);
-  pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
+    PCOR(pcop)->rIdx = rIdx;
+    PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
+    PCOR(pcop)->r->isFree = 0;
+    PCOR(pcop)->r->wasUsed = 1;
 
-  return pcop;
+    pcop->type = PCOR(pcop)->r->pc_type;
+
+
+    return pcop;
 }
 
 /*-----------------------------------------------------------------*/
 /* popGet - asm operator to pcode operator conversion              */
 /*-----------------------------------------------------------------*/
-pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
+pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 {
-    char *s = buffer ;
-    char *rs;
+    //char *s = buffer ;
+    //char *rs;
 
     pCodeOp *pcop;
 
@@ -1056,114 +1069,122 @@ pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
     /* offset is greater than
     size then zero */
 
+    assert (aop);
+
+
+    /* XXX: still needed for BIT operands (AOP_CRY) */
     if (offset > (aop->size - 1) &&
-        aop->type != AOP_LIT)
-      return NULL;  //zero;
+        aop->type != AOP_LIT &&
+        aop->type != AOP_PCODE)
+    {
+        printf( "%s: (offset[%d] > AOP_SIZE(op)[%d]-1) && AOP_TYPE(op) != AOP_LIT)\n", __FUNCTION__, offset, aop->size);
+        return NULL;  //zero;
+    }
 
     /* depending on type */
     switch (aop->type) {
-       
-    case AOP_R0:
-    case AOP_R1:
-    case AOP_DPTR:
-    case AOP_DPTR2:
-    case AOP_ACC:
-        DEBUGpic14_emitcode(";8051 legacy","%d",__LINE__);
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       pcop->type = PO_SFR_REGISTER;
-
-       PCOR(pcop)->rIdx = -1;
-       PCOR(pcop)->r = NULL;
-       // Really nasty hack to check for temporary registers
-
-       pcop->name = Safe_strdup("BAD_REGISTER");
-
-       return pcop;
-       
+
     case AOP_IMMD:
-      DEBUGpic14_emitcode(";","%d",__LINE__);
-       pcop = Safe_calloc(1,sizeof(pCodeOp) );
-       pcop->type = PO_IMMEDIATE;
-       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);
-       pcop->name = Safe_calloc(1,strlen(s)+1);
-       strcpy(pcop->name,s);   
-       return pcop;
-       
+        DEBUGpic14_emitcode(";","%d",__LINE__);
+        return popGetImmd(aop->aopu.aop_immd,offset,0,0);
+
     case AOP_DIR:
-       pcop = Safe_calloc(1,sizeof(pCodeOp) );
-       pcop->type = PO_DIR;
-       if (offset)
-           sprintf(s,"(%s + %d)",
-                   aop->aopu.aop_dir,
-                   offset);
-       else
-           sprintf(s,"%s",aop->aopu.aop_dir);
-       pcop->name = Safe_calloc(1,strlen(s)+1);
-       strcpy(pcop->name,s);   
-       return pcop;
-       
+        return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
+
     case AOP_REG:
-      {
-       int rIdx = aop->aopu.aop_reg[offset]->rIdx;
-
-       DEBUGpic14_emitcode(";","%d",__LINE__);
-       if(bit16)
-         pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
-       else
-         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       //pcop->type = PO_GPR_REGISTER;
-       PCOR(pcop)->rIdx = rIdx;
-       PCOR(pcop)->r = pic14_regWithIdx(rIdx);
-       pcop->type = PCOR(pcop)->r->pc_type;
-
-       if (dname)
-         rs = aop->aopu.aop_reg[offset]->dname;
-       else 
-         rs = aop->aopu.aop_reg[offset]->name;
-
-       DEBUGpic14_emitcode(";","%d  %s",__LINE__,rs);
-
-       return pcop;
-      }
+        {
+            int rIdx;
+            assert (offset < aop->size);
+            rIdx = aop->aopu.aop_reg[offset]->rIdx;
+
+            pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+            PCOR(pcop)->rIdx = rIdx;
+            PCOR(pcop)->r = pic14_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;
+            DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
+            return pcop;
+        }
 
     case AOP_CRY:
-      pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
-      return pcop;
-       
+        pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
+        PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
+        //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:
-      DEBUGpic14_emitcode(";","%d",__LINE__);
-      return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
+        return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
 
     case AOP_STR:
-      DEBUGpic14_emitcode(";","%d",__LINE__);
-
-      pcop = Safe_calloc(1,sizeof(pCodeOp) );
-      pcop->type = PO_STR;
-
-      //aop->coff = offset ;
-       if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
-         sprintf(s,"%s","acc");
-       else
-         sprintf(s,"%s",aop->aopu.aop_str[offset]);
-       pcop->name = Safe_calloc(1,strlen(s)+1);
-       strcpy(pcop->name,s);   
-       return pcop;
-       
+        DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
+        return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
+
+    case AOP_PCODE:
+        pcop = NULL;
+        DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
+            __LINE__,
+            ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
+        //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop));
+        switch (aop->aopu.pcop->type)
+        {
+        case PO_IMMEDIATE:
+          pcop = pCodeOpCopy (aop->aopu.pcop);
+          /* usually we want to access the memory at "<symbol> + offset" (using ->index),
+           * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
+          PCOI(pcop)->index += offset;
+          //PCOI(pcop)->offset = 0;
+          break;
+        case PO_DIR:
+          pcop = pCodeOpCopy (aop->aopu.pcop);
+          PCOR(pcop)->instance = offset;
+          break;
+        default:
+          assert ( !"unhandled pCode type" );
+          break;
+        } // switch
+        return pcop;
     }
 
     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-           "popGet got unsupported aop->type");
+        "popGet got unsupported aop->type");
     exit(0);
 }
+
+/*-----------------------------------------------------------------*/
+/* popGetAddr - access the low/high word of a symbol (immediate)   */
+/*              (for non-PO_IMMEDIATEs this is the same as popGet) */
+/*-----------------------------------------------------------------*/
+pCodeOp *popGetAddr (asmop *aop, int offset, int index)
+{
+  if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
+  {
+    pCodeOp *pcop = aop->aopu.pcop;
+    assert (offset <= GPTRSIZE);
+
+    /* special case: index >= 2 should return GPOINTER-style values */
+    if (offset == 2)
+    {
+      pcop = popGetLit (aop->code ? GPTRTAG_CODE : GPTRTAG_DATA);
+      return pcop;
+    }
+
+    pcop = pCodeOpCopy (pcop);
+    /* usually we want to access the memory at "<symbol> + offset" (using ->index),
+     * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
+    PCOI(pcop)->offset += offset;
+    PCOI(pcop)->index += index;
+    //fprintf (stderr, "is PO_IMMEDIATE: %s+o%d+i%d (new o%d,i%d)\n", pcop->name,PCOI(pcop)->offset,PCOI(pcop)->index, offset, index);
+    return pcop;
+  } else {
+    return popGet (aop, offset + index);
+  }
+}
+
 /*-----------------------------------------------------------------*/
 /* aopPut - puts a string for a aop                                */
 /*-----------------------------------------------------------------*/
@@ -1176,7 +1197,7 @@ void aopPut (asmop *aop, char *s, int offset)
 
     if (aop->size && offset > ( aop->size - 1)) {
         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-               "aopPut got offset > aop->size");
+            "aopPut got offset > aop->size");
         exit(0);
     }
 
@@ -1184,322 +1205,245 @@ void aopPut (asmop *aop, char *s, int offset)
     /* depending on where it is ofcourse */
     switch (aop->type) {
     case AOP_DIR:
-       if (offset)
-           sprintf(d,"(%s + %d)",
-                   aop->aopu.aop_dir,offset);
-       else
-           sprintf(d,"%s",aop->aopu.aop_dir);
-       
-       if (strcmp(d,s)) {
-         DEBUGpic14_emitcode(";","%d",__LINE__);
-         if(strcmp(s,"W"))
-           pic14_emitcode("movf","%s,w",s);
-         pic14_emitcode("movwf","%s",d);
-
-         if(strcmp(s,"W"))
-           pic14_emitcode(";BUG! should have this:movf","%s,w   %d",s,__LINE__);
-         emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
-
-
-       }
-       break;
-       
+        if (offset) {
+            sprintf(d,"(%s + %d)",
+                aop->aopu.aop_dir,offset);
+            fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
+
+        } else
+            sprintf(d,"%s",aop->aopu.aop_dir);
+
+        if (strcmp(d,s)) {
+            DEBUGpic14_emitcode(";","%d",__LINE__);
+            if(strcmp(s,"W"))
+                pic14_emitcode("movf","%s,w",s);
+            pic14_emitcode("movwf","%s",d);
+
+            if(strcmp(s,"W")) {
+                pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
+                if(offset >= aop->size) {
+                    emitpcode(POC_CLRF,popGet(aop,offset));
+                    break;
+                } else {
+                    emitpcode(POC_MOVFW, popGetImmd(s,0,offset,0));
+                }
+            }
+            emitpcode(POC_MOVWF,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 )
-               pic14_emitcode("mov","%s,%s  ; %d",
-                        aop->aopu.aop_reg[offset]->dname,s,__LINE__);
-           else
-         */
-
-         if(strcmp(s,"W"))
-           pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
-
-         pic14_emitcode("movwf","%s",
-                  aop->aopu.aop_reg[offset]->name);
-
-         if(strcmp(s,"W")) {
-           pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-           pcop->type = PO_GPR_REGISTER;
-
-           PCOR(pcop)->rIdx = -1;
-           PCOR(pcop)->r = NULL;
-
-           DEBUGpic14_emitcode(";","%d",__LINE__);
-           pcop->name = Safe_strdup(s);
-           emitpcode(POC_MOVFW,pcop);
-         }
-         emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
-
-       }
-       break;
-       
-    case AOP_DPTR:
-    case AOP_DPTR2:
-    
-    if (aop->type == AOP_DPTR2)
-    {
-        genSetDPTR(1);
-    }
-    
-       if (aop->code) {
-           werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                  "aopPut writting to code space");
-           exit(0);
-       }
-       
-       while (offset > aop->coff) {
-           aop->coff++;
-           pic14_emitcode ("inc","dptr");
-       }
-       
-       while (offset < aop->coff) {
-           aop->coff-- ;
-           pic14_emitcode("lcall","__decdptr");
-       }
-       
-       aop->coff = offset;
-       
-       /* if not in accumulater */
-       MOVA(s);        
-       
-       pic14_emitcode ("movx","@dptr,a");
-       
-    if (aop->type == AOP_DPTR2)
-    {
-        genSetDPTR(0);
-    }
-       break;
-       
-    case AOP_R0:
-    case AOP_R1:
-       while (offset > aop->coff) {
-           aop->coff++;
-           pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
-       }
-       while (offset < aop->coff) {
-           aop->coff-- ;
-           pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
-       }
-       aop->coff = offset;
-       
-       if (aop->paged) {
-           MOVA(s);           
-           pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
-           
-       } else
-           if (*s == '@') {
-               MOVA(s);
-               pic14_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);
-                   pic14_emitcode("mov","@%s,%s",
-                            aop->aopu.aop_ptr->name,buffer);
-               } else
-                   pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
-       
-       break;
-       
+        if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
+            if(strcmp(s,"W")==0 )
+                pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
+
+            pic14_emitcode("movwf","%s",
+                aop->aopu.aop_reg[offset]->name);
+
+            if(strcmp(s,zero)==0) {
+                emitpcode(POC_CLRF,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;
+
+                DEBUGpic14_emitcode(";","%d",__LINE__);
+                pcop->name = Safe_strdup(s);
+                emitpcode(POC_MOVFW,pcop);
+                emitpcode(POC_MOVWF,popGet(aop,offset));
+            } else if(strcmp(s,one)==0) {
+                emitpcode(POC_CLRF,popGet(aop,offset));
+                emitpcode(POC_INCF,popGet(aop,offset));
+            } else {
+                emitpcode(POC_MOVWF,popGet(aop,offset));
+            }
+        }
+        break;
+
     case AOP_STK:
-       if (strcmp(s,"a") == 0)
-           pic14_emitcode("push","acc");
-       else
-           pic14_emitcode("push","%s",s);
-       
-       break;
-       
+        if (strcmp(s,"a") == 0)
+            pic14_emitcode("push","acc");
+        else
+            pic14_emitcode("push","%s",s);
+
+        break;
+
     case AOP_CRY:
-       /* if bit variable */
-       if (!aop->aopu.aop_dir) {
-           pic14_emitcode("clr","a");
-           pic14_emitcode("rlc","a");
-       } else {
-           if (s == zero) 
-               pic14_emitcode("clr","%s",aop->aopu.aop_dir);
-           else
-               if (s == one)
-                   pic14_emitcode("setb","%s",aop->aopu.aop_dir);
-               else
-                   if (!strcmp(s,"c"))
-                       pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
-                   else {
-                       lbl = newiTempLabel(NULL);
-                       
-                       if (strcmp(s,"a")) {
-                           MOVA(s);
-                       }
-                       pic14_emitcode("clr","c");
-                       pic14_emitcode("jz","%05d_DS_",lbl->key+100);
-                       pic14_emitcode("cpl","c");
-                       pic14_emitcode("","%05d_DS_:",lbl->key+100);
-                       pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
-                   }
-       }
-       break;
-       
+        /* if bit variable */
+        if (!aop->aopu.aop_dir) {
+            pic14_emitcode("clr","a");
+            pic14_emitcode("rlc","a");
+        } else {
+            if (s == zero)
+                pic14_emitcode("clr","%s",aop->aopu.aop_dir);
+            else
+                if (s == one)
+                    pic14_emitcode("setb","%s",aop->aopu.aop_dir);
+                else
+                    if (!strcmp(s,"c"))
+                        pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
+                    else {
+                        lbl = newiTempLabel(NULL);
+
+                        if (strcmp(s,"a")) {
+                            MOVA(s);
+                        }
+                        pic14_emitcode("clr","c");
+                        pic14_emitcode("jz","%05d_DS_",lbl->key+100);
+                        pic14_emitcode("cpl","c");
+                        pic14_emitcode("","%05d_DS_:",lbl->key+100);
+                        pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
+                    }
+        }
+        break;
+
     case AOP_STR:
-       aop->coff = offset;
-       if (strcmp(aop->aopu.aop_str[offset],s))
-           pic14_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))
-           pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
-       break;
+        aop->coff = offset;
+        if (strcmp(aop->aopu.aop_str[offset],s))
+            pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
+        break;
 
     default :
-       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-              "aopPut got unsupported aop->type");
-       exit(0);    
-    }    
+        werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+            "aopPut got unsupported aop->type");
+        exit(0);
+    }
 
 }
 
 /*-----------------------------------------------------------------*/
-/* reAdjustPreg - points a register back to where it should        */
+/* mov2w_op - generate either a MOVLW or MOVFW based operand type  */
 /*-----------------------------------------------------------------*/
-static void reAdjustPreg (asmop *aop)
+static void mov2w_op (operand *op, int offset)
 {
-    int size ;
-
-    DEBUGpic14_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--)
-                pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
-            break;          
-        case AOP_DPTR :
-        case AOP_DPTR2:
-            if (aop->type == AOP_DPTR2)
-           {
-                genSetDPTR(1);
-           } 
-            while (size--)
-            {
-                pic14_emitcode("lcall","__decdptr");
-            }
-                
-           if (aop->type == AOP_DPTR2)
-           {
-                genSetDPTR(0);
-           }                
-            break;  
-
-    }   
+    assert (op);
+    FENTRY;
 
+    /* for PO_IMMEDIATEs: use address or value? */
+    if (op_isLitLike (op))
+    {
+        /* access address of op */
+        if (AOP_TYPE(op) != AOP_LIT) { assert (offset < 3); }
+        if (IS_SYMOP(op) && IS_GENPTR(OP_SYM_TYPE(op)) && AOP_SIZE(op) < offset)
+        {
+            if (offset == GPTRSIZE-1)
+                emitpcode (POC_MOVLW, popGetLit (GPTRTAG_DATA));
+            else
+                emitpcode (POC_MOVLW, popGetLit (0));
+        }
+        else
+            emitpcode (POC_MOVLW, popGetAddr(AOP(op), offset, 0));
+    } else {
+        /* access value stored in op */
+        mov2w (AOP(op), offset);
+    }
 }
 
+
 /*-----------------------------------------------------------------*/
-/* genNotFloat - generates not for float operations              */
+/* mov2w - generate either a MOVLW or MOVFW based operand type     */
 /*-----------------------------------------------------------------*/
-static void genNotFloat (operand *op, operand *res)
+void mov2w (asmop *aop, int offset)
 {
-    int size, offset;
-    char *l;
-    symbol *tlbl ;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* we will put 127 in the first byte of 
-    the result */
-    aopPut(AOP(res),"#127",0);
-    size = AOP_SIZE(op) - 1;
-    offset = 1;
+    if(!aop)
+        return;
 
-    l = aopGet(op->aop,offset++,FALSE,FALSE);
-    MOVA(l);    
+    DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
 
-    while(size--) {
-        pic14_emitcode("orl","a,%s",
-                 aopGet(op->aop,
-                        offset++,FALSE,FALSE));
-    }
-    tlbl = newiTempLabel(NULL);
+    if ( aop_isLitLike (aop) )
+        emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
+    else
+        emitpcode(POC_MOVFW,popGet(aop,offset));
 
-    tlbl = newiTempLabel(NULL);
-    aopPut(res->aop,one,1);
-    pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
-    aopPut(res->aop,zero,1);
-    pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
+}
 
-    size = res->aop->size - 2;
-    offset = 2;    
-    /* put zeros in the rest */
-    while (size--) 
-        aopPut(res->aop,zero,offset++);
+static void movwf (asmop *op, int offset)
+{
+    emitpcode (POC_MOVWF, popGet(op, offset));
 }
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* opIsGptr: returns non-zero if the passed operand is            */   
-/* a generic pointer type.                                        */
-/*-----------------------------------------------------------------*/ 
-static int opIsGptr(operand *op)
+static pCodeOp *get_argument_pcop (int idx)
 {
-    sym_link *type = operandType(op);
-    
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
-    {
-        return 1;
-    }
-    return 0;        
+    assert (idx > 0 && "the 0th (first) argument is passed via WREG");
+    return popRegFromIdx (Gstack_base_addr - (idx - 1));
+}
+
+static pCodeOp *get_return_val_pcop (int offset)
+{
+    assert (offset > 0 && "the most significant byte is returned via WREG");
+    return popRegFromIdx (Gstack_base_addr - (offset - 1));
+}
+
+static void pass_argument (operand *op, int offset, int idx)
+{
+    if (op)
+        mov2w_op (op, offset);
+    if (idx != 0)
+        emitpcode(POC_MOVWF, get_argument_pcop (idx));
+}
+
+static void get_returnvalue (operand *op, int offset, int idx)
+{
+    if (idx != 0)
+        emitpcode(POC_MOVFW, get_return_val_pcop (idx));
+    movwf(AOP(op), offset);
+}
+
+static void call_libraryfunc (char *name)
+{
+    symbol *sym;
+
+    /* library code might reside in different page... */
+    emitpcode (POC_PAGESEL, popGetWithString (name, 1));
+    /* call the library function */
+    emitpcode (POC_CALL, popGetExternal (name, 0));
+    /* might return from different page... */
+    emitpcode (POC_PAGESEL, popGetWithString ("$", 0));
+
+    /* create symbol, mark it as `extern' */
+    sym = findSym(SymbolTab, NULL, name);
+    if (!sym) {
+    sym = newSymbol(name, 0);
+    strncpy(sym->rname, name, SDCC_NAME_MAX);
+    addSym(SymbolTab, sym, sym->rname, 0, 0, 0);
+    addSet(&externs, sym);
+    } // if
+    sym->used++;
 }
-#endif
 
 /*-----------------------------------------------------------------*/
-/* pic14_getDataSize - get the operand data size                         */
+/* pic14_getDataSize - get the operand data size                   */
 /*-----------------------------------------------------------------*/
 int pic14_getDataSize(operand *op)
 {
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    int size;
 
+    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    return AOP_SIZE(op);
+#if 0
+    size = getSize(OP_SYM_ETYPE(op));
+    return size;
+    //return AOP_SIZE(op);
 
     // tsd- in the pic port, the genptr size is 1, so this code here
     // fails. ( in the 8051 port, the size was 4).
-#if 0
-    int size;
+#else
     size = AOP_SIZE(op);
-    if (size == GPTRSIZE)
+    if (IS_SYMOP(op) && IS_GENPTR(OP_SYM_TYPE(op)))
     {
         sym_link *type = operandType(op);
         if (IS_GENPTR(type))
         {
             /* generic pointer; arithmetic operations
-             * should ignore the high byte (pointer type).
-             */
+            * should ignore the high byte (pointer type).
+            */
             size--;
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+            DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
         }
     }
     return size;
@@ -1507,33 +1451,36 @@ int pic14_getDataSize(operand *op)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_outAcc - output Acc                                             */
+/* pic14_outAcc - output Acc                                       */
 /*-----------------------------------------------------------------*/
 void pic14_outAcc(operand *result)
 {
-    int size, offset;
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    int size,offset;
+    DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
+    DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
+
+
     size = pic14_getDataSize(result);
     if(size){
-        aopPut(AOP(result),"a",0);
+        emitpcode(POC_MOVWF,popGet(AOP(result),0));
         size--;
         offset = 1;
         /* unsigned or positive */
-        while(size--){
-            aopPut(AOP(result),zero,offset++);
-        }
+        while(size--)
+            emitpcode(POC_CLRF,popGet(AOP(result),offset++));
     }
+
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_outBitC - output a bit C                                        */
+/* pic14_outBitC - output a bit C                                  */
 /*-----------------------------------------------------------------*/
-void pic14_outBitC(operand *result)
+static void pic14_outBitC(operand *result)
 {
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* if the result is bit */
-    if (AOP_TYPE(result) == AOP_CRY) 
+    if (AOP_TYPE(result) == AOP_CRY)
         aopPut(AOP(result),"c",0);
     else {
         pic14_emitcode("clr","a  ; %d", __LINE__);
@@ -1543,23 +1490,30 @@ void pic14_outBitC(operand *result)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
+/* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
 /*-----------------------------------------------------------------*/
-void pic14_toBoolean(operand *oper)
+static void pic14_toBoolean(operand *oper)
 {
-    int size = AOP_SIZE(oper) - 1;
-    int offset = 1;
+    int size = AOP_SIZE(oper);
+    int offset = 0;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    if ( AOP_TYPE(oper) != AOP_ACC) {
-      emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
-      pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
+    assert (size > 0);
+
+    if (size == 1) {
+        /* MOVFW does not load the flags... */
+        emitpcode(POC_MOVLW, popGetLit(0));
+        offset = 0;
+    } else {
+        emitpcode(POC_MOVFW,popGet(AOP(oper),0));
+        offset = 1;
     }
-    while (size--) {
-      pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
-      emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
+
+    while (offset < size) {
+        emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
     }
+    /* Z is set iff (oper == 0) */
 }
 
 
@@ -1568,37 +1522,51 @@ void pic14_toBoolean(operand *oper)
 /*-----------------------------------------------------------------*/
 static void genNot (iCode *ic)
 {
-    symbol *tlbl;
-    sym_link *optype = operandType(IC_LEFT(ic));
+    //symbol *tlbl;
+    int size;
+
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* assign asmOps to operand & result */
     aopOp (IC_LEFT(ic),ic,FALSE);
     aopOp (IC_RESULT(ic),ic,TRUE);
 
+    DEBUGpic14_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) {
-      pic14_emitcode("movlw","1<<%s");
-      //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
-      //pic14_emitcode("cpl","c"); 
-      //pic14_outBitC(IC_RESULT(ic));
-      goto release;
-    }
-
-    /* if type float then do float */
-    if (IS_FLOAT(optype)) {
-        genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
+        if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+            emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
+            emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
+        } else {
+            emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
+            emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
+            emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
+        }
         goto release;
     }
 
-    pic14_toBoolean(IC_LEFT(ic));
+    size = AOP_SIZE(IC_LEFT(ic));
+    mov2w (AOP(IC_LEFT(ic)),0);
+    while (--size > 0)
+    {
+      if (op_isLitLike (IC_LEFT(ic)))
+        emitpcode (POC_IORLW, popGetAddr (AOP(IC_LEFT(ic)), size, 0));
+      else
+        emitpcode (POC_IORFW, popGet (AOP(IC_LEFT(ic)), size));
+    }
+    emitpcode(POC_MOVLW, popGetLit (0));
+    emitSKPNZ;
+    emitpcode(POC_MOVLW, popGetLit (1));
+    movwf(AOP(IC_RESULT(ic)), 0);
 
-    tlbl = newiTempLabel(NULL);
-    pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
-    pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-    pic14_outBitC(IC_RESULT(ic));
+    for (size = 1; size < AOP_SIZE(IC_RESULT(ic)); size++)
+    {
+      emitpcode(POC_CLRF, popGet (AOP(IC_RESULT(ic)), size));
+    }
+    goto release;
 
-release:    
+release:
     /* release the aops */
     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
@@ -1610,66 +1578,66 @@ release:
 /*-----------------------------------------------------------------*/
 static void genCpl (iCode *ic)
 {
-    int offset = 0;
-    int size ;
+    operand *left, *result;
+    int size, offset=0;
 
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* assign asmOps to operand & result */
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
+    aopOp((left = IC_LEFT(ic)),ic,FALSE);
+    aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
-    /* if both are in bit space then 
+    /* 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 ) { 
+    if (AOP_TYPE(result) == AOP_CRY &&
+        AOP_TYPE(left) == AOP_CRY ) {
 
-        pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
-        pic14_emitcode("cpl","c"); 
-        pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
-        goto release; 
-    } 
+        pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
+        pic14_emitcode("cpl","c");
+        pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
+        goto release;
+    }
 
-    size = AOP_SIZE(IC_RESULT(ic));
+    size = AOP_SIZE(result);
+    if (AOP_SIZE(left) < size) size = AOP_SIZE(left);
     while (size--) {
-        char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
-        MOVA(l);       
-        pic14_emitcode("cpl","a");
-        aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+        emitpcode(POC_COMFW,popGet(AOP(left),offset));
+        emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+        offset++;
     }
+    addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(result)));
 
 
 release:
     /* release the aops */
-    freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genUminusFloat - unary minus for floating points                */
 /*-----------------------------------------------------------------*/
-static void genUminusFloat(operand *op,operand *result)
+static void
+genUminusFloat(operand *op, operand *result)
 {
-    int size ,offset =0 ;
-    char *l;
+  int size;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* for this we just need to flip the 
-    first it then copy the rest in place */
-    size = AOP_SIZE(op) - 1;
-    l = aopGet(AOP(op),3,FALSE,FALSE);
+  FENTRY;
 
-    MOVA(l);    
+  DEBUGpic14_emitcode("; ***", "%s  %d", __FUNCTION__, __LINE__);
+  /* for this we just need to flip the
+     first it then copy the rest in place */
+  size = AOP_SIZE(op) - 1;
 
-    pic14_emitcode("cpl","acc.7");
-    aopPut(AOP(result),"a",3);    
+  mov2w_op(op, size);
+  emitpcode(POC_XORLW, popGetLit(0x80));
+  movwf(AOP(result), size);
 
-    while(size--) {
-        aopPut(AOP(result),
-               aopGet(AOP(op),offset,FALSE,FALSE),
-               offset);
-        offset++;
-    }          
+  while (size--)
+    {
+      mov2w_op(op, size);
+      movwf(AOP(result), size);
+    } // while
 }
 
 /*-----------------------------------------------------------------*/
@@ -1677,9 +1645,10 @@ static void genUminusFloat(operand *op,operand *result)
 /*-----------------------------------------------------------------*/
 static void genUminus (iCode *ic)
 {
-    int offset ,size ;
+    int size, i;
     sym_link *optype, *rtype;
 
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* assign asmops */
@@ -1689,13 +1658,14 @@ static void genUminus (iCode *ic)
     /* 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 ) {
 
-        pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
-        pic14_emitcode("cpl","c"); 
-        pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
-        goto release; 
-    } 
+        emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
+        emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
+        emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
+
+        goto release;
+    }
 
     optype = operandType(IC_LEFT(ic));
     rtype = operandType(IC_RESULT(ic));
@@ -1706,99 +1676,123 @@ static void genUminus (iCode *ic)
         goto release;
     }
 
-    /* otherwise subtract from zero */
+    /* otherwise subtract from zero by taking the 2's complement */
     size = AOP_SIZE(IC_LEFT(ic));
-    offset = 0 ;
-    CLRC ;
-    while(size--) {
-        char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
-        if (!strcmp(l,"a")) {
-            pic14_emitcode("cpl","a");
-            pic14_emitcode("inc","a");
-        } else {
-            pic14_emitcode("clr","a");
-            pic14_emitcode("subb","a,%s",l);
-        }       
-        aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+
+    for(i=0; i<size; i++) {
+        if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
+            emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
+        else {
+            emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
+            emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
+        }
     }
 
-    /* if any remaining bytes in the result */
-    /* we just need to propagate the sign   */
-    if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
-        pic14_emitcode("rlc","a");
-        pic14_emitcode("subb","a,acc");
-        while (size--) 
-            aopPut(AOP(IC_RESULT(ic)),"a",offset++);
-    }       
+    emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
+    for(i=1; i<size; i++) {
+        emitSKPNZ;
+        emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
+    }
 
 release:
     /* release the aops */
     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
+    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* saveRegisters - will look for a call and save the registers     */
+/* saverbank - saves an entire register bank on the stack          */
 /*-----------------------------------------------------------------*/
-static void saveRegisters(iCode *lic) 
+static void saverbank (int bank, iCode *ic, bool pushPsw)
 {
+    FENTRY;
+
+    DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
+#if 0
     int i;
+    asmop *aop ;
+    regs *r = NULL;
+
+    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    if (options.useXstack) {
+
+        aop = newAsmop(0);
+        r = getFreePtr(ic,&aop,FALSE);
+        pic14_emitcode("mov","%s,_spx",r->name);
+
+    }
+
+    for (i = 0 ; i < pic14_nRegs ;i++) {
+        if (options.useXstack) {
+            pic14_emitcode("inc","%s",r->name);
+            //pic14_emitcode("mov","a,(%s+%d)",
+            //       regspic14[i].base,8*bank+regspic14[i].offset);
+            pic14_emitcode("movx","@%s,a",r->name);
+        } else
+            pic14_emitcode("push","");// "(%s+%d)",
+        //regspic14[i].base,8*bank+regspic14[i].offset);
+    }
+
+    if (pushPsw) {
+        if (options.useXstack) {
+            pic14_emitcode("mov","a,psw");
+            pic14_emitcode("movx","@%s,a",r->name);
+            pic14_emitcode("inc","%s",r->name);
+            pic14_emitcode("mov","_spx,%s",r->name);
+            freeAsmop (NULL,aop,ic,TRUE);
+
+        } else
+            pic14_emitcode("push","psw");
+
+        pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
+    }
+    ic->bankSaved = 1;
+#endif
+}
+
+/*-----------------------------------------------------------------*/
+/* saveRegisters - will look for a call and save the registers     */
+/*-----------------------------------------------------------------*/
+static void saveRegisters(iCode *lic)
+{
     iCode *ic;
     bitVect *rsave;
-    sym_link *detype;
+    sym_link *dtype;
+
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* look for call */
-    for (ic = lic ; ic ; ic = ic->next) 
+    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 (!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 || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
-        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);
+            /* 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))
-           pic14_emitcode("mov","b,r0");
-       pic14_emitcode("mov","r0,%s",spname);
-       for (i = 0 ; i < pic14_nRegs ; i++) {
-           if (bitVectBitValue(rsave,i)) {
-               if (i == R0_IDX)
-                   pic14_emitcode("mov","a,b");
-               else
-                   pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
-               pic14_emitcode("movx","@r0,a");
-               pic14_emitcode("inc","r0");
-           }
-       }
-       pic14_emitcode("mov","%s,r0",spname);
-       if (bitVectBitValue(rsave,R0_IDX))
-           pic14_emitcode("mov","r0,b");           
-    } else
-       for (i = 0 ; i < pic14_nRegs ; i++) {
-           if (bitVectBitValue(rsave,i))
-               pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
-       }
-
-    detype = getSpec(operandType(IC_LEFT(ic)));
-    if (detype        && 
-        (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
-       IS_ISR(currFunc->etype) &&
-        !ic->bankSaved) 
-
-        saverbank(SPEC_BANK(detype),ic,TRUE);
+        ic->regsSaved = 1;
+
+        //fprintf(stderr, "ERROR: saveRegisters did not do anything to save registers, please report this as a bug.\n");
+
+        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);
 
 }
 /*-----------------------------------------------------------------*/
@@ -1809,124 +1803,91 @@ static void unsaveRegisters (iCode *ic)
     int i;
     bitVect *rsave;
 
+    FENTRY;
+
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* find the registers in use at this time 
+    /* find the registers in use at this time
     and push them away to safety */
     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
-                          ic->rUsed);
-    
+        ic->rUsed);
+
     if (options.useXstack) {
-       pic14_emitcode("mov","r0,%s",spname);   
-       for (i =  pic14_nRegs ; i >= 0 ; i--) {
-           if (bitVectBitValue(rsave,i)) {
-               pic14_emitcode("dec","r0");
-               pic14_emitcode("movx","a,@r0");
-               if (i == R0_IDX)
-                   pic14_emitcode("mov","b,a");
-               else
-                   pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
-           }       
+        pic14_emitcode("mov","r0,%s",spname);
+        for (i =  pic14_nRegs ; i >= 0 ; i--) {
+            if (bitVectBitValue(rsave,i)) {
+                pic14_emitcode("dec","r0");
+                pic14_emitcode("movx","a,@r0");
+                pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
+            }
 
-       }
-       pic14_emitcode("mov","%s,r0",spname);
-       if (bitVectBitValue(rsave,R0_IDX))
-           pic14_emitcode("mov","r0,b");
-    } else
-       for (i =  pic14_nRegs ; i >= 0 ; i--) {
-           if (bitVectBitValue(rsave,i))
-               pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
-       }
+        }
+        pic14_emitcode("mov","%s,r0",spname);
+    } //else
+    //for (i =  pic14_nRegs ; i >= 0 ; i--) {
+    //  if (bitVectBitValue(rsave,i))
+    //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
+    //}
 
-}  
+}
 
 
 /*-----------------------------------------------------------------*/
-/* pushSide -                                                     */
+/* pushSide -                */
 /*-----------------------------------------------------------------*/
 static void pushSide(operand * oper, int size)
 {
-       int offset = 0;
+#if 0
+    int offset = 0;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       while (size--) {
-               char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
-               if (AOP_TYPE(oper) != AOP_REG &&
-                   AOP_TYPE(oper) != AOP_DIR &&
-                   strcmp(l,"a") ) {
-                       pic14_emitcode("mov","a,%s",l);
-                       pic14_emitcode("push","acc");
-               } else
-                       pic14_emitcode("push","%s",l);
-       }
+    while (size--) {
+        char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
+        if (AOP_TYPE(oper) != AOP_REG &&
+            AOP_TYPE(oper) != AOP_DIR &&
+            strcmp(l,"a") ) {
+            pic14_emitcode("mov","a,%s",l);
+            pic14_emitcode("push","acc");
+        } else
+            pic14_emitcode("push","%s",l);
+    }
+#endif
 }
 
 /*-----------------------------------------------------------------*/
-/* assignResultValue -                                            */
+/* assignResultValue -               */
 /*-----------------------------------------------------------------*/
 static void assignResultValue(operand * oper)
 {
-       int offset = 0;
-       int size = AOP_SIZE(oper);
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    // The last byte in the assignment is in W
-    aopPut(AOP(oper),"W",size-1);
-
-    if(size>1) {
-      while (--size) {
-       aopPut(AOP(oper),fReturn[offset],offset);
-       offset++;
-
-      }
-    }
-}
-
+    int size = AOP_SIZE(oper);
+    int offset = 0;
 
-/*-----------------------------------------------------------------*/
-/* genXpush - pushes onto the external stack                       */
-/*-----------------------------------------------------------------*/
-static void genXpush (iCode *ic)
-{
-    asmop *aop = newAsmop(0);
-    regs *r ;
-    int size,offset = 0;
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    r = getFreePtr(ic,&aop,FALSE);
 
-    
-    pic14_emitcode("mov","%s,_spx",r->name);
-
-    size = AOP_SIZE(IC_LEFT(ic));
-    while(size--) {
-
-       char *l = aopGet(AOP(IC_LEFT(ic)),
-                        offset++,FALSE,FALSE); 
-       MOVA(l);            
-       pic14_emitcode("movx","@%s,a",r->name); 
-       pic14_emitcode("inc","%s",r->name);
+    DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
 
+    /* assign MSB first (passed via WREG) */
+    while (size--) {
+        get_returnvalue (oper, size, offset + GpsuedoStkPtr);
+        GpsuedoStkPtr++;
     }
-
-       
-    pic14_emitcode("mov","_spx,%s",r->name);
-
-    freeAsmop(NULL,aop,ic,TRUE);
-    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
 }
 
+
 /*-----------------------------------------------------------------*/
 /* genIpush - genrate code for pushing this gets a little complex  */
 /*-----------------------------------------------------------------*/
 static void genIpush (iCode *ic)
 {
+    FENTRY;
+
+    DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
+#if 0
     int size, offset = 0 ;
     char *l;
 
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* 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) {
 
@@ -1945,40 +1906,34 @@ static void genIpush (iCode *ic)
             }
             pic14_emitcode("push","%s",l);
         }
-        return ;        
+        return ;
     }
 
     /* this is a paramter push: in this case we call
     the routine to find the call and save those
-    registers that need to be saved */   
+    registers that need to be saved */
     saveRegisters(ic);
 
-    /* if use external stack then call the external
-    stack pushing routine */
-    if (options.useXstack) {
-        genXpush(ic);
-        return ;
-    }
-
     /* then do the push */
     aopOp(IC_LEFT(ic),ic,FALSE);
 
 
-       // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
+    // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
     size = AOP_SIZE(IC_LEFT(ic));
 
     while (size--) {
         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
-        if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
+        if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
             strcmp(l,"a") ) {
             pic14_emitcode("mov","a,%s",l);
             pic14_emitcode("push","acc");
         } else
             pic14_emitcode("push","%s",l);
-    }       
+    }
 
     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -1986,10 +1941,14 @@ static void genIpush (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genIpop (iCode *ic)
 {
+    FENTRY;
+
+    DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
+    assert (!"genIpop -- unimplemented");
+#if 0
     int size,offset ;
 
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* if the temp was not pushed then */
     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
         return ;
@@ -1997,11 +1956,12 @@ static void genIpop (iCode *ic)
     aopOp(IC_LEFT(ic),ic,FALSE);
     size = AOP_SIZE(IC_LEFT(ic));
     offset = (size-1);
-    while (size--) 
+    while (size--)
         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
-                                   FALSE,TRUE));
+        FALSE,TRUE));
 
     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -2009,90 +1969,49 @@ static void genIpop (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void unsaverbank (int bank,iCode *ic,bool popPsw)
 {
+    FENTRY;
+
+    DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
+#if 0
     int i;
     asmop *aop ;
     regs *r = NULL;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if (popPsw) {
-       if (options.useXstack) {
-           aop = newAsmop(0);
-           r = getFreePtr(ic,&aop,FALSE);
-           
-           
-           pic14_emitcode("mov","%s,_spx",r->name);
-           pic14_emitcode("movx","a,@%s",r->name);
-           pic14_emitcode("mov","psw,a");
-           pic14_emitcode("dec","%s",r->name);
-           
-       }else
-           pic14_emitcode ("pop","psw");
+        if (options.useXstack) {
+            aop = newAsmop(0);
+            r = getFreePtr(ic,&aop,FALSE);
+
+
+            pic14_emitcode("mov","%s,_spx",r->name);
+            pic14_emitcode("movx","a,@%s",r->name);
+            pic14_emitcode("mov","psw,a");
+            pic14_emitcode("dec","%s",r->name);
+
+        }else
+            pic14_emitcode ("pop","psw");
     }
 
     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
-        if (options.useXstack) {       
+        if (options.useXstack) {
             pic14_emitcode("movx","a,@%s",r->name);
             //pic14_emitcode("mov","(%s+%d),a",
-           //       regspic14[i].base,8*bank+regspic14[i].offset);
+            //     regspic14[i].base,8*bank+regspic14[i].offset);
             pic14_emitcode("dec","%s",r->name);
 
-        } else 
-         pic14_emitcode("pop",""); //"(%s+%d)",
-       //regspic14[i].base,8*bank); //+regspic14[i].offset);
+        } else
+            pic14_emitcode("pop",""); //"(%s+%d)",
+        //regspic14[i].base,8*bank); //+regspic14[i].offset);
     }
 
     if (options.useXstack) {
 
-       pic14_emitcode("mov","_spx,%s",r->name);
-       freeAsmop(NULL,aop,ic,TRUE);
-
-    } 
-}
-
-/*-----------------------------------------------------------------*/
-/* saverbank - saves an entire register bank on the stack          */
-/*-----------------------------------------------------------------*/
-static void saverbank (int bank, iCode *ic, bool pushPsw)
-{
-    int i;
-    asmop *aop ;
-    regs *r = NULL;
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if (options.useXstack) {
-
-       aop = newAsmop(0);
-       r = getFreePtr(ic,&aop,FALSE);  
-       pic14_emitcode("mov","%s,_spx",r->name);
-
-    }
+        pic14_emitcode("mov","_spx,%s",r->name);
+        freeAsmop(NULL,aop,ic,TRUE);
 
-    for (i = 0 ; i < pic14_nRegs ;i++) {
-        if (options.useXstack) {
-            pic14_emitcode("inc","%s",r->name);
-            //pic14_emitcode("mov","a,(%s+%d)",
-            //         regspic14[i].base,8*bank+regspic14[i].offset);
-            pic14_emitcode("movx","@%s,a",r->name);           
-        } else 
-         pic14_emitcode("push","");// "(%s+%d)",
-                     //regspic14[i].base,8*bank+regspic14[i].offset);
     }
-    
-    if (pushPsw) {
-       if (options.useXstack) {
-           pic14_emitcode("mov","a,psw");
-           pic14_emitcode("movx","@%s,a",r->name);     
-           pic14_emitcode("inc","%s",r->name);
-           pic14_emitcode("mov","_spx,%s",r->name);       
-           freeAsmop (NULL,aop,ic,TRUE);
-           
-       } else
-           pic14_emitcode("push","psw");
-       
-       pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
-    }
-    ic->bankSaved = 1;
-
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -2100,7 +2019,12 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
-    sym_link *detype;   
+    sym_link *dtype;
+    symbol *sym;
+    char *name;
+    int isExtern;
+
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -2108,96 +2032,118 @@ static void genCall (iCode *ic)
     if (!ic->regsSaved)
         saveRegisters(ic);
 
-    /* if we are calling a function that is not using
-    the same register bank then we need to save the
+        /* if we are calling a function that is not using
+        the same register bank then we need to save the
     destination registers on the stack */
-    detype = getSpec(operandType(IC_LEFT(ic)));
-    if (detype        && 
-        (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
-       IS_ISR(currFunc->etype) &&
-        !ic->bankSaved) 
+    dtype = operandType(IC_LEFT(ic));
+    if (currFunc && dtype &&
+        (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
+        IFFUNC_ISISR(currFunc->type) &&
+        !ic->bankSaved)
 
-        saverbank(SPEC_BANK(detype),ic,TRUE);
+        saverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
     /* if send set is not empty the assign */
     if (_G.sendSet) {
-       iCode *sic ;
-
-       for (sic = setFirstItem(_G.sendSet) ; sic ; 
-            sic = setNextItem(_G.sendSet)) {
-           int size, offset = 0;
-
-           aopOp(IC_LEFT(sic),sic,FALSE);
-           size = AOP_SIZE(IC_LEFT(sic));
-           while (size--) {
-               char *l = aopGet(AOP(IC_LEFT(sic)),offset,
-                               FALSE,FALSE);
-               DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
-
-               if (strcmp(l,fReturn[offset])) {
-
-                 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
-                      ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
-                   emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
-                 //pic14_emitcode("movlw","%s",l);
-                 else
-                   emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
-                 //pic14_emitcode("movf","%s,w",l);
-
-                 // The last one is passed in W
-                 if(size)
-                   pic14_emitcode("movwf","%s",fReturn[offset]);
-               }
-               offset++;
-           }
-           freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
-       }
-       _G.sendSet = NULL;
-    }
-    /* make the call */
-    emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
-                                       OP_SYMBOL(IC_LEFT(ic))->rname :
-                                       OP_SYMBOL(IC_LEFT(ic))->name));
+        iCode *sic;
+        /* For the Pic port, there is no data stack.
+        * So parameters passed to functions are stored
+        * in registers. (The pCode optimizer will get
+        * rid of most of these :).
+        */
+        int psuedoStkPtr=-1;
+        int firstTimeThruLoop = 1;
+
+        _G.sendSet = reverseSet(_G.sendSet);
+
+        /* First figure how many parameters are getting passed */
+        for (sic = setFirstItem(_G.sendSet) ; sic ;
+        sic = setNextItem(_G.sendSet)) {
+
+            aopOp(IC_LEFT(sic),sic,FALSE);
+            psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
+            freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
+        }
+
+        for (sic = setFirstItem(_G.sendSet) ; sic ;
+        sic = setNextItem(_G.sendSet)) {
+            int size, offset = 0;
+
+            aopOp(IC_LEFT(sic),sic,FALSE);
+            size = AOP_SIZE(IC_LEFT(sic));
 
-    pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
-                           OP_SYMBOL(IC_LEFT(ic))->rname :
-                           OP_SYMBOL(IC_LEFT(ic))->name));
+            while (size--) {
+                DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
+                    AopType(AOP_TYPE(IC_LEFT(sic))));
 
+                if(!firstTimeThruLoop) {
+                    /* If this is not the first time we've been through the loop
+                    * then we need to save the parameter in a temporary
+                    * register. The last byte of the last parameter is
+                    * passed in W. */
+                    emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
+
+                }
+                firstTimeThruLoop=0;
+
+                mov2w_op (IC_LEFT(sic),  offset);
+                offset++;
+            }
+            freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+        }
+        _G.sendSet = NULL;
+    }
+    /* make the call */
+    sym = OP_SYMBOL(IC_LEFT(ic));
+    name = sym->rname[0] ? sym->rname : sym->name;
+    /*
+     * As SDCC emits code as soon as it reaches the end of each
+     * function's definition, prototyped functions that are implemented
+     * after the current one are always considered EXTERN, which
+     * introduces many unneccessary PAGESEL instructions.
+     * XXX: Use a post pass to iterate over all `CALL _name' statements
+     * and insert `PAGESEL _name' and `PAGESEL $' around the CALL
+     * only iff there is no definition of the function in the whole
+     * file (might include this in the PAGESEL pass).
+     */
+    isExtern = IS_EXTERN(sym->etype) || pic14_inISR;
+    if (isExtern) {
+        /* Extern functions and ISRs maybe on a different page;
+         * must call pagesel */
+        emitpcode(POC_PAGESEL,popGetWithString(name,1));
+    }
+    emitpcode(POC_CALL,popGetWithString(name,isExtern));
+    if (isExtern) {
+        /* May have returned from a different page;
+         * must use pagesel to restore PCLATH before next
+         * goto or call instruction */
+        emitpcode(POC_PAGESEL,popGetWithString("$",0));
+    }
+    GpsuedoStkPtr=0;
     /* if we need assign a result value */
-    if ((IS_ITEMP(IC_RESULT(ic)) && 
-         (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
-          OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
+    if ((IS_ITEMP(IC_RESULT(ic)) &&
+        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+        OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
 
         _G.accInUse++;
         aopOp(IC_RESULT(ic),ic,FALSE);
         _G.accInUse--;
 
-       assignResultValue(IC_RESULT(ic));
-               
-        freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
-    }
+        assignResultValue(IC_RESULT(ic));
 
-    /* adjust the stack for parameters if 
-    required */
-    if (ic->parmBytes) {
-        int i;
-        if (ic->parmBytes > 3) {
-            pic14_emitcode("mov","a,%s",spname);
-            pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
-            pic14_emitcode("mov","%s,a",spname);
-        } else 
-            for ( i = 0 ; i <  ic->parmBytes ;i++)
-                pic14_emitcode("dec","%s",spname);
+        DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
+            AopType(AOP_TYPE(IC_RESULT(ic))));
 
+        freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
     }
 
     /* if register bank was saved then pop them */
     if (ic->bankSaved)
-        unsaverbank(SPEC_BANK(detype),ic,TRUE);
+        unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
     /* if we hade saved some registers then unsave them */
-    if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
+    if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
         unsaveRegisters (ic);
 
 
@@ -2208,107 +2154,95 @@ static void genCall (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genPcall (iCode *ic)
 {
-    sym_link *detype;
-    symbol *rlbl = newiTempLabel(NULL);
+    sym_link *dtype;
+    symbol *albl = newiTempLabel(NULL);
+    symbol *blbl = newiTempLabel(NULL);
+    PIC_OPCODE poc;
+    pCodeOp *pcop;
+    operand *left;
 
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* if caller saves & we have not saved then */
     if (!ic->regsSaved)
         saveRegisters(ic);
 
-    /* if we are calling a function that is not using
-    the same register bank then we need to save the
+        /* if we are calling a function that is not using
+        the same register bank then we need to save the
     destination registers on the stack */
-    detype = getSpec(operandType(IC_LEFT(ic)));
-    if (detype        && 
-       IS_ISR(currFunc->etype) &&
-        (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
-        saverbank(SPEC_BANK(detype),ic,TRUE);
-
-
-    /* push the return address on to the stack */
-    pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
-    pic14_emitcode("push","acc");    
-    pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
-    pic14_emitcode("push","acc");
-    
-    if (options.model == MODEL_FLAT24)
-    {
-       pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
-       pic14_emitcode("push","acc");    
-    }
+    dtype = operandType(IC_LEFT(ic));
+    if (currFunc && dtype &&
+        IFFUNC_ISISR(currFunc->type) &&
+        (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
+        saverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
-    /* now push the calling address */
-    aopOp(IC_LEFT(ic),ic,FALSE);
+    left = IC_LEFT(ic);
+    aopOp(left,ic,FALSE);
+    DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
 
-    pushSide(IC_LEFT(ic), FPTRSIZE);
+    poc = ( op_isLitLike (IC_LEFT(ic)) ? POC_MOVLW : POC_MOVFW );
 
-    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
+    pushSide(IC_LEFT(ic), FPTRSIZE);
 
-    /* if send set is not empty the assign */
+    /* if send set is not empty, assign parameters */
     if (_G.sendSet) {
-       iCode *sic ;
-
-       for (sic = setFirstItem(_G.sendSet) ; sic ; 
-            sic = setNextItem(_G.sendSet)) {
-           int size, offset = 0;
-           aopOp(IC_LEFT(sic),sic,FALSE);
-           size = AOP_SIZE(IC_LEFT(sic));
-           while (size--) {
-               char *l = aopGet(AOP(IC_LEFT(sic)),offset,
-                               FALSE,FALSE);
-               if (strcmp(l,fReturn[offset]))
-                   pic14_emitcode("mov","%s,%s",
-                            fReturn[offset],
-                            l);
-               offset++;
-           }
-           freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
-       }
-       _G.sendSet = NULL;
-    }
-
-    pic14_emitcode("ret","");
-    pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
 
+        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
+        /* no way to pass args - W always gets used to make the call */
+    }
+    /* first idea - factor out a common helper function and call it.
+    But don't know how to get it generated only once in its own block
 
-    /* if we need assign a result value */
+    if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
+        char *rname;
+        char *buffer;
+        rname = IC_LEFT(ic)->aop->aopu.aop_dir;
+        DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
+        buffer = Safe_calloc(1,strlen(rname)+16);
+        sprintf(buffer, "%s_goto_helper", rname);
+        addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
+        free(buffer);
+    }
+    */
+    emitpcode(POC_CALL,popGetLabel(albl->key));
+    pcop = popGetLabel(blbl->key);
+    emitpcode(POC_PAGESEL,pcop); /* Must restore PCLATH before goto, without destroying W */
+    emitpcode(POC_GOTO,pcop);
+    emitpLabel(albl->key);
+
+    emitpcode(poc,popGetAddr(AOP(left),1,0));
+    emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+    emitpcode(poc,popGetAddr(AOP(left),0,0));
+    emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+
+    emitpLabel(blbl->key);
+
+    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+
+    /* if we need to assign a result value */
     if ((IS_ITEMP(IC_RESULT(ic)) &&
-         (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
-          OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
+        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+        OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
 
         _G.accInUse++;
         aopOp(IC_RESULT(ic),ic,FALSE);
         _G.accInUse--;
-       
-       assignResultValue(IC_RESULT(ic));
 
-        freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-    }
+        GpsuedoStkPtr = 0;
 
-    /* adjust the stack for parameters if 
-    required */
-    if (ic->parmBytes) {
-        int i;
-        if (ic->parmBytes > 3) {
-            pic14_emitcode("mov","a,%s",spname);
-            pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
-            pic14_emitcode("mov","%s,a",spname);
-        } else 
-            for ( i = 0 ; i <  ic->parmBytes ;i++)
-                pic14_emitcode("dec","%s",spname);
+        assignResultValue(IC_RESULT(ic));
 
+        freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
     }
 
     /* if register bank was saved then unsave them */
-    if (detype        && 
-        (SPEC_BANK(currFunc->etype) != 
-         SPEC_BANK(detype)))
-        unsaverbank(SPEC_BANK(detype),ic,TRUE);
+    if (currFunc && dtype &&
+        (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
+        unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
-    /* if we hade saved some registers then
+        /* if we hade saved some registers then
     unsave them */
     if (ic->regsSaved)
         unsaveRegisters (ic);
@@ -2320,213 +2254,171 @@ static void genPcall (iCode *ic)
 /*-----------------------------------------------------------------*/
 static int resultRemat (iCode *ic)
 {
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    //  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    FENTRY;
+
     if (SKIP_IC(ic) || ic->op == IFX)
         return 0;
 
     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
-
-/*-----------------------------------------------------------------*/
-/* inExcludeList - return 1 if the string is in exclude Reg list   */
-/*-----------------------------------------------------------------*/
-static bool inExcludeList(char *s)
-{
-    int i =0;
-    
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if (options.excludeRegs[i] &&
-    STRCASECMP(options.excludeRegs[i],"none") == 0)
-       return FALSE ;
-
-    for ( i = 0 ; options.excludeRegs[i]; i++) {
-       if (options.excludeRegs[i] &&
-        STRCASECMP(s,options.excludeRegs[i]) == 0)
-           return TRUE;
-    }
-    return FALSE ;
-}
-
 /*-----------------------------------------------------------------*/
 /* genFunction - generated code for function entry                 */
 /*-----------------------------------------------------------------*/
 static void genFunction (iCode *ic)
 {
     symbol *sym;
-    sym_link *fetype;
+    sym_link *ftype;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    labelOffset += FUNCTION_LABEL_INC;
+    FENTRY;
 
+    DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
+
+    labelOffset += (max_key+4);
+    max_key=0;
+    GpsuedoStkPtr=0;
     _G.nRegsSaved = 0;
     /* create the function header */
     pic14_emitcode(";","-----------------------------------------");
     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
     pic14_emitcode(";","-----------------------------------------");
 
+    /* prevent this symbol from being emitted as 'extern' */
+    pic14_stringInSet(sym->rname, &pic14_localFunctions, 1);
+
     pic14_emitcode("","%s:",sym->rname);
-    addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
+    addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
 
-    fetype = getSpec(operandType(IC_LEFT(ic)));
+    /* mark symbol as NOT extern (even if it was declared so previously) */
+    assert(IS_SPEC(sym->etype));
+    SPEC_EXTR(sym->etype) = 0;
+    sym->cdef = 0;
+    if (!SPEC_OCLS(sym->etype)) SPEC_OCLS(sym->etype) = code;
+    addSetIfnotP(&SPEC_OCLS(sym->etype)->syms, sym);
+
+    ftype = operandType(IC_LEFT(ic));
 
     /* if critical function then turn interrupts off */
-    if (SPEC_CRTCL(fetype))
+    if (IFFUNC_ISCRITICAL(ftype))
         pic14_emitcode("clr","ea");
 
-    /* here we need to generate the equates for the
-       register bank if required */
+        /* here we need to generate the equates for the
+    register bank if required */
 #if 0
-    if (SPEC_BANK(fetype) != rbank) {
+    if (FUNC_REGBANK(ftype) != rbank) {
         int i ;
 
-        rbank = SPEC_BANK(fetype);
+        rbank = FUNC_REGBANK(ftype);
         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
             if (strcmp(regspic14[i].base,"0") == 0)
                 pic14_emitcode("","%s = 0x%02x",
-                         regspic14[i].dname,
-                         8*rbank+regspic14[i].offset);
+                regspic14[i].dname,
+                8*rbank+regspic14[i].offset);
             else
                 pic14_emitcode ("","%s = %s + 0x%02x",
-                          regspic14[i].dname,
-                          regspic14[i].base,
-                          8*rbank+regspic14[i].offset);
+                regspic14[i].dname,
+                regspic14[i].base,
+                8*rbank+regspic14[i].offset);
         }
     }
 #endif
 
-    /* if this is an interrupt service routine then
-    save acc, b, dpl, dph  */
-    if (IS_ISR(sym->etype)) {
-        
-       if (!inExcludeList("acc"))          
-           pic14_emitcode ("push","acc");      
-       if (!inExcludeList("b"))
-           pic14_emitcode ("push","b");
-       if (!inExcludeList("dpl"))
-           pic14_emitcode ("push","dpl");
-       if (!inExcludeList("dph"))
-           pic14_emitcode ("push","dph");
-       if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
-       {
-           pic14_emitcode ("push", "dpx");
-           /* Make sure we're using standard DPTR */
-           pic14_emitcode ("push", "dps");
-           pic14_emitcode ("mov", "dps, #0x00");
-           if (options.stack10bit)
-           {   
-               /* This ISR could conceivably use DPTR2. Better save it. */
-               pic14_emitcode ("push", "dpl1");
-               pic14_emitcode ("push", "dph1");
-               pic14_emitcode ("push", "dpx1");
-           }
-       }
-       /* if this isr has no bank i.e. is going to
-          run with bank 0 , then we need to save more
-          registers :-) */
-       if (!SPEC_BANK(sym->etype)) {
-
-           /* if this function does not call any other
-              function then we can be economical and
-              save only those registers that are used */
-           if (! sym->hasFcall) {
-               int i;
-
-               /* if any registers used */
-               if (sym->regsUsed) {
-                   /* save the registers used */
-                   for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-                       if (bitVectBitValue(sym->regsUsed,i) ||
-                          (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                           pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);                         
-                   }
-               }
-               
-           } else {
-               /* this function has  a function call cannot
-                  determines register usage so we will have the
-                  entire bank */
-               saverbank(0,ic,FALSE);
-           }       
-       }
+    /* if this is an interrupt service routine */
+    pic14_inISR = 0;
+    if (IFFUNC_ISISR(sym->type)) {
+        pic14_inISR = 1;
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
+        emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
+        /* XXX: Why? Does this assume that ssave and psave reside
+         * in a shared bank or bank0? We cannot guarantee the
+         * latter...
+         */
+        emitpcode(POC_CLRF,   popCopyReg(&pc_status));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
+        //emitpcode(POC_MOVWF,  popGetExternal("___sdcc_saved_status",1 ));
+        emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
+        /* during an interrupt PCLATH must be cleared before a goto or call statement */
+        emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
+        //emitpcode(POC_MOVWF,  popGetExternal("___sdcc_saved_pclath", 1));
+        emitpcode(POC_MOVFW,  popCopyReg(&pc_fsr));
+        emitpcode(POC_MOVWF,  popGetExternal("___sdcc_saved_fsr", 1));
+
+        pBlockConvert2ISR(pb);
+        pic14_hasInterrupt = 1;
     } else {
-       /* if callee-save to be used for this function
-          then save the registers being used in this function */
-       if (sym->calleeSave) {
-           int i;
-           
-           /* if any registers used */
-           if (sym->regsUsed) {
-               /* save the registers used */
-               for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-                   if (bitVectBitValue(sym->regsUsed,i) ||
-                      (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
-                       pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
-                       _G.nRegsSaved++;
-                   }
-               }
-           }
-       }
+    /* if callee-save to be used for this function
+        then save the registers being used in this function */
+        if (IFFUNC_CALLEESAVES(sym->type)) {
+            int i;
+
+            /* if any registers used */
+            if (sym->regsUsed) {
+                /* save the registers used */
+                for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+                    if (bitVectBitValue(sym->regsUsed,i)) {
+                        //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
+                        _G.nRegsSaved++;
+                    }
+                }
+            }
+        }
     }
 
     /* set the register bank to the desired value */
-    if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
+    if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
         pic14_emitcode("push","psw");
-        pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);   
+        pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
     }
 
-    if (IS_RENT(sym->etype) || options.stackAuto) {
+    if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
 
-       if (options.useXstack) {
-           pic14_emitcode("mov","r0,%s",spname);
-           pic14_emitcode("mov","a,_bp");
-           pic14_emitcode("movx","@r0,a");
-           pic14_emitcode("inc","%s",spname);
-       }
-       else
-       {
-           /* set up the stack */
-           pic14_emitcode ("push","_bp");     /* save the callers stack  */
-       }
-       pic14_emitcode ("mov","_bp,%s",spname);
+        if (options.useXstack) {
+            pic14_emitcode("mov","r0,%s",spname);
+            pic14_emitcode("mov","a,_bp");
+            pic14_emitcode("movx","@r0,a");
+            pic14_emitcode("inc","%s",spname);
+        }
+        else
+        {
+            /* set up the stack */
+            pic14_emitcode ("push","_bp");   /* save the callers stack  */
+        }
+        pic14_emitcode ("mov","_bp,%s",spname);
     }
 
     /* adjust the stack for the function */
     if (sym->stack) {
 
-       int i = sym->stack;
-       if (i > 256 ) 
-           werror(W_STACK_OVERFLOW,sym->name);
+        int i = sym->stack;
+        if (i > 256 )
+            werror(W_STACK_OVERFLOW,sym->name);
 
-       if (i > 3 && sym->recvSize < 4) {              
+        if (i > 3 && sym->recvSize < 4) {
 
-           pic14_emitcode ("mov","a,sp");
-           pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
-           pic14_emitcode ("mov","sp,a");
-          
-       }
-       else
-           while(i--)
-               pic14_emitcode("inc","sp");
+            pic14_emitcode ("mov","a,sp");
+            pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
+            pic14_emitcode ("mov","sp,a");
+
+        }
+        else
+            while(i--)
+                pic14_emitcode("inc","sp");
     }
 
-     if (sym->xstack) {
+    if (sym->xstack) {
 
-       pic14_emitcode ("mov","a,_spx");
-       pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
-       pic14_emitcode ("mov","_spx,a");
-    }    
+        pic14_emitcode ("mov","a,_spx");
+        pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
+        pic14_emitcode ("mov","_spx,a");
+    }
 
 }
 
@@ -2537,9 +2429,11 @@ static void genEndFunction (iCode *ic)
 {
     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
 
+    FENTRY;
+
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    if (IS_RENT(sym->etype) || options.stackAuto)
+    if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
     {
         pic14_emitcode ("mov","%s,_bp",spname);
     }
@@ -2547,138 +2441,109 @@ static void genEndFunction (iCode *ic)
     /* if use external stack but some variables were
     added to the local stack then decrement the
     local stack */
-    if (options.useXstack && sym->stack) {      
+    if (options.useXstack && sym->stack) {
         pic14_emitcode("mov","a,sp");
         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
         pic14_emitcode("mov","sp,a");
     }
 
 
-    if ((IS_RENT(sym->etype) || options.stackAuto)) {
-       if (options.useXstack) {
-           pic14_emitcode("mov","r0,%s",spname);
-           pic14_emitcode("movx","a,@r0");
-           pic14_emitcode("mov","_bp,a");
-           pic14_emitcode("dec","%s",spname);
-       }
-       else
-       {
-           pic14_emitcode ("pop","_bp");
-       }
+    if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
+        if (options.useXstack) {
+            pic14_emitcode("mov","r0,%s",spname);
+            pic14_emitcode("movx","a,@r0");
+            pic14_emitcode("mov","_bp,a");
+            pic14_emitcode("dec","%s",spname);
+        }
+        else
+        {
+            pic14_emitcode ("pop","_bp");
+        }
     }
 
-    /* restore the register bank  */    
-    if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
+    /* restore the register bank    */
+    if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
         pic14_emitcode ("pop","psw");
 
-    if (IS_ISR(sym->etype)) {
-
-       /* now we need to restore the registers */
-       /* if this isr has no bank i.e. is going to
-          run with bank 0 , then we need to save more
-          registers :-) */
-       if (!SPEC_BANK(sym->etype)) {
-           
-           /* if this function does not call any other
-              function then we can be economical and
-              save only those registers that are used */
-           if (! sym->hasFcall) {
-               int i;
-               
-               /* if any registers used */
-               if (sym->regsUsed) {
-                   /* save the registers used */
-                   for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
-                       if (bitVectBitValue(sym->regsUsed,i) ||
-                          (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                           pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
-                   }
-               }
-               
-           } else {
-               /* this function has  a function call cannot
-                  determines register usage so we will have the
-                  entire bank */
-               unsaverbank(0,ic,FALSE);
-           }       
-       }
-
-       if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
-       {
-           if (options.stack10bit)
-           {
-               pic14_emitcode ("pop", "dpx1");
-               pic14_emitcode ("pop", "dph1");
-               pic14_emitcode ("pop", "dpl1");
-           }   
-           pic14_emitcode ("pop", "dps");
-           pic14_emitcode ("pop", "dpx");
-       }
-       if (!inExcludeList("dph"))
-           pic14_emitcode ("pop","dph");
-       if (!inExcludeList("dpl"))
-           pic14_emitcode ("pop","dpl");
-       if (!inExcludeList("b"))
-           pic14_emitcode ("pop","b");
-       if (!inExcludeList("acc"))
-           pic14_emitcode ("pop","acc");
-
-        if (SPEC_CRTCL(sym->etype))
-            pic14_emitcode("setb","ea");
+    if (IFFUNC_ISISR(sym->type)) {
+
+        /* now we need to restore the registers */
+        /* if this isr has no bank i.e. is going to
+        run with bank 0 , then we need to save more
+registers :-) */
+        if (!FUNC_REGBANK(sym->type)) {
+
+        /* if this function does not call any other
+        function then we can be economical and
+            save only those registers that are used */
+            if (! IFFUNC_HASFCALL(sym->type)) {
+                int i;
+
+                /* if any registers used */
+                if (sym->regsUsed) {
+                    /* save the registers used */
+                    for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
+                        if (bitVectBitValue(sym->regsUsed,i)) {
+                            pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
+                        }
+                    }
+                }
+
+            } else {
+                /* this function has a function call; cannot
+                   determines register usage so we will have the
+                   entire bank */
+                unsaverbank(0,ic,FALSE);
+            }
+        }
+
+        /* if debug then send end of function */
+        if (options.debug && debugFile && currFunc) {
+            debugFile->writeEndFunction (currFunc, ic, 1);
+        }
 
-       /* if debug then send end of function */
-/*     if (options.debug && currFunc) { */
-       if (currFunc) {
-           _G.debugLine = 1;
-           pic14_emitcode(";","C$%s$%d$%d$%d ==.",
-                    FileBaseName(ic->filename),currFunc->lastLine,
-                    ic->level,ic->block); 
-           if (IS_STATIC(currFunc->etype))         
-               pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
-           else
-               pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
-           _G.debugLine = 0;
-       }
-       
-        pic14_emitcode ("reti","");
+        emitpcode(POC_MOVFW,  popGetExternal("___sdcc_saved_fsr", 1));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_fsr));
+        //emitpcode(POC_MOVFW,  popGetExternal("___sdcc_saved_pclath", 1));
+        emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
+        emitpcode(POC_CLRF,   popCopyReg(&pc_status)); // see genFunction
+        //emitpcode(POC_SWAPFW, popGetExternal("___sdcc_saved_status", 1));
+        emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
+        emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
+        emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
+        addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
+        emitpcodeNULLop(POC_RETFIE);
     }
     else {
-        if (SPEC_CRTCL(sym->etype))
+        if (IFFUNC_ISCRITICAL(sym->type))
             pic14_emitcode("setb","ea");
-       
-       if (sym->calleeSave) {
-           int i;
-           
-           /* if any registers used */
-           if (sym->regsUsed) {
-               /* save the registers used */
-               for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
-                   if (bitVectBitValue(sym->regsUsed,i) ||
-                      (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                       pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
-               }
-           }
-           
-       }
-
-       /* if debug then send end of function */
-       if (currFunc) {
-           _G.debugLine = 1;
-           pic14_emitcode(";","C$%s$%d$%d$%d ==.",
-                    FileBaseName(ic->filename),currFunc->lastLine,
-                    ic->level,ic->block); 
-           if (IS_STATIC(currFunc->etype))         
-               pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
-           else
-               pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
-           _G.debugLine = 0;
-       }
+
+        if (IFFUNC_CALLEESAVES(sym->type)) {
+            int i;
+
+            /* if any registers used */
+            if (sym->regsUsed) {
+                /* save the registers used */
+                for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
+                    if (bitVectBitValue(sym->regsUsed,i)) {
+                        pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
+                    }
+                }
+            }
+        }
+
+        /* if debug then send end of function */
+        if (options.debug && debugFile && currFunc) {
+            debugFile->writeEndFunction (currFunc, ic, 1);
+        }
 
         pic14_emitcode ("return","");
-       emitpcode(POC_RETURN,NULL);
+        emitpcodeNULLop(POC_RETURN);
 
-       /* Mark the end of a function */
-       addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
+        /* Mark the end of a function */
+        addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
     }
 
 }
@@ -2688,64 +2553,37 @@ static void genEndFunction (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genRet (iCode *ic)
 {
-    int size,offset = 0 , pushed = 0;
-    
+    int size,offset = 0;
+
+    FENTRY;
+
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* 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 */
+    just generate the "ret" */
+    if (!IC_LEFT(ic))
+        goto jumpret;
+
+        /* we have something to return then
+    move the return value into place */
     aopOp(IC_LEFT(ic),ic,FALSE);
     size = AOP_SIZE(IC_LEFT(ic));
-    
-    while (size--) {
-           char *l ;
-           if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
-                   /* #NOCHANGE */
-                   l = aopGet(AOP(IC_LEFT(ic)),offset++,
-                          FALSE,TRUE);
-                   pic14_emitcode("push","%s",l);
-                   pushed++;
-           } else {
-                   l = aopGet(AOP(IC_LEFT(ic)),offset,
-                              FALSE,FALSE);
-                   if (strcmp(fReturn[offset],l)) {
-                     if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
-                         ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
-                       pic14_emitcode("movlw","%s",l);
-                     else
-                       pic14_emitcode("movf","%s,w",l);
-                     if(size)
-                       pic14_emitcode("movwf","%s",fReturn[offset]);
-                     offset++;
-                   }
-           }
-    }    
-
-    if (pushed) {
-       while(pushed) {
-           pushed--;
-           if (strcmp(fReturn[pushed],"a"))
-               pic14_emitcode("pop",fReturn[pushed]);
-           else
-               pic14_emitcode("pop","acc");
-       }
+
+    for (offset = 0; offset < size; offset++)
+    {
+        pass_argument (IC_LEFT(ic), offset, size - 1 - offset);
     }
+
     freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
-    
- jumpret:
-       /* generate a jump to the return label
-          if the next is not the return statement */
+
+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)) {
-       
-       emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
-       pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
+        IC_LABEL(ic->next) == returnLabel)) {
+
+        emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
     }
-    
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -2753,12 +2591,14 @@ static void genRet (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genLabel (iCode *ic)
 {
+    FENTRY;
+
     /* special case never generate */
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if (IC_LABEL(ic) == entryLabel)
         return ;
 
-    emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
+    emitpLabel(IC_LABEL(ic)->key);
     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
 }
 
@@ -2768,50 +2608,30 @@ static void genLabel (iCode *ic)
 //tsd
 static void genGoto (iCode *ic)
 {
-  emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
-  pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
+    FENTRY;
+
+    emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
+    pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
 }
 
+
 /*-----------------------------------------------------------------*/
-/* findLabelBackwards: walks back through the iCode chain looking  */
-/* for the given label. Returns number of iCode instructions      */
-/* between that label and given ic.                               */
-/* Returns zero if label not found.                               */
+/* genMultbits :- multiplication of bits                           */
 /*-----------------------------------------------------------------*/
-#if 0
-static int findLabelBackwards(iCode *ic, int key)
+static void genMultbits (operand *left,
+                         operand *right,
+                         operand *result)
 {
-    int count = 0;
-    
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    while (ic->prev)
-    {
-        ic = ic->prev;
-        count++;
-        
-        if (ic->op == LABEL && IC_LABEL(ic)->key == key)
-        {
-            /* printf("findLabelBackwards = %d\n", count); */
-            return count;
-        }
-    }
-    
-    return 0;
-}
-#endif
 
-/*-----------------------------------------------------------------*/
-/* genMultbits :- multiplication of bits                           */
-/*-----------------------------------------------------------------*/
-static void genMultbits (operand *left, 
-                         operand *right, 
-                         operand *result)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    if(!pic14_sameRegs(AOP(result),AOP(right)))
+        emitpcode(POC_BSF,  popGet(AOP(result),0));
+
+    emitpcode(POC_BTFSC,popGet(AOP(right),0));
+    emitpcode(POC_BTFSS,popGet(AOP(left),0));
+    emitpcode(POC_BCF,  popGet(AOP(result),0));
 
-    pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-    pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
-    pic14_outBitC(result);
 }
 
 
@@ -2822,12 +2642,18 @@ static void genMultOneByte (operand *left,
                             operand *right,
                             operand *result)
 {
-    sym_link *opetype = operandType(result);
-    char *l ;
-    symbol *lbl ;
-    int size,offset;
+    char *func[] = { NULL, "__mulchar", "__mulint", NULL, "__mullong" };
+
+    // symbol *lbl ;
+    int size,offset,i;
+
+
+    FENTRY;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    DEBUGpic14_AopType(__LINE__,left,right,result);
+    DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
+
     /* (if two literals, the value is computed before) */
     /* if one literal, literal on the right */
     if (AOP_TYPE(left) == AOP_LIT){
@@ -2836,69 +2662,40 @@ static void genMultOneByte (operand *left,
         left = t;
     }
 
-    size = AOP_SIZE(result);
-    /* signed or unsigned */
-    pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
-    l = aopGet(AOP(left),0,FALSE,FALSE);
-    MOVA(l);       
-    pic14_emitcode("mul","ab");
-    /* if result size = 1, mul signed = mul unsigned */
-    aopPut(AOP(result),"a",0);
-    if (size > 1){
-        if (SPEC_USIGN(opetype)){
-            aopPut(AOP(result),"b",1);
-            if (size > 2)
-                /* for filling the MSBs */
-                pic14_emitcode("clr","a");
-        }
-        else{
-            pic14_emitcode("mov","a,b");
+    assert (AOP_SIZE(left) == AOP_SIZE(right));
 
-            /* adjust the MSB if left or right neg */
+    size = min(AOP_SIZE(result),AOP_SIZE(left));
+    offset = Gstack_base_addr - (2*size - 1);
 
-            /* if one literal */
-            if (AOP_TYPE(right) == AOP_LIT){
-                /* AND literal negative */
-                if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
-                    /* adjust MSB (c==0 after mul) */
-                    pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
-                }
-            }
-            else{
-                lbl = newiTempLabel(NULL);
-                pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
-                pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
-                pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-                pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
-                lbl = newiTempLabel(NULL);      
-                pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
-                pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
-                pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-            }
+    /* pass right operand as argument */
+    for (i=0; i < size; i++)
+    {
+        mov2w (AOP(right), i);
+        emitpcode(POC_MOVWF, popRegFromIdx (++offset));
+    } // for
 
-            lbl = newiTempLabel(NULL);
-            pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
-            pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-            pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            lbl = newiTempLabel(NULL);      
-            pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
-            pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
-            pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-
-            aopPut(AOP(result),"a",1);
-            if(size > 2){
-                /* get the sign */
-                pic14_emitcode("rlc","a");
-                pic14_emitcode("subb","a,acc");
-            }
-        }
-        size -= 2;   
-        offset = 2;
-        if (size > 0)
-            while (size--)
-                aopPut(AOP(result),"a",offset++);
-    }
+    /* pass left operand as argument */
+    for (i=0; i < size; i++)
+    {
+        mov2w (AOP(left), i);
+        if (i != size-1) emitpcode(POC_MOVWF, popRegFromIdx (++offset));
+    } // for
+    assert (offset == Gstack_base_addr);
+
+    /* call library routine */
+    assert (size > 0 && size <= 4);
+    call_libraryfunc (func[size]);
+
+    /* assign result */
+    movwf (AOP(result), size-1);
+    for (i=0; i < size - 1; i++)
+    {
+        emitpcode(POC_MOVFW, popRegFromIdx (Gstack_base_addr - i));
+        movwf (AOP(result), size - 2 - i);
+    } // for
+
+    /* now (zero-/sign) extend the result to its size */
+    addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(result)));
 }
 
 /*-----------------------------------------------------------------*/
@@ -2908,7 +2705,9 @@ 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;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* assign the amsops */
@@ -2916,6 +2715,8 @@ static void genMult (iCode *ic)
     aopOp (right,ic,FALSE);
     aopOp (result,ic,TRUE);
 
+    DEBUGpic14_AopType(__LINE__,left,right,result);
+
     /* special cases first */
     /* both are bits */
     if (AOP_TYPE(left) == AOP_CRY &&
@@ -2931,31 +2732,33 @@ static void genMult (iCode *ic)
         goto release ;
     }
 
-    /* should have been converted to function call */       
-    assert(1) ;
+    /* should have been converted to function call */
+    assert(0) ;
 
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genDivbits :- division of bits                                  */
 /*-----------------------------------------------------------------*/
-static void genDivbits (operand *left, 
-                        operand *right, 
+static void genDivbits (operand *left,
+                        operand *right,
                         operand *result)
 {
 
     char *l;
 
+    FENTRY;
+
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* the result must be bit */    
+    /* the result must be bit */
     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
     l = aopGet(AOP(left),0,FALSE,FALSE);
 
-    MOVA(l);    
+    MOVA(l);
 
     pic14_emitcode("div","ab");
     pic14_emitcode("rrc","a");
@@ -2969,92 +2772,98 @@ static void genDivOneByte (operand *left,
                            operand *right,
                            operand *result)
 {
-    sym_link *opetype = operandType(result);
-    char *l ;
-    symbol *lbl ;
-    int size,offset;
+    int size;
+    int sign;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    size = AOP_SIZE(result) - 1;
-    offset = 1;
-    /* signed or unsigned */
-    if (SPEC_USIGN(opetype)) {
-        /* unsigned is easy */
-        pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);        
-        pic14_emitcode("div","ab");
-        aopPut(AOP(result),"a",0);
-        while (size--)
-            aopPut(AOP(result),zero,offset++);
-        return ;
-    }
 
-    /* signed is a little bit more difficult */
+    assert (AOP_SIZE(right) == 1);
+    assert (AOP_SIZE(left) == 1);
 
-    /* save the signs of the operands */
-    l = aopGet(AOP(left),0,FALSE,FALSE);    
-    MOVA(l);    
-    pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
-    pic14_emitcode("push","acc"); /* save it on the stack */
+    size = min(AOP_SIZE(result),AOP_SIZE(left));
+    sign = !(SPEC_USIGN(operandType(left))
+        && SPEC_USIGN(operandType(right)));
 
-    /* now sign adjust for both left & right */
-    l =  aopGet(AOP(right),0,FALSE,FALSE);    
-    MOVA(l);       
-    lbl = newiTempLabel(NULL);
-    pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
-    pic14_emitcode("cpl","a");   
-    pic14_emitcode("inc","a");
-    pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-    pic14_emitcode("mov","b,a");
-
-    /* sign adjust left side */
-    l =  aopGet(AOP(left),0,FALSE,FALSE);    
-    MOVA(l);
+    if (AOP_TYPE(right) == AOP_LIT)
+    {
+        /* XXX: might add specialized code */
+    }
 
-    lbl = newiTempLabel(NULL);
-    pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
-    pic14_emitcode("cpl","a");
-    pic14_emitcode("inc","a");
-    pic14_emitcode("","%05d_DS_:",(lbl->key+100));
+    if (!sign)
+    {
+        /* unsigned division */
+    #if 1
+        mov2w(AOP(right),0);
+        emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+        mov2w(AOP(left),0);
+        call_libraryfunc("__divuchar");
+        movwf(AOP(result),0);
+    #else
+        pCodeOp *temp;
+        symbol *lbl;
+
+        temp = popGetTempReg();
+        lbl = newiTempLabel(NULL);
+
+        /* XXX: improve this naive approach:
+           [result] = [a] / [b]
+            ::= [result] = 0; while ([a] > [b]) do [a] -= [b]; [result]++ done
+
+           In PIC assembler:
+           movf  left,W
+           movwf temp       // temp <-- left
+           movf  right,W    // W <-- right
+           clrf  result
+           label1:
+           incf  result
+           subwf temp,F     // temp <-- temp - W
+           skipNC       // subwf clears CARRY (i.e. sets BORROW) if temp < W
+           goto  label1
+           decf result      // we just subtract once too often
+         */
 
-    /* now the division */
-    pic14_emitcode("div","ab");
-    /* we are interested in the lower order
-    only */
-    pic14_emitcode("mov","b,a");
-    lbl = newiTempLabel(NULL);
-    pic14_emitcode("pop","acc");   
-    /* if there was an over flow we don't 
-    adjust the sign of the result */
-    pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
-    pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
-    CLRC;
-    pic14_emitcode("clr","a");
-    pic14_emitcode("subb","a,b");
-    pic14_emitcode("mov","b,a");
-    pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-
-    /* now we are done */
-    aopPut(AOP(result),"b",0);
-    if(size > 0){
-        pic14_emitcode("mov","c,b.7");
-        pic14_emitcode("subb","a,acc");   
+        /* XXX: This loops endlessly on DIVIDE BY ZERO */
+        /* We need 1..128 iterations of the loop body (`4 / 5' .. `255 / 2'). */
+
+        mov2w(AOP(left),0);
+        emitpcode(POC_MOVWF, temp);
+        mov2w(AOP(right),0);
+        emitpcode(POC_CLRF, popGet(AOP(result),0));
+
+        emitpLabel(lbl->key);
+        emitpcode(POC_INCF, popGet(AOP(result),0));
+        emitpcode(POC_SUBWF, temp);
+        emitSKPNC;
+        emitpcode(POC_GOTO, popGetLabel(lbl->key));
+        emitpcode(POC_DECF, popGet(AOP(result),0));
+        popReleaseTempReg(temp);
+    #endif
+    }
+    else
+    {
+        /* signed division */
+        mov2w(AOP(right),0);
+        emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+        mov2w(AOP(left),0);
+        call_libraryfunc("__divschar");
+        movwf(AOP(result),0);
     }
-    while (size--)
-        aopPut(AOP(result),"a",offset++);
 
+    /* now performed the signed/unsigned division -- extend result */
+    addSign(result, 1, sign);
 }
 
 /*-----------------------------------------------------------------*/
-/* genDiv - generates code for division                            */
+/* genDiv - generates code for division                */
 /*-----------------------------------------------------------------*/
 static void genDiv (iCode *ic)
 {
     operand *left = IC_LEFT(ic);
     operand *right = IC_RIGHT(ic);
-    operand *result= IC_RESULT(ic);   
+    operand *result= IC_RESULT(ic);
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* assign the amsops */
     aopOp (left,ic,FALSE);
@@ -3077,33 +2886,11 @@ static void genDiv (iCode *ic)
     }
 
     /* should have been converted to function call */
-    assert(1);
+    assert(0);
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
-}
-
-/*-----------------------------------------------------------------*/
-/* genModbits :- modulus of bits                                   */
-/*-----------------------------------------------------------------*/
-static void genModbits (operand *left, 
-                        operand *right, 
-                        operand *result)
-{
-
-    char *l;
-
-    /* the result must be bit */    
-    pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    l = aopGet(AOP(left),0,FALSE,FALSE);
-
-    MOVA(l);       
-
-    pic14_emitcode("div","ab");
-    pic14_emitcode("mov","a,b");
-    pic14_emitcode("rrc","a");
-    aopPut(AOP(result),"c",0);
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3113,71 +2900,85 @@ static void genModOneByte (operand *left,
                            operand *right,
                            operand *result)
 {
-    sym_link *opetype = operandType(result);
-    char *l ;
-    symbol *lbl ;
+    int size;
+    int sign;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* signed or unsigned */
-    if (SPEC_USIGN(opetype)) {
-        /* unsigned is easy */
-        pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);    
-        pic14_emitcode("div","ab");
-        aopPut(AOP(result),"b",0);
-        return ;
-    }
-
-    /* signed is a little bit more difficult */
 
-    /* save the signs of the operands */
-    l = aopGet(AOP(left),0,FALSE,FALSE);    
-    MOVA(l);
+    assert (AOP_SIZE(right) == 1);
+    assert (AOP_SIZE(left) == 1);
 
-    pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    pic14_emitcode("push","acc"); /* save it on the stack */
+    size = min(AOP_SIZE(result),AOP_SIZE(left));
+    sign = !(SPEC_USIGN(operandType(left))
+        && SPEC_USIGN(operandType(right)));
 
-    /* now sign adjust for both left & right */
-    l =  aopGet(AOP(right),0,FALSE,FALSE);    
-    MOVA(l);
+    if (AOP_TYPE(right) == AOP_LIT)
+    {
+        /* XXX: might add specialized code */
+    }
 
-    lbl = newiTempLabel(NULL);
-    pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
-    pic14_emitcode("cpl","a");   
-    pic14_emitcode("inc","a");
-    pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-    pic14_emitcode("mov","b,a"); 
-
-    /* sign adjust left side */
-    l =  aopGet(AOP(left),0,FALSE,FALSE);    
-    MOVA(l);
+    if (!sign)
+    {
+        /* unsigned division */
+    #if 1
+        mov2w(AOP(right),0);
+        emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+        mov2w(AOP(left),0);
+        call_libraryfunc("__moduchar");
+        movwf(AOP(result),0);
+    #else
+        pCodeOp *temp;
+        symbol *lbl;
+
+        lbl = newiTempLabel(NULL);
+
+        assert(!pic14_sameRegs(AOP(right),AOP(result)));
+
+        /* XXX: improve this naive approach:
+           [result] = [a] % [b]
+            ::= [result] = [a]; while ([result] > [b]) do [result] -= [b]; done
+
+           In PIC assembler:
+           movf  left,W
+           movwf result     // result <-- left
+           movf  right,W    // W <-- right
+           label1:
+           subwf result,F   // result <-- result - W
+           skipNC       // subwf clears CARRY (i.e. sets BORROW) if result < W
+           goto  label1
+           addwf result, F  // we just subtract once too often
+         */
 
-    lbl = newiTempLabel(NULL);
-    pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
-    pic14_emitcode("cpl","a");   
-    pic14_emitcode("inc","a");
-    pic14_emitcode("","%05d_DS_:",(lbl->key+100));
+        /* XXX: This loops endlessly on DIVIDE BY ZERO */
+        /* We need 1..128 iterations of the loop body (`4 % 5' .. `255 % 2'). */
 
-    /* now the multiplication */
-    pic14_emitcode("div","ab");
-    /* we are interested in the lower order
-    only */
-    lbl = newiTempLabel(NULL);
-    pic14_emitcode("pop","acc");   
-    /* if there was an over flow we don't 
-    adjust the sign of the result */
-    pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
-    pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
-    CLRC ;
-    pic14_emitcode("clr","a");
-    pic14_emitcode("subb","a,b");
-    pic14_emitcode("mov","b,a");
-    pic14_emitcode("","%05d_DS_:",(lbl->key+100));
+        if (!pic14_sameRegs(AOP(left), AOP(result)))
+        {
+            mov2w(AOP(left),0);
+            emitpcode(POC_MOVWF, popGet(AOP(result),0));
+        }
+        mov2w(AOP(right),0);
 
-    /* now we are done */
-    aopPut(AOP(result),"b",0);
+        emitpLabel(lbl->key);
+        emitpcode(POC_SUBWF, popGet(AOP(result),0));
+        emitSKPNC;
+        emitpcode(POC_GOTO, popGetLabel(lbl->key));
+        emitpcode(POC_ADDWF, popGet(AOP(result),0));
+    #endif
+    }
+    else
+    {
+        /* signed division */
+        mov2w(AOP(right),0);
+        emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+        mov2w(AOP(left),0);
+        call_libraryfunc("__modschar");
+        movwf(AOP(result),0);
+    }
 
+    /* now we performed the signed/unsigned modulus -- extend result */
+    addSign(result, 1, sign);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3187,22 +2988,15 @@ static void genMod (iCode *ic)
 {
     operand *left = IC_LEFT(ic);
     operand *right = IC_RIGHT(ic);
-    operand *result= IC_RESULT(ic);  
+    operand *result= IC_RESULT(ic);
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* assign the amsops */
     aopOp (left,ic,FALSE);
     aopOp (right,ic,FALSE);
     aopOp (result,ic,TRUE);
 
-    /* special cases first */
-    /* both are bits */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        AOP_TYPE(right)== AOP_CRY) {
-        genModbits(left,right,result);
-        goto release ;
-    }
-
     /* if both are of size == 1 */
     if (AOP_SIZE(left) == 1 &&
         AOP_SIZE(right) == 1 ) {
@@ -3211,54 +3005,55 @@ static void genMod (iCode *ic)
     }
 
     /* should have been converted to function call */
-    assert(1);
+    assert(0);
 
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genIfxJump :- will create a jump depending on the ifx           */
 /*-----------------------------------------------------------------*/
 /*
-  note: May need to add parameter to indicate when a variable is in bit space.
+note: May need to add parameter to indicate when a variable is in bit space.
 */
 static void genIfxJump (iCode *ic, char *jval)
 {
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* 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)
-         emitSKPC;
-       else {
-         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
-         emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
-       }
+        if(strcmp(jval,"a") == 0)
+            emitSKPZ;
+        else if (strcmp(jval,"c") == 0)
+            emitSKPC;
+        else {
+            DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+            emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
+        }
 
-       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
-       pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
+        emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
+        pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
 
     }
     else {
         /* false label is present */
-       if(strcmp(jval,"a") == 0)
-         emitSKPNZ;
-       else if (strcmp(jval,"c") == 0)
-         emitSKPNC;
-       else {
-         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
-         emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
-       }
+        if(strcmp(jval,"a") == 0)
+            emitSKPNZ;
+        else if (strcmp(jval,"c") == 0)
+            emitSKPNC;
+        else {
+            DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+            emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
+        }
 
-       emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
-       pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
+        emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
+        pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
 
     }
 
@@ -3267,236 +3062,254 @@ static void genIfxJump (iCode *ic, char *jval)
     ic->generated = 1;
 }
 
-/*-----------------------------------------------------------------*/
-/* genSkip                                                         */
-/*-----------------------------------------------------------------*/
-static void genSkip(iCode *ifx,int status_bit)
-{
-  if(!ifx)
-    return;
-
-  if ( IC_TRUE(ifx) ) {
-    switch(status_bit) {
-    case 'z':
-      emitSKPNZ;
-      break;
-
-    case 'c':
-      emitSKPNC;
-      break;
-
-    case 'd':
-      emitSKPDC;
-      break;
-
-    }
-
-    emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-    pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-
-  } else {
-
-    switch(status_bit) {
-
-    case 'z':
-      emitSKPZ;
-      break;
-
-    case 'c':
-      emitSKPC;
-      break;
-
-    case 'd':
-      emitSKPDC;
-      break;
-    }
-    emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-    pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-
-  }
-
-}
-
 /*-----------------------------------------------------------------*/
 /* genSkipc                                                        */
 /*-----------------------------------------------------------------*/
-static void genSkipc(iCode *ifx, int condition)
+static void genSkipc(resolvedIfx *rifx)
 {
-  if(!ifx)
-    return;
-
-  if(condition)
-    emitSKPNC;
-  else
-    emitSKPC;
-
-  if ( IC_TRUE(ifx) )
-    emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-  else
-    emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
+    FENTRY;
+    if(!rifx)
+        return;
 
-  if ( IC_TRUE(ifx) )
-    pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-  else
-    pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+    if(rifx->condition)
+        emitSKPNC;
+    else
+        emitSKPC;
 
+    emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+    emitpComment ("%s:%u: created from rifx:%p", __FUNCTION__, __LINE__, rifx);
+    rifx->generated = 1;
 }
 
+#define isAOP_REGlike(x)  (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE)
+#define isAOP_LIT(x)      (AOP_TYPE(x) == AOP_LIT)
+#define DEBUGpc           emitpComment
+
 /*-----------------------------------------------------------------*/
-/* genSkipz                                                        */
+/* mov2w_regOrLit :- move to WREG either the offset's byte from    */
+/*                  aop (if it's NOT a literal) or from lit (if    */
+/*                  aop is a literal)                              */
 /*-----------------------------------------------------------------*/
-static void genSkipz(iCode *ifx, int condition)
+static void pic14_mov2w_regOrLit (asmop *aop, unsigned long lit, int offset)
 {
-  if(!ifx)
-    return;
-
-  if(condition)
-    emitSKPNZ;
-  else
-    emitSKPZ;
-
-  if ( IC_TRUE(ifx) )
-    emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-  else
-    emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-
-  if ( IC_TRUE(ifx) )
-    pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-  else
-    pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-
+  if (aop->type == AOP_LIT) {
+    emitpcode (POC_MOVLW, popGetLit((lit >> (offset*8)) & 0x00FF));
+  } else {
+    emitpcode (POC_MOVFW, popGet (aop, offset));
+  }
 }
-/*-----------------------------------------------------------------*/
-/* genCmp :- greater or less than comparison                       */
-/*-----------------------------------------------------------------*/
+
+/* genCmp performs a left < right comparison, stores
+ * the outcome in result (if != NULL) and generates
+ * control flow code for the ifx (if != NULL).
+ *
+ * This version leaves in sequences like
+ * "B[CS]F STATUS,0; BTFS[CS] STATUS,0"
+ * which should be optmized by the peephole
+ * optimizer - RN 2005-01-01 */
 static void genCmp (operand *left,operand *right,
                     operand *result, iCode *ifx, int sign)
 {
-  int size, offset = 0 ;
-  unsigned long lit = 0L,i = 0;
-
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  /* if left & right are bit variables */
-  if (AOP_TYPE(left) == AOP_CRY &&
-      AOP_TYPE(right) == AOP_CRY ) {
-    pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-    pic14_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 */
-    size = max(AOP_SIZE(left),AOP_SIZE(right));
-
-    /* if unsigned char cmp with lit, do cjne left,#right,zz */
-    if((size == 1) && !sign &&
-       (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
-      symbol *lbl  = newiTempLabel(NULL);
-      pic14_emitcode("cjne","%s,%s,%05d_DS_",
-              aopGet(AOP(left),offset,FALSE,FALSE),
-              aopGet(AOP(right),offset,FALSE,FALSE),
-              lbl->key+100);
-      pic14_emitcode("","%05d_DS_:",lbl->key+100);
-    } else {
+  resolvedIfx rIfx;
+  int size;
+  int offs;
+  symbol *templbl;
+  operand *dummy;
+  unsigned long lit;
+  unsigned long mask;
+  int performedLt;
+  int invert_result = 0;
+
+  FENTRY;
+
+  assert (AOP_SIZE(left) == AOP_SIZE(right));
+  assert (left && right);
+
+  size = AOP_SIZE(right) - 1;
+  mask = (0x100UL << (size*8)) - 1;
+  // in the end CARRY holds "left < right" (performedLt == 1) or "left >= right" (performedLt == 0)
+  performedLt = 1;
+  templbl = NULL;
+  lit = 0;
+
+  resolveIfx (&rIfx, ifx);
+
+  /**********************************************************************
+   * handle bits - bit compares are promoted to int compares seemingly! *
+   **********************************************************************/
+#if 0
+  // THIS IS COMPLETELY UNTESTED!
+  if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY) {
+    pCodeOp *pcleft = pic16_popGet(AOP(left), 0);
+    pCodeOp *pcright = pic16_popGet(AOP(right), 0);
+    assert (pcleft->type == PO_GPR_BIT && pcright->type == PO_GPR_BIT);
+
+    emitSETC;
+    // 1 < {0,1} is false --> clear C by skipping the next instruction
+    //pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (AOP(left),0), PCORB(pcleft)->bit);
+    pic16_emitpcode (POC_BTFSS, pic16_popGet (AOP(left), 0));
+    // {0,1} < 0 is false --> clear C by NOT skipping the next instruction
+    pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (pic16_popGet(AOP(right),0), PCORB(pcright)->bit));
+    emitCLRC; // only skipped for left=0 && right=1
+
+    goto correct_result_in_carry;
+  } // if
+#endif
 
-      if(AOP_TYPE(right) == AOP_LIT) {
-
-       DEBUGpic14_emitcode(";right lit","%d",sign);
-
-       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-       //default:
-       while(size--) {
-         i = (lit >> (size*8)) & 0xff;
-         if(i == 0) {
-           emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
-           pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
-           genSkipz(ifx,IC_TRUE(ifx) == NULL);
-         } else {
-           emitpcode(POC_MOVLW, popGetLit(i));
-           emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
-
-           pic14_emitcode("movlw","0x%x",i);
-           pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
-           genSkipc(ifx,IC_TRUE(ifx) == NULL);
-         }
-
-       }
-       ifx->generated = 1;
-       return;
+  /*************************************************
+   * make sure that left is register (or the like) *
+   *************************************************/
+  if (!isAOP_REGlike(left)) {
+    DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right));
+    assert (isAOP_LIT(left));
+    assert (isAOP_REGlike(right));
+    // swap left and right
+    // left < right <==> right > left <==> (right >= left + 1)
+    lit = ulFromVal(AOP(left)->aopu.aop_lit);
+
+    if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) {
+      // MAXVALUE < right? always false
+      if (performedLt) emitCLRC; else emitSETC;
+      goto correct_result_in_carry;
+    } // if
+
+    // This fails for lit = 0xFF (unsigned) AND lit = 0x7F (signed),
+    // 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, i.e. "right < left+1"
+  } else if (isAOP_LIT(right)) {
+    lit = ulFromVal(AOP(right)->aopu.aop_lit);
+  } // if
+
+  assert (isAOP_REGlike(left)); // left must be register or the like
+  assert (isAOP_REGlike(right) || isAOP_LIT(right)); // right may be register-like or a literal
+
+  /*************************************************
+   * special cases go here                         *
+   *************************************************/
+
+  if (isAOP_LIT(right)) {
+    if (!sign) {
+      // unsigned comparison to a literal
+      DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1);
+      if (lit == 0) {
+    // unsigned left < 0? always false
+    if (performedLt) emitCLRC; else emitSETC;
+    goto correct_result_in_carry;
       }
-      if(AOP_TYPE(left) == AOP_LIT) {
-
-       DEBUGpic14_emitcode(";left lit","%d",sign);
-
-       lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
-
-       //default:
-       while(size--) {
-         i = (lit >> (size*8)) & 0xff;
-         if(i == 0) {
-           emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
-           genSkipz(ifx,IC_TRUE(ifx) != NULL);
-         } else if( i == 1 ) {
-           emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
-           pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
-           genSkipz(ifx,IC_TRUE(ifx) != NULL);
-
-         } else {
-           emitpcode(POC_MOVLW, popGetLit(i));
-           emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
-
-           pic14_emitcode("movlw","0x%x",i);
-           pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
-           genSkipc(ifx,IC_TRUE(ifx) != NULL);
-         }
-       }
-       ifx->generated = 1;
-       return;
-      }
-
-
-      // CLRC;
-      DEBUGpic14_emitcode(";sign","%d",sign);
-
-      pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-      pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
-
-      emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
-      emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
-
-      size--;
-      while (size--) {
-
-       emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
-       emitSKPC;
-       emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
-       emitpcode(POC_SUBFW,   popGet(AOP(left),offset,FALSE,FALSE));
-
-/*
-       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-       emitSKPC;
-       pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-       pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-*/
-       offset++;
+    } else {
+      // signed comparison to a literal
+      DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask);
+      if ((lit & mask) == ((0x80 << (size*8)) & mask)) {
+    // 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;
+    emitpcode (POC_BTFSS, newpCodeOpBit (aopGet (AOP(left), size, FALSE, FALSE), 7, 0));
+    if (performedLt) emitCLRC; else emitSETC;
+    goto correct_result_in_carry;
       }
-    }
-  }
-
-  //release:
-  if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-    pic14_outBitC(result);
+    } // if (!sign)
+  } // right is literal
+
+  /*************************************************
+   * perform a general case comparison             *
+   * make sure we get CARRY==1 <==> left >= right  *
+   *************************************************/
+  // compare most significant bytes
+  //DEBUGpc ("comparing bytes at offset %d", size);
+  if (!sign) {
+    // unsigned comparison
+    pic14_mov2w_regOrLit (AOP(right), lit, size);
+    emitpcode (POC_SUBFW, popGet (AOP(left), size));
   } else {
-    /* if the result is used in the next
-       ifx conditional branch then generate
-       code a little differently */
-    if (ifx )
-      genIfxJump (ifx,"c");
-    else
-      pic14_outBitC(result);
-    /* leave the result in acc */
-  }
+    // signed comparison
+    // (add 2^n to both operands then perform an unsigned comparison)
+    if (isAOP_LIT(right)) {
+      // left >= LIT <-> LIT-left <= 0 <-> LIT-left == 0 OR !(LIT-left >= 0)
+      unsigned char litbyte = (lit >> (8*size)) & 0xFF;
+
+      if (litbyte == 0x80) {
+    // left >= 0x80 -- always true, but more bytes to come
+    mov2w (AOP(left), size);
+    emitpcode (POC_XORLW, popGetLit (0x80)); // set ZERO flag
+    emitSETC;
+      } else {
+    // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
+    mov2w (AOP(left), size);
+    emitpcode (POC_ADDLW, popGetLit (0x80));
+    emitpcode (POC_ADDLW, popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
+      } // if
+    } else {
+      pCodeOp *pctemp = popGetTempReg();
+      mov2w (AOP(left), size);
+      emitpcode (POC_ADDLW, popGetLit (0x80));
+      emitpcode (POC_MOVWF, pctemp);
+      mov2w (AOP(right), size);
+      emitpcode (POC_ADDLW, popGetLit (0x80));
+      emitpcode (POC_SUBFW, pctemp);
+      popReleaseTempReg(pctemp);
+    }
+  } // if (!sign)
+
+  // compare remaining bytes (treat as unsigned case from above)
+  templbl = newiTempLabel ( NULL );
+  offs = size;
+  while (offs--) {
+    //DEBUGpc ("comparing bytes at offset %d", offs);
+    emitSKPZ;
+    emitpcode (POC_GOTO, popGetLabel (templbl->key));
+    pic14_mov2w_regOrLit (AOP(right), lit, offs);
+    emitpcode (POC_SUBFW, popGet (AOP(left), offs));
+  } // while (offs)
+  emitpLabel (templbl->key);
+  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)                                *
+   ****************************************************/
+
+  if (performedLt) {
+    invert_result = 1;
+    // value will be used in the following genSkipc()
+    rIfx.condition ^= 1;
+  } // if
+
+correct_result_in_carry:
+
+  // assign result to variable (if neccessary)
+  if (result && AOP_TYPE(result) != AOP_CRY) {
+    //DEBUGpc ("assign result");
+    size = AOP_SIZE(result);
+    while (size--) {
+      emitpcode (POC_CLRF, popGet (AOP(result), size));
+    } // while
+    if (invert_result) {
+      emitSKPC;
+      emitpcode (POC_BSF, newpCodeOpBit (aopGet (AOP(result), 0, FALSE, FALSE), 0, 0));
+    } else {
+      emitpcode (POC_RLF, popGet (AOP(result), 0));
+    }
+  } // if (result)
 
+  // perform conditional jump
+  if (ifx) {
+    //DEBUGpc ("generate control flow");
+    genSkipc (&rIfx);
+    ifx->generated = 1;
+  } // if
 }
 
 /*-----------------------------------------------------------------*/
@@ -3508,6 +3321,7 @@ static void genCmpGt (iCode *ic, iCode *ifx)
     sym_link *letype , *retype;
     int sign ;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     left = IC_LEFT(ic);
     right= IC_RIGHT(ic);
@@ -3525,7 +3339,7 @@ static void genCmpGt (iCode *ic, iCode *ifx)
 
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3537,6 +3351,7 @@ static void genCmpLt (iCode *ic, iCode *ifx)
     sym_link *letype , *retype;
     int sign ;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     left = IC_LEFT(ic);
     right= IC_RIGHT(ic);
@@ -3555,462 +3370,127 @@ static void genCmpLt (iCode *ic, iCode *ifx)
 
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* gencjneshort - compare and jump if not equal                    */
+/* genCmpEq - generates code for equal to                          */
 /*-----------------------------------------------------------------*/
-static void gencjneshort(operand *left, operand *right, symbol *lbl)
+static void genCmpEq (iCode *ic, iCode *ifx)
 {
-    int size = max(AOP_SIZE(left),AOP_SIZE(right));
-    int offset = 0;
-    unsigned long lit = 0L;
+  operand *left, *right, *result;
+  int size;
+  symbol *false_label;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* 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);
+  FENTRY;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    /* if the right side is a literal then anything goes */
-    if (AOP_TYPE(right) == AOP_LIT &&
-        AOP_TYPE(left) != AOP_DIR ) {
-        while (size--) {
-         if(lit & 0xff) {
-           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-           pic14_emitcode("xorlw","0x%x",lit & 0xff);
-         } else
-           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-
-         emitSKPNZ;
-         pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
-         offset++;
-         lit >>= 8;
-        }
-    }
+  if(ifx)
+    DEBUGpic14_emitcode ("; ifx is non-null","");
+  else
+    DEBUGpic14_emitcode ("; ifx is null","");
 
-    /* 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))) {
-        while (size--) {
-         if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
-            ( (lit & 0xff) != 0)) {
-           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-           pic14_emitcode("xorlw","0x%x",lit & 0xff);
-           lit >>= 8;
-         } else
-           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-
-         emitSKPZ;
-         pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
-         offset++;
-/*
-            MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
-            if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
-               ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
-                pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
-            else
-                pic14_emitcode("cjne","a,%s,%05d_DS_",
-                         aopGet(AOP(right),offset,FALSE,TRUE),
-                         lbl->key+100);
-            offset++;
-*/
-        }
-    } else {
-        /* right is a pointer reg need both a & b */
-        while(size--) {
-            char *l = aopGet(AOP(left),offset,FALSE,FALSE);
-            if(strcmp(l,"b"))
-                pic14_emitcode("mov","b,%s",l);
-            MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-            pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
-            offset++;
-        }
-    }
-}
+  aopOp((left=IC_LEFT(ic)),ic,FALSE);
+  aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+  aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
-/*-----------------------------------------------------------------*/
-/* gencjne - compare and jump if not equal                         */
-/*-----------------------------------------------------------------*/
-static void gencjne(operand *left, operand *right, symbol *lbl)
-{
-    symbol *tlbl  = newiTempLabel(NULL);
+  DEBUGpic14_AopType(__LINE__,left,right,result);
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    gencjneshort(left, right, lbl);
+  /* if literal, move literal to right */
+  if (op_isLitLike (IC_LEFT(ic))) {
+    operand *tmp = right ;
+    right = left;
+    left = tmp;
+  }
 
-    pic14_emitcode("mov","a,%s",one);
-    pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
-    pic14_emitcode("","%05d_DS_:",lbl->key+100);
-    pic14_emitcode("clr","a");
-    pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-}
+  false_label = NULL;
+  if (ifx && !IC_TRUE(ifx))
+  {
+    assert (IC_FALSE(ifx));
+    false_label = IC_FALSE(ifx);
+  }
 
+  size = min(AOP_SIZE(left),AOP_SIZE(right));
+  assert(!pic14_sameRegs(AOP(result),AOP(left)));
+  assert(!pic14_sameRegs(AOP(result),AOP(right)));
 
-/*-----------------------------------------------------------------*/
-/* 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;
+  /* assume left != right */
+  {
+    int i;
+    for (i=0; i < AOP_SIZE(result); i++)
+    {
+      emitpcode(POC_CLRF, popGet(AOP(result),i));
+    }
+  }
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(ifx)
-      DEBUGpic14_emitcode ("; ifx is non-null","");
-    else
-      DEBUGpic14_emitcode ("; ifx is null","");
+  if (AOP_TYPE(right) == AOP_LIT)
+  {
+    unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
+    int i;
+    size = AOP_SIZE(left);
+    assert(!op_isLitLike(left));
 
-    aopOp((left=IC_LEFT(ic)),ic,FALSE);
-    aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,TRUE);
+    switch (lit)
+    {
+      case 0:
+        mov2w(AOP(left), 0);
+    for (i=1; i < size; i++)
+      emitpcode(POC_IORFW,popGet(AOP(left),i));
+    /* now Z is set iff `left == right' */
+    emitSKPZ;
+    if (!false_label) false_label = newiTempLabel(NULL);
+    emitpcode(POC_GOTO, popGetLabel(false_label->key));
+    break;
 
-    size = max(AOP_SIZE(left),AOP_SIZE(right));
+      default:
+    for (i=0; i < size; i++)
+    {
+      mov2w(AOP(left),i);
+      emitpcode(POC_XORLW, popGetLit(lit >> (8*i)));
+      /* now Z is cleared if `left != right' */
+      emitSKPZ;
+      if (!false_label) false_label = newiTempLabel(NULL);
+      emitpcode(POC_GOTO, popGetLabel(false_label->key));
+    } // for i
+    break;
+    } // switch (lit)
+  }
+  else
+  {
+    /* right is no literal */
+    int i;
 
-    /* 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))) {
-        operand *t = IC_RIGHT(ic);
-        IC_RIGHT(ic) = IC_LEFT(ic);
-        IC_LEFT(ic) = t;
-    }
+    for (i=0; i < size; i++)
+    {
+      mov2w(AOP(right),i);
+      emitpcode(POC_XORFW,popGet(AOP(left),i));
+      /* now Z is cleared if `left != right' */
+      emitSKPZ;
+      if (!false_label) false_label = newiTempLabel(NULL);
+      emitpcode(POC_GOTO, popGetLabel(false_label->key));
+    } // for i
+  }
 
-    if(ifx && !AOP_SIZE(result)){
-        symbol *tlbl;
-        /* if they are both bit variables */
-        if (AOP_TYPE(left) == AOP_CRY &&
-            ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
-            if(AOP_TYPE(right) == AOP_LIT){
-                unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
-                if(lit == 0L){
-                    pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-                    pic14_emitcode("cpl","c");
-                } else if(lit == 1L) {
-                    pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-                } else {
-                    pic14_emitcode("clr","c");
-                }
-                /* AOP_TYPE(right) == AOP_CRY */
-            } else {
-                symbol *lbl = newiTempLabel(NULL);
-                pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-                pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
-                pic14_emitcode("cpl","c");
-                pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-            }
-            /* if true label then we jump if condition
-            supplied is true */
-            tlbl = newiTempLabel(NULL);
-            if ( IC_TRUE(ifx) ) {
-                pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
-                pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
-            } else {
-                pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
-                pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
-            }
-            pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
-        } else {
+  /* if we reach here, left == right */
 
-         /* 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);
-           while (size--) {
-
-             if(size >= 1) {
-               int l = lit & 0xff;
-               int h = (lit>>8) & 0xff;
-               int optimized=0;
-
-               /* Check special cases for integers */
-               switch(lit & 0xffff) {
-               case 0x0000:
-                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0x0001:
-                 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0x0100:
-                 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0x00ff:
-                 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0xff00:
-                 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               default:
-                 if(h == 0) {
-                   emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-                   emitpcode(POC_XORLW,popGetLit(l));
-                   emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-
-                   pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                   pic14_emitcode("xorlw","0x%x",l);
-                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                   optimized++;
-                   genSkip(ifx,'z');
-                 } else if (l == 0) {
-                   emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                   emitpcode(POC_XORLW,popGetLit(h));
-                   emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
-
-                   pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                   pic14_emitcode("xorlw","0x%x",h);
-                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                   optimized++;
-                   genSkip(ifx,'z');
-                 } else {
-                   emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-                   emitpcode(POC_XORLW,popGetLit(l));
-                   emitpcode(POC_MOVLW,popGetLit(h));
-                   emitSKPNZ;
-                   emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-/*
-                   pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                   pic14_emitcode("xorlw","0x%x",l);
-                   pic14_emitcode("movlw","0x%x",h);
-                   emitSKPZ;
-                   pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-*/
-                   optimized++;
-                   genSkip(ifx,'z');
-                 }
-
-               }
-               if(optimized) {
-                 size--;
-                 offset+=2;
-                 lit>>=16;
-
-                 continue;
-               }
-                 
-             }
-               
-             switch(lit & 0xff) {
-             case 1:
-               if ( IC_TRUE(ifx) ) {
-
-                 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-
-                 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitSKPNZ;
-                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-
-                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-               } else {
-                 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-
-                 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-               }
-               break;
-             case 0xff:
-               if ( IC_TRUE(ifx) ) {
-                 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-
-                 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitSKPNZ;
-                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-
-                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-               } else {
-                 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-
-                 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-               }
-               break;
-             default:
-               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-               //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-               if(lit)
-                 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
-               //pic14_emitcode("xorlw","0x%x",lit & 0xff);
-               genSkip(ifx,'z');
-             }
-
-
-             //              pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
-             //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
-             offset++;
-             lit >>= 8;
-           }
-
-         } else if(AOP_TYPE(right) == AOP_CRY ) {
-           /* we know the left is not a bit, but that the right is */
-           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-           emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
-                     popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_XORLW,popGetLit(1));
-
-           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-           if ( IC_TRUE(ifx) )
-             pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                      AOP(right)->aopu.aop_dir,
-                      AOP(right)->aopu.aop_dir);
-           else
-             pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
-                      AOP(right)->aopu.aop_dir,
-                      AOP(right)->aopu.aop_dir);
-
-           pic14_emitcode("xorlw","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)
-             emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
-           //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-
-           if ( IC_TRUE(ifx) ) {
-             emitSKPNZ;
-             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-             pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-           } else {
-             emitSKPZ;
-             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-             pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-           }
-
-         } else {
-           /* They're both variables that are larger than bits */
-           int s = size;
-
-           tlbl = newiTempLabel(NULL);
-
-           while(size--) {
-             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-             emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
-
-             pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-             pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-
-             if ( IC_TRUE(ifx) ) {
-               if(size) {
-                 emitSKPZ;
-                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
-                 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
-               } else {
-                 emitSKPNZ;
-                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-               }
-             } else {
-               emitSKPZ;
-               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-             }
-             offset++;
-           }
-           if(s>1 && IC_TRUE(ifx)) {
-             emitpLabel(tlbl->key+100+labelOffset);
-             pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
-           }
-         }
-        }
-        /* mark the icode as generated */
-        ifx->generated = 1;
-        goto release ;
-    }
+  if (AOP_SIZE(result) > 0)
+  {
+    emitpcode(POC_INCF, popGet(AOP(result),0));
+  }
 
-    /* if they are both bit variables */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
-        if(AOP_TYPE(right) == AOP_LIT){
-            unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
-            if(lit == 0L){
-                pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-                pic14_emitcode("cpl","c");
-            } else if(lit == 1L) {
-                pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-            } else {
-                pic14_emitcode("clr","c");
-            }
-            /* AOP_TYPE(right) == AOP_CRY */
-        } else {
-            symbol *lbl = newiTempLabel(NULL);
-            pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-            pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
-            pic14_emitcode("cpl","c");
-            pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-        }
-        /* c = 1 if egal */
-        if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
-            pic14_outBitC(result);
-            goto release ;
-        }
-        if (ifx) {
-            genIfxJump (ifx,"c");
-            goto release ;
-        }
-        /* if the result is used in an arithmetic operation
-        then put the result in place */
-        pic14_outBitC(result);
-    } else {
-        gencjne(left,right,newiTempLabel(NULL));    
-        if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-            aopPut(AOP(result),"a",0);
-            goto release ;
-        }
-        if (ifx) {
-            genIfxJump (ifx,"a");
-            goto release ;
-        }
-        /* if the result is used in an arithmetic operation
-        then put the result in place */
-        if (AOP_TYPE(result) != AOP_CRY) 
-            pic14_outAcc(result);
-        /* leave the result in acc */
-    }
+  if (ifx && IC_TRUE(ifx))
+  {
+    emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
+  }
 
-release:
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);
+  if (false_label && (!ifx || IC_TRUE(ifx)))
+    emitpLabel(false_label->key);
+
+  if (ifx) ifx->generated = 1;
+
+  freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+  freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+  freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4018,6 +3498,7 @@ release:
 /*-----------------------------------------------------------------*/
 static iCode *ifxForOp ( operand *op, iCode *ic )
 {
+    FENTRY;
     /* if true symbol then needs to be assigned */
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if (IS_TRUE_SYMOP(op))
@@ -4032,6 +3513,28 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
         OP_SYMBOL(op)->liveTo <= ic->next->seq )
         return ic->next;
 
+    if (ic->next &&
+        ic->next->op == IFX &&
+        IC_COND(ic->next)->key == op->key) {
+        DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
+        return ic->next;
+    }
+
+    DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
+    if (ic->next &&
+        ic->next->op == IFX)
+        DEBUGpic14_emitcode ("; ic-next"," is an IFX");
+
+    if (ic->next &&
+        ic->next->op == IFX &&
+        IC_COND(ic->next)->key == op->key) {
+        DEBUGpic14_emitcode ("; "," key is okay");
+        DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
+            OP_SYMBOL(op)->liveTo,
+            ic->next->seq);
+    }
+
+
     return NULL;
 }
 /*-----------------------------------------------------------------*/
@@ -4040,8 +3543,9 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
 static void genAndOp (iCode *ic)
 {
     operand *left,*right, *result;
-    symbol *tlbl;
+    /*     symbol *tlbl; */
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* note here that && operations that are in an
     if statement are taken away by backPatchLabels
@@ -4050,20 +3554,26 @@ static void genAndOp (iCode *ic)
     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
     aopOp((result=IC_RESULT(ic)),ic,FALSE);
 
+    DEBUGpic14_AopType(__LINE__,left,right,result);
+
+    emitpcode(POC_MOVFW,popGet(AOP(left),0));
+    emitpcode(POC_ANDFW,popGet(AOP(right),0));
+    emitpcode(POC_MOVWF,popGet(AOP(result),0));
+
     /* if both are bit variables */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        AOP_TYPE(right) == AOP_CRY ) {
-        pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-        pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
-        pic14_outBitC(result);
-    } else {
-        tlbl = newiTempLabel(NULL);
-        pic14_toBoolean(left);    
-        pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
-        pic14_toBoolean(right);
-        pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-        pic14_outBitAcc(result);
-    }
+    /*     if (AOP_TYPE(left) == AOP_CRY && */
+    /*         AOP_TYPE(right) == AOP_CRY ) { */
+    /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
+    /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
+    /*         pic14_outBitC(result); */
+    /*     } else { */
+    /*         tlbl = newiTempLabel(NULL); */
+    /*         pic14_toBoolean(left);     */
+    /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
+    /*         pic14_toBoolean(right); */
+    /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
+    /*         pic14_outBitAcc(result); */
+    /*     } */
 
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
@@ -4075,49 +3585,45 @@ static void genAndOp (iCode *ic)
 /* genOrOp - for || operation                                      */
 /*-----------------------------------------------------------------*/
 /*
-  tsd pic port -
-  modified this code, but it doesn't appear to ever get called
+tsd pic port -
+modified this code, but it doesn't appear to ever get called
 */
 
 static void genOrOp (iCode *ic)
 {
     operand *left,*right, *result;
     symbol *tlbl;
+    int i;
 
     /* note here that || operations that are in an
     if statement are taken away by backPatchLabels
     only those used in arthmetic operations remain */
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     aopOp((left=IC_LEFT(ic)),ic,FALSE);
     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
     aopOp((result=IC_RESULT(ic)),ic,FALSE);
 
-    /* if both are bit variables */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        AOP_TYPE(right) == AOP_CRY ) {
-      pic14_emitcode("clrc","");
-      pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
-              AOP(left)->aopu.aop_dir,
-              AOP(left)->aopu.aop_dir);
-      pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-              AOP(right)->aopu.aop_dir,
-              AOP(right)->aopu.aop_dir);
-      pic14_emitcode("setc","");
+    DEBUGpic14_AopType(__LINE__,left,right,result);
 
-    } else {
-        tlbl = newiTempLabel(NULL);
-        pic14_toBoolean(left);
-       emitSKPZ;
-        pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
-        pic14_toBoolean(right);
-        pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
+    for (i=0; i < AOP_SIZE(result); i++)
+    {
+        emitpcode(POC_CLRF, popGet(AOP(result), i));
+    } // for i
 
-        pic14_outBitAcc(result);
-    }
+    tlbl = newiTempLabel(NULL);
+    pic14_toBoolean(left);
+    emitSKPZ;
+    emitpcode(POC_GOTO, popGetLabel(tlbl->key));
+    pic14_toBoolean(right);
+    emitpLabel(tlbl->key);
+    /* here Z is clear IFF `left || right' */
+    emitSKPZ;
+    emitpcode(POC_INCF, popGet(AOP(result), 0));
 
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);            
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4126,19 +3632,20 @@ static void genOrOp (iCode *ic)
 static int isLiteralBit(unsigned long lit)
 {
     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
-    0x100L,0x200L,0x400L,0x800L,
-    0x1000L,0x2000L,0x4000L,0x8000L,
-    0x10000L,0x20000L,0x40000L,0x80000L,
-    0x100000L,0x200000L,0x400000L,0x800000L,
-    0x1000000L,0x2000000L,0x4000000L,0x8000000L,
-    0x10000000L,0x20000000L,0x40000000L,0x80000000L};
+        0x100L,0x200L,0x400L,0x800L,
+        0x1000L,0x2000L,0x4000L,0x8000L,
+        0x10000L,0x20000L,0x40000L,0x80000L,
+        0x100000L,0x200000L,0x400000L,0x800000L,
+        0x1000000L,0x2000000L,0x4000000L,0x8000000L,
+        0x10000000L,0x20000000L,0x40000000L,0x80000000L};
     int idx;
-    
+
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     for(idx = 0; idx < 32; idx++)
         if(lit == pw[idx])
             return idx+1;
-    return 0;
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -4146,9 +3653,14 @@ static int isLiteralBit(unsigned long lit)
 /*-----------------------------------------------------------------*/
 static void continueIfTrue (iCode *ic)
 {
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if(IC_TRUE(ic))
-        pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
+    {
+        // Why +100?!?
+        emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
+        pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
+    }
     ic->generated = 1;
 }
 
@@ -4157,9 +3669,14 @@ static void continueIfTrue (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void jumpIfTrue (iCode *ic)
 {
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if(!IC_TRUE(ic))
+    {
+        // Why +100?!?
+        emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
+    }
     ic->generated = 1;
 }
 
@@ -4168,11 +3685,12 @@ static void jumpIfTrue (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
 {
+    FENTRY;
     // ugly but optimized by peephole
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if(IC_TRUE(ic)){
         symbol *nlbl = newiTempLabel(NULL);
-        pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
+        pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
@@ -4190,28 +3708,22 @@ 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;
-    //    char buffer[10];
+    resolvedIfx rIfx;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     aopOp((left = IC_LEFT(ic)),ic,FALSE);
     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
     aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
-#ifdef DEBUG_TYPE
-    pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
-             AOP_TYPE(result),
-             AOP_TYPE(left), AOP_TYPE(right));
-    pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
-             AOP_SIZE(result),
-             AOP_SIZE(left), AOP_SIZE(right));
-#endif
+    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)) {
+        AOP_NEEDSACC(left)) {
         operand *tmp = right ;
         right = left;
         left = tmp;
@@ -4232,10 +3744,12 @@ static void genAnd (iCode *ic, iCode *ifx)
         left = tmp;
     }
     if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+        lit = ulFromVal (AOP(right)->aopu.aop_lit);
 
     size = AOP_SIZE(result);
 
+    DEBUGpic14_AopType(__LINE__,left,right,result);
+
     // if(bit & yy)
     // result = bit & yy;
     if (AOP_TYPE(left) == AOP_CRY){
@@ -4277,41 +3791,39 @@ static void genAnd (iCode *ic, iCode *ifx)
             pic14_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  -
     // bit = val & 0xZZ     - size = 1, ifx = FALSE -
     if((AOP_TYPE(right) == AOP_LIT) &&
-       (AOP_TYPE(result) == AOP_CRY) &&
-       (AOP_TYPE(left) != AOP_CRY)){
+        (AOP_TYPE(result) == AOP_CRY) &&
+        (AOP_TYPE(left) != AOP_CRY)){
         int posbit = isLiteralBit(lit);
         /* left &  2^n */
         if(posbit){
-         posbit--;
-         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
+            posbit--;
+            //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
             // bit = left & 2^n
-         if(size)
-           pic14_emitcode("mov","c,acc.%d",posbit&0x07);
+            if(size)
+                pic14_emitcode("mov","c,acc.%d",posbit&0x07);
             // if(left &  2^n)
-         else{
-           if(ifx){
-             pCodeOp *pcorb = popGet(AOP(left),0,TRUE,FALSE);
-             PCORB(pcorb)->subtype = PCOP(pcorb)->type;
-             PCOP(pcorb)->type = PO_GPR_BIT;
-             PCORB(pcorb)->bit = posbit;
-             if(IC_TRUE(ifx)) {
-               emitpcode(POC_BTFSC, pcorb); 
-               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
-             } else {
-               emitpcode(POC_BTFSS, pcorb); 
-               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
-             }
-             ifx->generated = 1;
-           }
-           goto release;
-         }
+            else{
+                if(ifx){
+                    int offset = 0;
+                    while (posbit > 7) {
+                        posbit -= 8;
+                        offset++;
+                    }
+                    emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
+                        newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
+                    emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+
+                    ifx->generated = 1;
+                }
+                goto release;
+            }
         } else {
             symbol *tlbl = newiTempLabel(NULL);
             int sizel = AOP_SIZE(left);
@@ -4319,16 +3831,29 @@ static void genAnd (iCode *ic, iCode *ifx)
                 pic14_emitcode("setb","c");
             while(sizel--){
                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
-                    MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
+                    mov2w( AOP(left), offset);
                     // byte ==  2^n ?
-                    if((posbit = isLiteralBit(bytelit)) != 0)
+                    if((posbit = isLiteralBit(bytelit)) != 0) {
+                        emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round?
+                            newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0));
                         pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
+                    }
                     else{
+                        emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff));
+                        if (rIfx.condition) emitSKPZ;
+                        else emitSKPNZ;
+
                         if(bytelit != 0x0FFL)
+                        {
                             pic14_emitcode("anl","a,%s",
-                                     aopGet(AOP(right),offset,FALSE,TRUE));
+                            aopGet(AOP(right),offset,FALSE,TRUE));
+                        }
                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
                     }
+
+                    emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key));
+                    ifx->generated = 1;
+
                 }
                 offset++;
             }
@@ -4350,48 +3875,38 @@ static void genAnd (iCode *ic, iCode *ifx)
 
     /* if left is same as result */
     if(pic14_sameRegs(AOP(result),AOP(left))){
-      for(;size--; offset++,lit>>=8) {
-       if(AOP_TYPE(right) == AOP_LIT){
-         switch(lit & 0xff) {
-         case 0x00:
-           /*  and'ing with 0 has clears the result */
-           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-           emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
-           break;
-         case 0xff:
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF,popGet(AOP(right),offset,FALSE,FALSE));
-           break;
-
-         default:
-           {
-             int p = my_powof2( (~lit) & 0xff );
-             if(p>=0) {
-               /* only one bit is set in the literal, so use a bcf instruction */
-               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
-               emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
-             } else {
-               pic14_emitcode("movlw","0x%x", (lit & 0xff));
-               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
-               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-               emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
-             }
-           }    
-         }
-       } else {
-         if (AOP_TYPE(left) == AOP_ACC) {
-           pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
-
-         } else {                  
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
-
-         }
-       }
-      }
+        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 */
+                    emitpcode(POC_CLRF,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 = my_powof2( (~lit) & 0xff );
+                        if(p>=0) {
+                            /* only one bit is set in the literal, so use a bcf instruction */
+                            emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+
+                        } else {
+                            if(know_W != (int)(lit&0xff))
+                                emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+                            know_W = lit &0xff;
+                            emitpcode(POC_ANDWF,popGet(AOP(left),offset));
+                        }
+                    }
+                }
+            } else {
+                emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+                emitpcode(POC_ANDWF,popGet(AOP(left),offset));
+            }
+        }
 
     } else {
         // left & result in different registers
@@ -4406,7 +3921,7 @@ static void genAnd (iCode *ic, iCode *ifx)
             while(sizer--){
                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
                 pic14_emitcode("anl","a,%s",
-                         aopGet(AOP(left),offset,FALSE,FALSE));
+                    aopGet(AOP(left),offset,FALSE,FALSE));
                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
                 offset++;
             }
@@ -4417,59 +3932,38 @@ static void genAnd (iCode *ic, iCode *ifx)
             } 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:
-               pic14_emitcode("clrf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-               emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
-               break;
-             case 0xff:
-               pic14_emitcode("movf","%s,w",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-               break;
-             default:
-               pic14_emitcode("movlw","0x%x",t);
-               pic14_emitcode("andwf","%s,w",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-             
-               emitpcode(POC_MOVLW, popGetLit(t));
-               emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-             }
-             continue;
-           }
-
-           if (AOP_TYPE(left) == AOP_ACC) {
-             pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-             emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
-           } else {
-             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-             pic14_emitcode("andwf","%s,w",
-                      aopGet(AOP(left),offset,FALSE,FALSE));
-             emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
-             emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
-           }
-           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-         }
-       }
+            for(;(size--);offset++) {
+                // normal case
+                // result = left & right
+                if(AOP_TYPE(right) == AOP_LIT){
+                    int t = (lit >> (offset*8)) & 0x0FFL;
+                    switch(t) {
+                    case 0x00:
+                        emitpcode(POC_CLRF,popGet(AOP(result),offset));
+                        break;
+                    case 0xff:
+                        emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+                        emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+                        break;
+                    default:
+                        emitpcode(POC_MOVLW, popGetLit(t));
+                        emitpcode(POC_ANDFW,popGet(AOP(left),offset));
+                        emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+                    }
+                    continue;
+                }
+
+                emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+                emitpcode(POC_ANDFW,popGet(AOP(left),offset));
+                emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+            }
+        }
     }
 
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);     
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4481,16 +3975,18 @@ static void genOr (iCode *ic, iCode *ifx)
     int size, offset=0;
     unsigned long lit = 0L;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     aopOp((left = IC_LEFT(ic)),ic,FALSE);
     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
     aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
+    DEBUGpic14_AopType(__LINE__,left,right,result);
 
     /* 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)) {
+        AOP_NEEDSACC(left)) {
         operand *tmp = right ;
         right = left;
         left = tmp;
@@ -4511,8 +4007,10 @@ static void genOr (iCode *ic, iCode *ifx)
         left = tmp;
     }
 
+    DEBUGpic14_AopType(__LINE__,left,right,result);
+
     if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+        lit = ulFromVal (AOP(right)->aopu.aop_lit);
 
     size = AOP_SIZE(result);
 
@@ -4524,11 +4022,11 @@ static void genOr (iCode *ic, iCode *ifx)
             if(lit){
                 // lit != 0 => result = 1
                 if(AOP_TYPE(result) == AOP_CRY){
-                 if(size)
-                   emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
-                 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
-                 //     AOP(result)->aopu.aop_dir,
-                 //     AOP(result)->aopu.aop_dir);
+                    if(size)
+                        emitpcode(POC_BSF, popGet(AOP(result),0));
+                    //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
+                    //   AOP(result)->aopu.aop_dir,
+                    //   AOP(result)->aopu.aop_dir);
                     else if(ifx)
                         continueIfTrue(ifx);
                     goto release;
@@ -4541,50 +4039,39 @@ static void genOr (iCode *ic, iCode *ifx)
             }
         } else {
             if (AOP_TYPE(right) == AOP_CRY){
-             if(pic14_sameRegs(AOP(result),AOP(left))){
-                // c = bit | bit;
-               emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
-               emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
-               emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
-
-               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
-               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                        AOP(right)->aopu.aop_dir,
-                        AOP(right)->aopu.aop_dir);
-               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
-             } else {
-
-               emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
-               emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
-               emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
-               emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
-
-               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
-               pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
-                        AOP(right)->aopu.aop_dir,
-                        AOP(right)->aopu.aop_dir);
-               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                        AOP(left)->aopu.aop_dir,
-                        AOP(left)->aopu.aop_dir);
-               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
-             }
-            }
-            else{
+                if(pic14_sameRegs(AOP(result),AOP(left))){
+                    // c = bit | bit;
+                    emitpcode(POC_BCF,   popGet(AOP(result),0));
+                    emitpcode(POC_BTFSC, popGet(AOP(right),0));
+                    emitpcode(POC_BSF,   popGet(AOP(result),0));
+
+                    pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
+                        AOP(result)->aopu.aop_dir,
+                        AOP(result)->aopu.aop_dir);
+                    pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+                        AOP(right)->aopu.aop_dir,
+                        AOP(right)->aopu.aop_dir);
+                    pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
+                        AOP(result)->aopu.aop_dir,
+                        AOP(result)->aopu.aop_dir);
+                } else {
+                        emitpcode(POC_BCF,   popGet(AOP(result),0));
+                        emitpcode(POC_BTFSS, popGet(AOP(right),0));
+                        emitpcode(POC_BTFSC, popGet(AOP(left),0));
+                        emitpcode(POC_BSF,   popGet(AOP(result),0));
+                }
+            } else {
                 // c = bit | val;
                 symbol *tlbl = newiTempLabel(NULL);
                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
+
+                emitpcode(POC_BCF,   popGet(AOP(result),0));
+
                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
                     pic14_emitcode(";XXX setb","c");
                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
-                         AOP(left)->aopu.aop_dir,tlbl->key+100);
+                    AOP(left)->aopu.aop_dir,tlbl->key+100);
                 pic14_toBoolean(right);
                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
@@ -4602,25 +4089,25 @@ static void genOr (iCode *ic, iCode *ifx)
             pic14_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  -
     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
     if((AOP_TYPE(right) == AOP_LIT) &&
-       (AOP_TYPE(result) == AOP_CRY) &&
-       (AOP_TYPE(left) != AOP_CRY)){
+      (AOP_TYPE(result) == AOP_CRY) &&
+      (AOP_TYPE(left) != AOP_CRY)){
         if(lit){
-         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+            pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
             // result = 1
             if(size)
                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
-            else 
+            else
                 continueIfTrue(ifx);
             goto release;
         } else {
-         pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+            pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
             // lit = 0, result = boolean(left)
             if(size)
                 pic14_emitcode(";XXX setb","c");
@@ -4641,40 +4128,31 @@ static void genOr (iCode *ic, iCode *ifx)
 
     /* if left is same as result */
     if(pic14_sameRegs(AOP(result),AOP(left))){
-      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 = my_powof2(lit & 0xff);
-           if(p>=0) {
-             /* only one bit is set in the literal, so use a bsf instruction */
-             emitpcode(POC_BSF,   popGet(AOP(left),offset,FALSE,FALSE));
-             pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
-           } else {
-             emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-             emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
-
-             pic14_emitcode("movlw","0x%x", (lit & 0xff));
-             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
-           }
-                   
-         }
-       } else {
-         if (AOP_TYPE(left) == AOP_ACC) {
-           emitpcode(POC_IORFW,  popGet(AOP(right),offset,FALSE,FALSE));
-           pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-         } else {                  
-           emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_IORWF,  popGet(AOP(left),offset,FALSE,FALSE));
-
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-
-         }
-       }
-      }
+        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 = my_powof2(lit & 0xff);
+                    if(p>=0) {
+                        /* only one bit is set in the literal, so use a bsf instruction */
+                        emitpcode(POC_BSF,
+                            newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+                    } else {
+                        if(know_W != (int)(lit & 0xff))
+                            emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+                        know_W = lit & 0xff;
+                        emitpcode(POC_IORWF, popGet(AOP(left),offset));
+                    }
+
+                }
+            } else {
+                emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
+                emitpcode(POC_IORWF,  popGet(AOP(left),offset));
+            }
+        }
     } else {
         // left & result in different registers
         if(AOP_TYPE(result) == AOP_CRY){
@@ -4683,14 +4161,15 @@ static void genOr (iCode *ic, iCode *ifx)
             // if(!size && ifx), conditional oper: if(left | right)
             symbol *tlbl = newiTempLabel(NULL);
             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
-           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+            pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
 
             if(size)
                 pic14_emitcode(";XXX setb","c");
             while(sizer--){
                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
                 pic14_emitcode(";XXX orl","a,%s",
-                         aopGet(AOP(left),offset,FALSE,FALSE));
+                    aopGet(AOP(left),offset,FALSE,FALSE));
                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
                 offset++;
             }
@@ -4701,57 +4180,36 @@ static void genOr (iCode *ic, iCode *ifx)
             } 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:
-             emitpcode(POC_MOVFW,  popGet(AOP(left),offset,FALSE,FALSE));
-             emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
-
-             pic14_emitcode("movf","%s,w",
-                      aopGet(AOP(left),offset,FALSE,FALSE));
-             pic14_emitcode("movwf","%s",
-                      aopGet(AOP(result),offset,FALSE,FALSE));
-             break;
-           default:
-             emitpcode(POC_MOVLW,  popGetLit(t));
-             emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
-             emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
-
-             pic14_emitcode("movlw","0x%x",t);
-             pic14_emitcode("iorwf","%s,w",
-                      aopGet(AOP(left),offset,FALSE,FALSE));
-             pic14_emitcode("movwf","%s",
-                      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) {
-           emitpcode(POC_IORWF,  popGet(AOP(right),offset,FALSE,FALSE));
-           pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-         } else {
-           emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
-
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           pic14_emitcode("iorwf","%s,w",
-                    aopGet(AOP(left),offset,FALSE,FALSE));
-         }
-         emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
-         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-       }
+            // normal case
+            // result = left | right
+            if(AOP_TYPE(right) == AOP_LIT){
+                int t = (lit >> (offset*8)) & 0x0FFL;
+                switch(t) {
+                case 0x00:
+                    emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
+                    emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
+
+                    break;
+                default:
+                    emitpcode(POC_MOVLW,  popGetLit(t));
+                    emitpcode(POC_IORFW,  popGet(AOP(left),offset));
+                    emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
+                }
+                continue;
+            }
+
+            // faster than result <- left, anl result,right
+            // and better if result is SFR
+            emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+            emitpcode(POC_IORFW,popGet(AOP(left),offset));
+            emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
+        }
     }
 
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);     
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4763,6 +4221,7 @@ static void genXor (iCode *ic, iCode *ifx)
     int size, offset=0;
     unsigned long lit = 0L;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     aopOp((left = IC_LEFT(ic)),ic,FALSE);
@@ -4770,9 +4229,9 @@ static void genXor (iCode *ic, iCode *ifx)
     aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
     /* if left is a literal & right is not ||
-       if left needs acc & right does 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))) {
+        (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
         operand *tmp = right ;
         right = left;
         left = tmp;
@@ -4793,7 +4252,7 @@ static void genXor (iCode *ic, iCode *ifx)
         left = tmp;
     }
     if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+        lit = ulFromVal (AOP(right)->aopu.aop_lit);
 
     size = AOP_SIZE(result);
 
@@ -4806,7 +4265,8 @@ static void genXor (iCode *ic, iCode *ifx)
                 // lit>>1  != 0 => result = 1
                 if(AOP_TYPE(result) == AOP_CRY){
                     if(size)
-                        pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
+                    {emitpcode(POC_BSF,  popGet(AOP(result),offset));
+                    pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
                     else if(ifx)
                         continueIfTrue(ifx);
                     goto release;
@@ -4822,9 +4282,12 @@ static void genXor (iCode *ic, iCode *ifx)
                 } else{
                     // lit == 1, result = not(left)
                     if(size && pic14_sameRegs(AOP(result),AOP(left))){
+                        emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
+                        emitpcode(POC_XORWF,  popGet(AOP(result),offset));
                         pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
                         goto release;
                     } else {
+                        assert ( !"incomplete genXor" );
                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
                         pic14_emitcode("cpl","c");
                     }
@@ -4849,7 +4312,7 @@ static void genXor (iCode *ic, iCode *ifx)
                         // test the msb of the lsb
                         pic14_emitcode("anl","a,#0xfe");
                     pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
-                   sizer--;
+                    sizer--;
                 }
                 // val = (0,1)
                 pic14_emitcode("rrc","a");
@@ -4864,7 +4327,7 @@ static void genXor (iCode *ic, iCode *ifx)
             pic14_outBitC(result);
         // if(bit | ...)
         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-            genIfxJump(ifx, "c");           
+            genIfxJump(ifx, "c");
         goto release ;
     }
 
@@ -4872,33 +4335,16 @@ static void genXor (iCode *ic, iCode *ifx)
         /* if left is same as result */
         for(;size--; offset++) {
             if(AOP_TYPE(right) == AOP_LIT){
-             int t  = (lit >> (offset*8)) & 0x0FFL;
+                int t  = (lit >> (offset*8)) & 0x0FFL;
                 if(t == 0x00L)
                     continue;
-                else
-                   if (IS_AOP_PREG(left)) {
-                       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                       pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                       aopPut(AOP(result),"a",offset);
-                   } else {
-                     emitpcode(POC_MOVLW, popGetLit(t));
-                     emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
-                     pic14_emitcode("xrl","%s,%s",
-                                    aopGet(AOP(left),offset,FALSE,TRUE),
-                                    aopGet(AOP(right),offset,FALSE,FALSE));
-                   }
+                else {
+                        emitpcode(POC_MOVLW, popGetLit(t));
+                        emitpcode(POC_XORWF,popGet(AOP(left),offset));
+                }
             } else {
-               if (AOP_TYPE(left) == AOP_ACC)
-                   pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
-               else {
-                   MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                   if (IS_AOP_PREG(left)) {
-                       pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                       aopPut(AOP(result),"a",offset);
-                   } else
-                       pic14_emitcode("xrl","%s,a",
-                                aopGet(AOP(left),offset,FALSE,TRUE));
-               }
+                emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+                emitpcode(POC_XORWF,popGet(AOP(left),offset));
             }
         }
     } else {
@@ -4913,12 +4359,12 @@ static void genXor (iCode *ic, iCode *ifx)
                 pic14_emitcode("setb","c");
             while(sizer--){
                 if((AOP_TYPE(right) == AOP_LIT) &&
-                   (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
+                    (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
                     MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
                 } else {
                     MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
                     pic14_emitcode("xrl","a,%s",
-                             aopGet(AOP(left),offset,FALSE,FALSE));
+                        aopGet(AOP(left),offset,FALSE,FALSE));
                 }
                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
                 offset++;
@@ -4933,60 +4379,36 @@ static void genXor (iCode *ic, iCode *ifx)
             // normal case
             // result = left & right
             if(AOP_TYPE(right) == AOP_LIT){
-             int t = (lit >> (offset*8)) & 0x0FFL;
-             switch(t) { 
-             case 0x00:
-               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-               pic14_emitcode("movf","%s,w",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-               break;
-             case 0xff:
-               emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-               pic14_emitcode("comf","%s,w",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-               break;
-             default:
-               emitpcode(POC_MOVLW, popGetLit(t));
-               emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-               pic14_emitcode("movlw","0x%x",t);
-               pic14_emitcode("xorwf","%s,w",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-
-             }
-             continue;
+                int t = (lit >> (offset*8)) & 0x0FFL;
+                switch(t) {
+                case 0x00:
+                    emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+                    emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+                    break;
+                case 0xff:
+                    emitpcode(POC_COMFW,popGet(AOP(left),offset));
+                    emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+                    break;
+                default:
+                    emitpcode(POC_MOVLW, popGetLit(t));
+                    emitpcode(POC_XORFW,popGet(AOP(left),offset));
+                    emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+                }
+                continue;
             }
 
             // faster than result <- left, anl result,right
             // and better if result is SFR
-           if (AOP_TYPE(left) == AOP_ACC) {
-               emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
-               pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           } else {
-               emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
-               emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-               pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-           }
-           if ( AOP_TYPE(result) != AOP_ACC){
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-             pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-           }
+            emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+            emitpcode(POC_XORFW,popGet(AOP(left),offset));
+            emitpcode(POC_MOVWF,popGet(AOP(result),offset));
         }
     }
 
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);     
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4994,36 +4416,56 @@ release :
 /*-----------------------------------------------------------------*/
 static void genInline (iCode *ic)
 {
-    char *buffer, *bp, *bp1;
-    
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  char *buffer, *bp, *bp1;
+  bool inComment = FALSE;
 
-    _G.inLine += (!options.asmpeep);
+  FENTRY;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
-    strcpy(buffer,IC_INLINE(ic));
+  _G.inLine += (!options.asmpeep);
 
-    /* emit each line as a code */
-    while (*bp) {
-        if (*bp == '\n') {
-            *bp++ = '\0';
-            pic14_emitcode(bp1,"");
-            bp1 = bp;
-        } else {
-            if (*bp == ':') {
-                bp++;
-                *bp = '\0';
-                bp++;
-                pic14_emitcode(bp1,"");
-                bp1 = bp;
-            } else
-                bp++;
+  buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
+
+  while (*bp)
+    {
+      switch (*bp)
+        {
+        case ';':
+          inComment = TRUE;
+          ++bp;
+          break;
+
+        case '\n':
+          inComment = FALSE;
+          *bp++ = '\0';
+          if (*bp1)
+            addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+          bp1 = bp;
+          break;
+
+        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 */
+              addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process
+              bp1 = bp;
+            }
+          else
+            ++bp;
+          break;
         }
     }
-    if (bp1 != bp)
-        pic14_emitcode(bp1,"");
-    /*     pic14_emitcode("",buffer); */
-    _G.inLine -= (!options.asmpeep);
+  if ((bp1 != bp) && *bp1)
+    addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+
+  Safe_free (buffer);
+
+  _G.inLine -= (!options.asmpeep);
 }
 
 /*-----------------------------------------------------------------*/
@@ -5032,34 +4474,38 @@ static void genInline (iCode *ic)
 static void genRRC (iCode *ic)
 {
     operand *left , *result ;
-    int size, offset = 0;
-    char *l;    
+    int size, offset = 0, same;
 
+    FENTRY;
     /* rotate right with carry */
     left = IC_LEFT(ic);
     result=IC_RESULT(ic);
     aopOp (left,ic,FALSE);
     aopOp (result,ic,FALSE);
 
-    /* move it to the result */
-    size = AOP_SIZE(result);    
-    offset = size - 1 ;
-    CLRC;
-    while (size--) {
-        l = aopGet(AOP(left),offset,FALSE,FALSE);
-        MOVA(l);
-        pic14_emitcode("rrc","a");
-        if (AOP_SIZE(result) > 1)
-            aopPut(AOP(result),"a",offset--);
-    }
-    /* now we need to put the carry into the
-    highest order byte of the result */
-    if (AOP_SIZE(result) > 1) {
-        l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
-        MOVA(l);
-    }
-    pic14_emitcode("mov","acc.7,c");
-    aopPut(AOP(result),"a",AOP_SIZE(result)-1);
+    DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+    same = pic14_sameRegs(AOP(result),AOP(left));
+
+    size = AOP_SIZE(result);
+
+    /* get the lsb and put it into the carry */
+    emitpcode(POC_RRFW, popGet(AOP(left),size-1));
+
+    offset = 0 ;
+
+    while(size--) {
+
+        if(same) {
+            emitpcode(POC_RRF, popGet(AOP(left),offset));
+        } else {
+            emitpcode(POC_RRFW, popGet(AOP(left),offset));
+            emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+        }
+
+        offset++;
+    }
+
     freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
 }
@@ -5068,11 +4514,12 @@ 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;
-    char *l;    
+    int same;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* rotate right with carry */
     left = IC_LEFT(ic);
@@ -5080,31 +4527,31 @@ static void genRLC (iCode *ic)
     aopOp (left,ic,FALSE);
     aopOp (result,ic,FALSE);
 
+    DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+    same = pic14_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 */
+    emitpcode(POC_RLFW, popGet(AOP(left),size-1));
+
     offset = 0 ;
-    if (size--) {
-        l = aopGet(AOP(left),offset,FALSE,FALSE);
-        MOVA(l);
-        pic14_emitcode("add","a,acc");
-        if (AOP_SIZE(result) > 1)
-            aopPut(AOP(result),"a",offset++);
-        while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,FALSE);
-            MOVA(l);
-            pic14_emitcode("rlc","a");
-            if (AOP_SIZE(result) > 1)
-                aopPut(AOP(result),"a",offset++);
+
+    while(size--) {
+
+        if(same) {
+            emitpcode(POC_RLF, popGet(AOP(left),offset));
+        } else {
+            emitpcode(POC_RLFW, popGet(AOP(left),offset));
+            emitpcode(POC_MOVWF, popGet(AOP(result),offset));
         }
+
+        offset++;
     }
-    /* now we need to put the carry into the
-    highest order byte of the result */
-    if (AOP_SIZE(result) > 1) {
-        l = aopGet(AOP(result),0,FALSE,FALSE);
-        MOVA(l);
-    }
-    pic14_emitcode("mov","acc.0,c");
-    aopPut(AOP(result),"a",0);
+
+
     freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
 }
@@ -5120,6 +4567,7 @@ static void genGetHbit (iCode *ic)
     aopOp (left,ic,FALSE);
     aopOp (result,ic,FALSE);
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* get the highest order byte into a */
     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
@@ -5139,1516 +4587,407 @@ static void genGetHbit (iCode *ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* AccRol - rotate left accumulator by known count                 */
+/* AccLsh - shift left accumulator by known count                  */
+/* MARK: pic14 always rotates through CARRY!                       */
 /*-----------------------------------------------------------------*/
-static void AccRol (int shCount)
+static void AccLsh (pCodeOp *pcop,int shCount)
 {
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     shCount &= 0x0007;              // shCount : 0..7
     switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            pic14_emitcode("rl","a");
-            break;
-        case 2 :
-            pic14_emitcode("rl","a");
-            pic14_emitcode("rl","a");
-            break;
-        case 3 :
-            pic14_emitcode("swap","a");
-            pic14_emitcode("rr","a");
-            break;
-        case 4 :
-            pic14_emitcode("swap","a");
-            break;
-        case 5 :
-            pic14_emitcode("swap","a");
-            pic14_emitcode("rl","a");
-            break;
-        case 6 :
-            pic14_emitcode("rr","a");
-            pic14_emitcode("rr","a");
-            break;
-        case 7 :
-            pic14_emitcode("rr","a");
-            break;
-    }
-}
-
-/*-----------------------------------------------------------------*/
-/* AccLsh - left shift accumulator by known count                  */
-/*-----------------------------------------------------------------*/
-static void AccLsh (int shCount)
-{
+    case 0 :
+        return;
+        break;
+    case 1 :
+        emitCLRC;
+        emitpcode(POC_RLF,pcop);
+        return;
+        break;
+    case 2 :
+        emitpcode(POC_RLF,pcop);
+        emitpcode(POC_RLF,pcop);
+        break;
+    case 3 :
+        emitpcode(POC_RLF,pcop);
+        emitpcode(POC_RLF,pcop);
+        emitpcode(POC_RLF,pcop);
+        break;
+    case 4 :
+        emitpcode(POC_SWAPF,pcop);
+        break;
+    case 5 :
+        emitpcode(POC_SWAPF,pcop);
+        emitpcode(POC_RLF,pcop);
+        break;
+    case 6 :
+        emitpcode(POC_SWAPF,pcop);
+        emitpcode(POC_RLF,pcop);
+        emitpcode(POC_RLF,pcop);
+        break;
+    case 7 :
+        emitpcode(POC_RRFW,pcop);
+        emitpcode(POC_RRF,pcop);
+        break;
+    }
+    /* clear invalid bits */
+    emitpcode(POC_MOVLW, popGetLit ((unsigned char)(~((1UL << shCount) - 1))));
+    emitpcode(POC_ANDWF, pcop);
+}
+
+/*-----------------------------------------------------------------*/
+/* AccRsh - shift right accumulator by known count                 */
+/* MARK: pic14 always rotates through CARRY!                       */
+/* maskmode - 0: leave invalid bits undefined (caller should mask) */
+/*            1: mask out invalid bits (zero-extend)               */
+/*            2: sign-extend result (pretty slow)                  */
+/*-----------------------------------------------------------------*/
+static void AccRsh (pCodeOp *pcop,int shCount, int mask_mode)
+{
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(shCount != 0){
-        if(shCount == 1)
-            pic14_emitcode("add","a,acc");
-        else 
-           if(shCount == 2) {
-            pic14_emitcode("add","a,acc");
-            pic14_emitcode("add","a,acc");
+    shCount &= 0x0007;              // shCount : 0..7
+    switch(shCount){
+    case 0 :
+        return;
+        break;
+    case 1 :
+        /* load sign if needed */
+        if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+        else if (mask_mode == 1) emitCLRC;
+        emitpcode(POC_RRF,pcop);
+        return;
+        break;
+    case 2 :
+        /* load sign if needed */
+        if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+        emitpcode(POC_RRF,pcop);
+        /* load sign if needed */
+        if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+        emitpcode(POC_RRF,pcop);
+        if (mask_mode == 2) return;
+        break;
+    case 3 :
+        /* load sign if needed */
+        if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+        emitpcode(POC_RRF,pcop);
+        /* load sign if needed */
+        if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+        emitpcode(POC_RRF,pcop);
+        /* load sign if needed */
+        if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+        emitpcode(POC_RRF,pcop);
+        if (mask_mode == 2) return;
+        break;
+    case 4 :
+        emitpcode(POC_SWAPF,pcop);
+        break;
+    case 5 :
+        emitpcode(POC_SWAPF,pcop);
+        emitpcode(POC_RRF,pcop);
+        break;
+    case 6 :
+        emitpcode(POC_SWAPF,pcop);
+        emitpcode(POC_RRF,pcop);
+        emitpcode(POC_RRF,pcop);
+        break;
+    case 7 :
+        if (mask_mode == 2)
+        {
+            /* load sign */
+            emitpcode(POC_RLFW,pcop);
+            emitpcode(POC_CLRF,pcop);
+            emitSKPNC;
+            emitpcode(POC_COMF,pcop);
+            return;
         } else {
-            /* rotate left accumulator */
-            AccRol(shCount);
-            /* and kill the lower order bits */
-            pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
+            emitpcode(POC_RLFW,pcop);
+            emitpcode(POC_RLF,pcop);
         }
+        break;
+    }
+
+    if (mask_mode == 0)
+    {
+        /* leave invalid bits undefined */
+        return;
+    }
+
+    /* clear invalid bits -- zero-extend */
+    emitpcode(POC_MOVLW, popGetLit (0x00ff >> shCount));
+    emitpcode(POC_ANDWF, pcop);
+
+    if (mask_mode == 2) {
+      /* sign-extend */
+      emitpcode(POC_MOVLW, popGetLit (0x00ff << (8 - shCount)));
+      emitpcode(POC_BTFSC, newpCodeOpBit (get_op(pcop,NULL,0), 7 - shCount ,0));
+      emitpcode(POC_IORWF, pcop);
     }
 }
 
 /*-----------------------------------------------------------------*/
-/* AccRsh - right shift accumulator by known count                 */
+/* movLeft2Result - move byte from left to result                  */
 /*-----------------------------------------------------------------*/
-static void AccRsh (int shCount)
+static void movLeft2Result (operand *left, int offl,
+                            operand *result, int offr)
 {
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(shCount != 0){
-        if(shCount == 1){
-            CLRC;
-            pic14_emitcode("rrc","a");
-        } else {
-            /* rotate right accumulator */
-            AccRol(8 - shCount);
-            /* and kill the higher order bits */
-            pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
-        }
+    if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
+        aopGet(AOP(left),offl,FALSE,FALSE);
+
+        emitpcode(POC_MOVFW, popGet(AOP(left),offl));
+        emitpcode(POC_MOVWF, popGet(AOP(result),offr));
     }
 }
 
-#if 0
 /*-----------------------------------------------------------------*/
-/* AccSRsh - signed right shift accumulator by known count                 */
+/* shiftLeft_Left2ResultLit - shift left by known count            */
 /*-----------------------------------------------------------------*/
-static void AccSRsh (int shCount)
+
+static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
 {
-    symbol *tlbl ;
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(shCount != 0){
-        if(shCount == 1){
-            pic14_emitcode("mov","c,acc.7");
-            pic14_emitcode("rrc","a");
-        } else if(shCount == 2){
-            pic14_emitcode("mov","c,acc.7");
-            pic14_emitcode("rrc","a");
-            pic14_emitcode("mov","c,acc.7");
-            pic14_emitcode("rrc","a");
-        } else {
-            tlbl = newiTempLabel(NULL);
-            /* rotate right accumulator */
-            AccRol(8 - shCount);
-            /* and kill the higher order bits */
-            pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
-            pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
-            pic14_emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);
-            pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-        }
-    }
-}
-#endif
-/*-----------------------------------------------------------------*/
-/* shiftR1Left2Result - shift right one byte from left to result   */
-/*-----------------------------------------------------------------*/
-static void shiftR1Left2ResultSigned (operand *left, int offl,
-                                operand *result, int offr,
-                                int shCount)
-{
-  int same;
-
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  same = (left == result) || (AOP(left) == AOP(result));
-
-  switch(shCount) {
-  case 1:
-    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
-    if(same) 
-      emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
-    else {
-      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    }
-
-    break;
-
-  default:
-    break;
-  }
-}
-
-/*-----------------------------------------------------------------*/
-/* shiftR1Left2Result - shift right one byte from left to result   */
-/*-----------------------------------------------------------------*/
-static void shiftR1Left2Result (operand *left, int offl,
-                                operand *result, int offr,
-                                int shCount, int sign)
-{
-  int same;
-
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  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);
-    return;
-  }
-
-
-
-  switch(shCount) {
-  case 1:
-    emitCLRC;
-    if(same) 
-      emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
-    else {
-      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    }
-    break;
-  case 2:
-    emitCLRC;
-    if(same) {
-      emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
-    } else {
-      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    }
-    emitCLRC;
-    emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
-
-    break;
-  case 3:
-    if(same) 
-      emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
-    else {
-      emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    }
-
-    emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0x1f));
-    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-      
-  case 4:
-    emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0x0f));
-    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-
-  case 5:
-    emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0x0f));
-    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    emitCLRC;
-    emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
-
-    break;
-  case 6:
-
-    emitpcode(POC_RLFW,  popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0x80));
-    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-
-  case 7:
-
-    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
-
-    break;
-
-  default:
-    break;
-  }
-
-
-#if 0
-    
-  MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-
-  /* shift right accumulator */
-  if(sign)
-    AccSRsh(shCount);
-  else
-    AccRsh(shCount);
-  aopPut(AOP(result),"a",offr);
-#endif
-}
-
-/*-----------------------------------------------------------------*/
-/* shiftL1Left2Result - shift left one byte from left to result    */
-/*-----------------------------------------------------------------*/
-static void shiftL1Left2Result (operand *left, int offl,
-                                operand *result, int offr, int shCount)
-{
-  int same;
-
-  //    char *l;
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
-  DEBUGpic14_emitcode ("; ***","same =  %d",same);
-    //    l = aopGet(AOP(left),offl,FALSE,FALSE);
-    //    MOVA(l);
-    /* shift left accumulator */
-    //AccLsh(shCount); // don't comment out just yet...
-  //    aopPut(AOP(result),"a",offr);
-
-  switch(shCount) {
-  case 1:
-    /* Shift left 1 bit position */
-    emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
-    if(same) {
-      emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
-    } else {
-      emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-    }
-    break;
-  case 2:
-    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW,popGetLit(0x7e));
-    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-  case 3:
-    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW,popGetLit(0x3e));
-    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-  case 4:
-    emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0xf0));
-    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-  case 5:
-    emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0xf0));
-    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-  case 6:
-    emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0x30));
-    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-  case 7:
-    emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
-    emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
-    break;
-
-  default:
-    DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
-  }
-
-}
-
-/*-----------------------------------------------------------------*/
-/* movLeft2Result - move byte from left to result                  */
-/*-----------------------------------------------------------------*/
-static void movLeft2Result (operand *left, int offl,
-                            operand *result, int offr, int sign)
-{
-    char *l;
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
-        l = aopGet(AOP(left),offl,FALSE,FALSE);
-
-        if (*l == '@' && (IS_AOP_PREG(result))) {
-            pic14_emitcode("mov","a,%s",l);
-            aopPut(AOP(result),"a",offr);
-        } else {
-         if(!sign) {
-           emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
-           emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-
-           //aopPut(AOP(result),l,offr);
-         }else{
-                /* MSB sign in acc.7 ! */
-                if(pic14_getDataSize(left) == offl+1){
-                    pic14_emitcode("mov","a,%s",l);
-                    aopPut(AOP(result),"a",offr);
-                }
-            }
-        }
-    }
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXRrl1 - right rotate c->a:x->c by 1                         */
-/*-----------------------------------------------------------------*/
-static void AccAXRrl1 (char *x)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    pic14_emitcode("rrc","a");
-    pic14_emitcode("xch","a,%s", x);
-    pic14_emitcode("rrc","a");
-    pic14_emitcode("xch","a,%s", x);
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
-/*-----------------------------------------------------------------*/
-static void AccAXLrl1 (char *x)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    pic14_emitcode("xch","a,%s",x);
-    pic14_emitcode("rlc","a");
-    pic14_emitcode("xch","a,%s",x);
-    pic14_emitcode("rlc","a");
-}
-#if 0
-/*-----------------------------------------------------------------*/
-/* AccAXLsh1 - left shift a:x<-0 by 1                              */
-/*-----------------------------------------------------------------*/
-static void AccAXLsh1 (char *x)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    pic14_emitcode("xch","a,%s",x);
-    pic14_emitcode("add","a,acc");
-    pic14_emitcode("xch","a,%s",x);
-    pic14_emitcode("rlc","a");
-}
-#endif
-#if 0
-/*-----------------------------------------------------------------*/
-/* AccAXLsh - left shift a:x by known count (0..7)                 */
-/*-----------------------------------------------------------------*/
-static void AccAXLsh (char *x, int shCount)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            AccAXLsh1(x);
-            break;
-        case 2 :
-            AccAXLsh1(x);
-            AccAXLsh1(x);
-            break;
-        case 3 :
-        case 4 :
-        case 5 :                        // AAAAABBB:CCCCCDDD
-            AccRol(shCount);            // BBBAAAAA:CCCCCDDD
-            pic14_emitcode("anl","a,#0x%02x",
-                     SLMask[shCount]);  // BBB00000:CCCCCDDD
-            pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBB00000
-            AccRol(shCount);            // DDDCCCCC:BBB00000
-            pic14_emitcode("xch","a,%s",x);   // BBB00000:DDDCCCCC
-            pic14_emitcode("xrl","a,%s",x);   // (BBB^DDD)CCCCC:DDDCCCCC
-            pic14_emitcode("xch","a,%s",x);   // DDDCCCCC:(BBB^DDD)CCCCC
-            pic14_emitcode("anl","a,#0x%02x",
-                     SLMask[shCount]);  // DDD00000:(BBB^DDD)CCCCC
-            pic14_emitcode("xch","a,%s",x);   // (BBB^DDD)CCCCC:DDD00000
-            pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:DDD00000            
-            break;
-        case 6 :                        // AAAAAABB:CCCCCCDD
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000000BB:CCCCCCDD
-            pic14_emitcode("mov","c,acc.0");  // c = B
-            pic14_emitcode("xch","a,%s",x);   // CCCCCCDD:000000BB
-            AccAXRrl1(x);               // BCCCCCCD:D000000B
-            AccAXRrl1(x);               // BBCCCCCC:DD000000
-            break;
-        case 7 :                        // a:x <<= 7
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 0000000B:CCCCCCCD
-            pic14_emitcode("mov","c,acc.0");  // c = B
-            pic14_emitcode("xch","a,%s",x);   // CCCCCCCD:0000000B
-            AccAXRrl1(x);               // BCCCCCCC:D0000000
-            break;
-        default :
-            break;
-    }
-}
-#endif
-#if 0
-/*-----------------------------------------------------------------*/
-/* AccAXRsh - right shift a:x known count (0..7)                   */
-/*-----------------------------------------------------------------*/
-static void AccAXRsh (char *x, int shCount)
-{   
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            CLRC;
-            AccAXRrl1(x);               // 0->a:x
-            break;
-        case 2 :
-            CLRC;
-            AccAXRrl1(x);               // 0->a:x
-            CLRC;
-            AccAXRrl1(x);               // 0->a:x
-            break;
-        case 3 :
-        case 4 :
-        case 5 :                        // AAAAABBB:CCCCCDDD = a:x
-            AccRol(8 - shCount);        // BBBAAAAA:DDDCCCCC
-            pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
-            AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000CCCCC:BBBAAAAA
-            pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
-            pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
-            pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
-            pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
-            pic14_emitcode("xch","a,%s",x);   // 000AAAAA:BBBCCCCC
-            break;
-        case 6 :                        // AABBBBBB:CCDDDDDD
-            pic14_emitcode("mov","c,acc.7");
-            AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
-            AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
-            pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000000AA:BBBBBBCC
-            break;
-        case 7 :                        // ABBBBBBB:CDDDDDDD
-            pic14_emitcode("mov","c,acc.7");  // c = A
-            AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
-            pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 0000000A:BBBBBBBC
-            break;
-        default :
-            break;
-    }
-}
-#endif
-/*-----------------------------------------------------------------*/
-/* AccAXRshS - right shift signed a:x known count (0..7)           */
-/*-----------------------------------------------------------------*/
-static void AccAXRshS (char *x, int shCount)
-{   
-    symbol *tlbl ;
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            pic14_emitcode("mov","c,acc.7");
-            AccAXRrl1(x);               // s->a:x
-            break;
-        case 2 :
-            pic14_emitcode("mov","c,acc.7");
-            AccAXRrl1(x);               // s->a:x
-            pic14_emitcode("mov","c,acc.7");
-            AccAXRrl1(x);               // s->a:x
-            break;
-        case 3 :
-        case 4 :
-        case 5 :                        // AAAAABBB:CCCCCDDD = a:x
-            tlbl = newiTempLabel(NULL);
-            AccRol(8 - shCount);        // BBBAAAAA:CCCCCDDD
-            pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
-            AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000CCCCC:BBBAAAAA
-            pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
-            pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
-            pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
-            pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
-            pic14_emitcode("xch","a,%s",x);   // 000SAAAA:BBBCCCCC
-            pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
-            pic14_emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);  // 111AAAAA:BBBCCCCC
-            pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-            break;                      // SSSSAAAA:BBBCCCCC
-        case 6 :                        // AABBBBBB:CCDDDDDD
-            tlbl = newiTempLabel(NULL);
-            pic14_emitcode("mov","c,acc.7");
-            AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
-            AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
-            pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000000AA:BBBBBBCC
-            pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
-            pic14_emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);  // 111111AA:BBBBBBCC
-            pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-            break;
-        case 7 :                        // ABBBBBBB:CDDDDDDD
-            tlbl = newiTempLabel(NULL);
-            pic14_emitcode("mov","c,acc.7");  // c = A
-            AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
-            pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
-            pic14_emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 0000000A:BBBBBBBC
-            pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
-            pic14_emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);  // 1111111A:BBBBBBBC
-            pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-            break;
-        default :
-            break;
-    }
-}
-
-/*-----------------------------------------------------------------*/
-/* shiftL2Left2Result - shift left two bytes from left to result   */
-/*-----------------------------------------------------------------*/
-static void shiftL2Left2Result (operand *left, int offl,
-                                operand *result, int offr, int shCount)
-{
-
-
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  if(pic14_sameRegs(AOP(result), AOP(left))) {
-    switch(shCount) {
-    case 0:
-      break;
-    case 1:
-    case 2:
-    case 3:
-
-      emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-
-      while(--shCount) {
-       emitCLRC;
-       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      }
-
-      break;
-    case 4:
-    case 5:
-      emitpcode(POC_MOVLW, popGetLit(0x0f));
-      emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      if(shCount >=5) {
-       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      }
-      break;
-    case 6:
-      emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_ANDLW,popGetLit(0xc0));
-      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      break;
-    case 7:
-      emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
-    }
-
-  } else {
-    switch(shCount) {
-    case 0:
-      break;
-    case 1:
-    case 2:
-    case 3:
-      /* note, use a mov/add for the shift since the mov has a
-        chance of getting optimized out */
-      emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-
-      while(--shCount) {
-       emitCLRC;
-       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      }
-      break;
-
-    case 4:
-    case 5:
-      emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
-      emitpcode(POC_ANDLW, popGetLit(0xF0));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_ANDLW, popGetLit(0xF0));
-      emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-
-
-      if(shCount == 5) {
-       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      }
-      break;
-    case 6:
-      emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
-      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF,  popGet(AOP(result),offr,FALSE,FALSE));
-
-      emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_ANDLW,popGetLit(0xc0));
-      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      break;
-    case 7:
-      emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
-      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
-    }
-  }
-
-}
-/*-----------------------------------------------------------------*/
-/* shiftR2Left2Result - shift right two bytes from left to result  */
-/*-----------------------------------------------------------------*/
-static void shiftR2Left2Result (operand *left, int offl,
-                                operand *result, int offr,
-                                int shCount, int sign)
-{
-  int same=0;
-
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  same = pic14_sameRegs(AOP(result), AOP(left));
-
-  if(same && ((offl + MSB16) == offr)){
-    same=1;
-    /* don't crash result[offr] */
-    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-    pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-  } else {
-    movLeft2Result(left,offl, result, offr, 0);
-    MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-  }
-  /* a:x >> shCount (x = lsb(result))*/
-  if(sign)
-    AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
-  else {
-    //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
-    
-    switch(shCount) {
-    case 0:
-      break;
-    case 1:
-    case 2:
-    case 3:
-      emitCLRC;
-      if(same) {
-       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
-      } else {
-
-       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
-       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
-       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-      }
-
-      while(--shCount) {
-       emitCLRC;
-       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
-      }
-      break;
-    case 4:
-    case 5:
-      if(same) {
-
-       emitpcode(POC_MOVLW, popGetLit(0xf0));
-       emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
-
-       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
-      } else {
-       emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
-       emitpcode(POC_ANDLW, popGetLit(0x0f));
-       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
-
-       emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
-       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_ANDLW, popGetLit(0xf0));
-       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
-      }
-
-      if(shCount >=5) {
-       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
-      }
-
-      break;
-
-    case 6:
-      if(same) {
-
-       emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-
-       emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_ANDLW,popGetLit(0x03));
-       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-      } else {
-       emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
-       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
-       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
-       emitpcode(POC_ANDLW,popGetLit(0x03));
-       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-      }
-
-      break;
-    case 7:
-      emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
-      emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
-      emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
-      emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-      emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-    }
-  }
-}
-
-/*-----------------------------------------------------------------*/
-/* shiftLLeftOrResult - shift left one byte from left, or to result*/
-/*-----------------------------------------------------------------*/
-static void shiftLLeftOrResult (operand *left, int offl,
-                                operand *result, int offr, int shCount)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-    /* shift left accumulator */
-    AccLsh(shCount);
-    /* or with result */
-    pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-    /* back to result */
-    aopPut(AOP(result),"a",offr);
-}
-
-/*-----------------------------------------------------------------*/
-/* shiftRLeftOrResult - shift right one byte from left,or to result*/
-/*-----------------------------------------------------------------*/
-static void shiftRLeftOrResult (operand *left, int offl,
-                                operand *result, int offr, int shCount)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-    /* shift right accumulator */
-    AccRsh(shCount);
-    /* or with result */
-    pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-    /* back to result */
-    aopPut(AOP(result),"a",offr);
-}
-
-/*-----------------------------------------------------------------*/
-/* genlshOne - left shift a one byte quantity by known count       */
-/*-----------------------------------------------------------------*/
-static void genlshOne (operand *result, operand *left, int shCount)
-{       
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    shiftL1Left2Result(left, LSB, result, LSB, shCount);
-}
-
-/*-----------------------------------------------------------------*/
-/* genlshTwo - left shift two bytes by known amount != 0           */
-/*-----------------------------------------------------------------*/
-static void genlshTwo (operand *result,operand *left, int shCount)
-{
-    int size;
-    
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    size = pic14_getDataSize(result);
-
-    /* if shCount >= 8 */
-    if (shCount >= 8) {
-        shCount -= 8 ;
-
-        if (size > 1){
-            if (shCount)
-                shiftL1Left2Result(left, LSB, result, MSB16, shCount);
-            else 
-                movLeft2Result(left, LSB, result, MSB16, 0);
-        }
-       emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
-    }
-
-    /*  1 <= shCount <= 7 */
-    else {  
-        if(size == 1)
-            shiftL1Left2Result(left, LSB, result, LSB, shCount); 
-        else 
-            shiftL2Left2Result(left, LSB, result, LSB, shCount);
-    }
-}
+    int size, same, offr, i;
 
-/*-----------------------------------------------------------------*/
-/* shiftLLong - shift left one long from left to result            */
-/* offl = LSB or MSB16                                             */
-/*-----------------------------------------------------------------*/
-static void shiftLLong (operand *left, operand *result, int offr )
-{
-    char *l;
-    int size = AOP_SIZE(result);
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(size >= LSB+offr){
-        l = aopGet(AOP(left),LSB,FALSE,FALSE);
-        MOVA(l);
-        pic14_emitcode("add","a,acc");
-       if (pic14_sameRegs(AOP(left),AOP(result)) && 
-           size >= MSB16+offr && offr != LSB )
-           pic14_emitcode("xch","a,%s",
-                    aopGet(AOP(left),LSB+offr,FALSE,FALSE));
-       else        
-           aopPut(AOP(result),"a",LSB+offr);
-    }
-
-    if(size >= MSB16+offr){
-       if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
-           l = aopGet(AOP(left),MSB16,FALSE,FALSE);
-           MOVA(l);
-       }
-        pic14_emitcode("rlc","a");
-       if (pic14_sameRegs(AOP(left),AOP(result)) && 
-           size >= MSB24+offr && offr != LSB)
-           pic14_emitcode("xch","a,%s",
-                    aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
-       else        
-           aopPut(AOP(result),"a",MSB16+offr);
-    }
-
-    if(size >= MSB24+offr){
-       if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
-           l = aopGet(AOP(left),MSB24,FALSE,FALSE);
-           MOVA(l);
-       }
-        pic14_emitcode("rlc","a");
-       if (pic14_sameRegs(AOP(left),AOP(result)) && 
-           size >= MSB32+offr && offr != LSB )
-           pic14_emitcode("xch","a,%s",
-                    aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
-       else        
-           aopPut(AOP(result),"a",MSB24+offr);
-    }
-
-    if(size > MSB32+offr){
-       if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
-           l = aopGet(AOP(left),MSB32,FALSE,FALSE);
-           MOVA(l);    
-       }
-        pic14_emitcode("rlc","a");
-        aopPut(AOP(result),"a",MSB32+offr);
-    }
-    if(offr != LSB)
-        aopPut(AOP(result),zero,LSB);       
-}
-
-/*-----------------------------------------------------------------*/
-/* genlshFour - shift four byte by a known amount != 0             */
-/*-----------------------------------------------------------------*/
-static void genlshFour (operand *result, operand *left, int shCount)
-{
-    int size;
+    size = AOP_SIZE(left);
+    if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    size = AOP_SIZE(result);
+    same = pic14_sameRegs (AOP(left), AOP(result));
 
-    /* if shifting more that 3 bytes */
-    if (shCount >= 24 ) {
-        shCount -= 24;
-        if (shCount)
-            /* lowest order of left goes to the highest
-            order of the destination */
-            shiftL1Left2Result(left, LSB, result, MSB32, shCount);
-        else
-            movLeft2Result(left, LSB, result, MSB32, 0);
-        aopPut(AOP(result),zero,LSB);
-        aopPut(AOP(result),zero,MSB16);
-        aopPut(AOP(result),zero,MSB32);
-        return;
-    }
+    offr = shCount / 8;
+    shCount = shCount & 0x07;
 
-    /* more than two bytes */
-    else if ( shCount >= 16 ) {
-        /* lower order two bytes goes to higher order two bytes */
-        shCount -= 16;
-        /* if some more remaining */
-        if (shCount)
-            shiftL2Left2Result(left, LSB, result, MSB24, shCount);
-        else {
-            movLeft2Result(left, MSB16, result, MSB32, 0);
-            movLeft2Result(left, LSB, result, MSB24, 0);
-        }
-        aopPut(AOP(result),zero,MSB16);
-        aopPut(AOP(result),zero,LSB);
-        return;
-    }    
-
-    /* if more than 1 byte */
-    else if ( shCount >= 8 ) {
-        /* lower order three bytes goes to higher order  three bytes */
-        shCount -= 8;
-        if(size == 2){
-            if(shCount)
-                shiftL1Left2Result(left, LSB, result, MSB16, shCount);
-            else
-                movLeft2Result(left, LSB, result, MSB16, 0);
-        }
-        else{   /* size = 4 */
-            if(shCount == 0){
-                movLeft2Result(left, MSB24, result, MSB32, 0);
-                movLeft2Result(left, MSB16, result, MSB24, 0);
-                movLeft2Result(left, LSB, result, MSB16, 0);
-                aopPut(AOP(result),zero,LSB);
-            }
-            else if(shCount == 1)
-                shiftLLong(left, result, MSB16);
-            else{
-                shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
-                shiftL1Left2Result(left, LSB, result, MSB16, shCount);
-                shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
-                aopPut(AOP(result),zero,LSB);
-            }
-        }
-    }
+    size -= offr;
 
-    /* 1 <= shCount <= 7 */
-    else if(shCount <= 2){
-        shiftLLong(left, result, LSB);
-        if(shCount == 2)
-            shiftLLong(result, result, LSB);
-    }
-    /* 3 <= shCount <= 7, optimize */
-    else{
-        shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
-        shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
-        shiftL2Left2Result(left, LSB, result, LSB, shCount);
-    }
+    switch (shCount)
+    {
+    case 0: /* takes 0 or 2N cycles (for offr==0) */
+        if (!same || offr) {
+            for (i=size-1; i >= 0; i--)
+                movLeft2Result (left, i, result, offr + i);
+        } // if
+        break;
+
+    case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
+        if (same && offr) {
+            shiftLeft_Left2ResultLit (left, result, 8 * offr);
+            shiftLeft_Left2ResultLit (result, result, shCount);
+            return; /* prevent clearing result again */
+        } else {
+            emitCLRC;
+            for (i=0; i < size; i++) {
+                if (same && !offr) {
+                    emitpcode (POC_RLF, popGet (AOP(left), i));
+                } else {
+                    emitpcode (POC_RLFW, popGet (AOP(left), i));
+                    emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+                } // if
+            } // for
+        } // if (offr)
+        break;
+
+    case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
+        /* works in-place/with offr as well */
+        emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
+        emitpcode (POC_ANDLW, popGetLit (0xF0));
+        emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
+
+        for (i = size - 2; i >= 0; i--)
+        {
+            emitpcode (POC_SWAPFW, popGet (AOP(left), i));
+            emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+            emitpcode (POC_ANDLW, popGetLit (0x0F));
+            emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
+            emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
+        } // for i
+        break;
+
+    case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
+        /* works in-place/with offr as well */
+        emitpcode (POC_RRFW, popGet (AOP(left), size-1));
+        for (i = size-2; i >= 0; i--) {
+            emitpcode (POC_RRFW, popGet (AOP(left), i));
+            emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
+        } // for i
+        emitpcode (POC_CLRF, popGet (AOP(result), offr));
+        emitpcode (POC_RRF, popGet (AOP(result), offr));
+        break;
+
+    default:
+        shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
+        shiftLeft_Left2ResultLit (result, result, 1);
+        return; /* prevent clearing result again */
+        break;
+    } // switch
+
+    while (0 < offr--)
+    {
+        emitpcode (POC_CLRF, popGet (AOP(result), offr));
+    } // while
 }
 
 /*-----------------------------------------------------------------*/
-/* genLeftShiftLiteral - left shifting by known count              */
+/* shiftRight_Left2ResultLit - shift right by known count          */
 /*-----------------------------------------------------------------*/
-static void genLeftShiftLiteral (operand *left,
-                                 operand *right,
-                                 operand *result,
-                                 iCode *ic)
-{    
-    int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
-    int size;
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    freeAsmop(right,NULL,ic,TRUE);
-
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
-
-    size = getSize(operandType(result));
-
-#if VIEW_SIZE
-    pic14_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, 0);
-        }
-    }
-
-    else if(shCount >= (size * 8))
-        while(size--)
-            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;
-        }
-    }
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
-}
 
-/*-----------------------------------------------------------------*/
-/* genLeftShift - generates code for left shifting                 */
-/*-----------------------------------------------------------------*/
-static void genLeftShift (iCode *ic)
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
 {
-    operand *left,*right, *result;
-    int size, offset;
-    char *l;
-    symbol *tlbl , *tlbl1;
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    right = IC_RIGHT(ic);
-    left  = IC_LEFT(ic);
-    result = IC_RESULT(ic);
+    int size, same, offr, i;
 
-    aopOp(right,ic,FALSE);
+    size = AOP_SIZE(left);
+    if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
 
-    /* if the shift count is known then do it 
-    as efficiently as possible */
-    if (AOP_TYPE(right) == AOP_LIT) {
-        genLeftShiftLiteral (left,right,result,ic);
-        return ;
-    }
+    same = pic14_sameRegs (AOP(left), AOP(result));
 
-    /* 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 ) */  
+    offr = shCount / 8;
+    shCount = shCount & 0x07;
 
-    
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+    size -= offr;
 
-    /* now move the left to the result if they are not the
-    same */
-    if (!pic14_sameRegs(AOP(left),AOP(result)) && 
-        AOP_SIZE(result) > 1) {
+    if (size)
+    {
+        switch (shCount)
+        {
+        case 0: /* takes 0 or 2N cycles (for offr==0) */
+            if (!same || offr) {
+                for (i=0; i < size; i++)
+                    movLeft2Result (left, i + offr, result, i);
+            } // if
+            break;
 
-        size = AOP_SIZE(result);
-        offset=0;
-        while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,TRUE);
-            if (*l == '@' && (IS_AOP_PREG(result))) {
+        case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
+            emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
+            if (same && offr) {
+                shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
+                shiftRight_Left2ResultLit (result, result, shCount, sign);
+                return; /* prevent sign-extending result again */
+            } else {
+                emitCLRC;
+                if (sign) {
+                    emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
+                    emitSETC;
+                }
+                for (i = size-1; i >= 0; i--) {
+                    if (same && !offr) {
+                        emitpcode (POC_RRF, popGet (AOP(left), i));
+                    } else {
+                        emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
+                        emitpcode (POC_MOVWF, popGet (AOP(result), i));
+                    }
+                } // for i
+            } // if (offr)
+            break;
 
-                pic14_emitcode("mov","a,%s",l);
-                aopPut(AOP(result),"a",offset);
-            } else
-                aopPut(AOP(result),l,offset);
-            offset++;
-        }
-    }
+        case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
+            /* works in-place/with offr as well */
+            emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
+            emitpcode (POC_ANDLW, popGetLit (0x0F));
+            emitpcode (POC_MOVWF, popGet(AOP(result), 0));
 
-    size = AOP_SIZE(result);
+            for (i = 1; i < size; i++)
+            {
+                emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
+                emitpcode (POC_MOVWF, popGet (AOP(result), i));
+                emitpcode (POC_ANDLW, popGetLit (0xF0));
+                emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
+                emitpcode (POC_XORWF, popGet (AOP(result), i));
+            } // for i
+
+            if (sign)
+            {
+                emitpcode (POC_MOVLW, popGetLit (0xF0));
+                emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
+                emitpcode (POC_IORWF, popGet (AOP(result), size-1));
+            } // if
+            break;
 
-    /* if it is only one byte then */
-    if (size == 1) {
-      if(optimized_for_speed) {
-       emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
-       emitpcode(POC_ANDLW,  popGetLit(0xf0));
-       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
-       emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
-       emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
-       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
-       emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
-       emitpcode(POC_RLFW,   popGet(AOP(result),0,FALSE,FALSE));
-       emitpcode(POC_ANDLW,  popGetLit(0xfe));
-       emitpcode(POC_ADDFW,  popGet(AOP(result),0,FALSE,FALSE));
-       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
-       emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
-      } else {
+        case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
+            /* works in-place/with offr as well */
+            emitpcode (POC_RLFW, popGet (AOP(left), offr));
+            for (i = 0; i < size-1; i++) {
+                emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
+                emitpcode (POC_MOVWF, popGet (AOP(result), i));
+            } // for i
+            emitpcode (POC_CLRF, popGet (AOP(result), size-1));
+            if (!sign) {
+                emitpcode (POC_RLF, popGet (AOP(result), size-1));
+            } else {
+                emitSKPNC;
+                emitpcode (POC_DECF, popGet (AOP(result), size-1));
+            }
+            break;
 
-       tlbl = newiTempLabel(NULL);
-       if (!pic14_sameRegs(AOP(left),AOP(result))) {
-         emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
-         emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
-       }
-
-       emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
-       emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
-       emitpLabel(tlbl->key+100+labelOffset);
-       emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
-       emitpcode(POC_ADDLW,  popGetLit(1));
-       emitSKPC;
-       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
-      }
-      goto release ;
-    }
-    
+        default:
+            shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
+            shiftRight_Left2ResultLit (result, result, 1, sign);
+            return; /* prevent sign extending result again */
+            break;
+        } // switch
+    } // if
 
-    tlbl = newiTempLabel(NULL);
-    offset = 0 ;   
-    tlbl1 = newiTempLabel(NULL);
-
-    reAdjustPreg(AOP(result));    
-    
-    pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
-    pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
-    l = aopGet(AOP(result),offset,FALSE,FALSE);
-    MOVA(l);
-    pic14_emitcode("add","a,acc");         
-    aopPut(AOP(result),"a",offset++);
-    while (--size) {
-        l = aopGet(AOP(result),offset,FALSE,FALSE);
-        MOVA(l);
-        pic14_emitcode("rlc","a");         
-        aopPut(AOP(result),"a",offset++);
-    }
-    reAdjustPreg(AOP(result));
-
-    pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
-    pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-release:
-    freeAsmop (right,NULL,ic,TRUE);
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+    addSign (result, size, sign);
 }
 
-/*-----------------------------------------------------------------*/
-/* genrshOne - right shift a one byte quantity by known count      */
-/*-----------------------------------------------------------------*/
-static void genrshOne (operand *result, operand *left,
-                       int shCount, int sign)
+/*-----------------------------------------------------------------*
+* 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)
 {
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
-}
 
-/*-----------------------------------------------------------------*/
-/* genrshTwo - right shift two bytes by known amount != 0          */
-/*-----------------------------------------------------------------*/
-static void genrshTwo (operand *result,operand *left,
-                       int shCount, int sign)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if shCount >= 8 */
-    if (shCount >= 8) {
-        shCount -= 8 ;
-        if (shCount)
-            shiftR1Left2Result(left, MSB16, result, LSB,
-                               shCount, sign);
-        else 
-            movLeft2Result(left, MSB16, result, LSB, sign);
-       if(sign)
-         addSign(result, MSB16, sign);
-       else
-         emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
-
-    }
-
-    /*  1 <= shCount <= 7 */
-    else
-        shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
-}
+    int offset = 0;
 
-/*-----------------------------------------------------------------*/
-/* shiftRLong - shift right one long from left to result           */
-/* offl = LSB or MSB16                                             */
-/*-----------------------------------------------------------------*/
-static void shiftRLong (operand *left, int offl,
-                        operand *result, int sign)
-{
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(!sign)
-        pic14_emitcode("clr","c");
-    MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
-    if(sign)
-        pic14_emitcode("mov","c,acc.7");
-    pic14_emitcode("rrc","a");
-    aopPut(AOP(result),"a",MSB32-offl);
-    if(offl == MSB16)
-        /* add sign of "a" */
-        addSign(result, MSB32, sign);
-
-    MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
-    pic14_emitcode("rrc","a");
-    aopPut(AOP(result),"a",MSB24-offl);
 
-    MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
-    pic14_emitcode("rrc","a");
-    aopPut(AOP(result),"a",MSB16-offl);
+    if(!reg)
+        return;
 
-    if(offl == LSB){
-        MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
-        pic14_emitcode("rrc","a");
-        aopPut(AOP(result),"a",LSB);
+    if(!endian) {
+        endian = 1;
+    } else {
+        endian = -1;
+        offset = size-1;
     }
-}
 
-/*-----------------------------------------------------------------*/
-/* genrshFour - shift four byte by a known amount != 0             */
-/*-----------------------------------------------------------------*/
-static void genrshFour (operand *result, operand *left,
-                        int shCount, int sign)
-{
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if shifting more that 3 bytes */
-    if(shCount >= 24 ) {
-        shCount -= 24;
-        if(shCount)
-            shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
-        else
-            movLeft2Result(left, MSB32, result, LSB, sign);
-        addSign(result, MSB16, sign);
-    }
-    else if(shCount >= 16){
-        shCount -= 16;
-        if(shCount)
-            shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
-        else{
-            movLeft2Result(left, MSB24, result, LSB, 0);
-            movLeft2Result(left, MSB32, result, MSB16, sign);
-        }
-        addSign(result, MSB24, sign);
-    }
-    else if(shCount >= 8){
-        shCount -= 8;
-        if(shCount == 1)
-            shiftRLong(left, MSB16, result, sign);
-        else if(shCount == 0){
-            movLeft2Result(left, MSB16, result, LSB, 0);
-            movLeft2Result(left, MSB24, result, MSB16, 0);
-            movLeft2Result(left, MSB32, result, MSB24, sign);
-            addSign(result, MSB32, sign);
-        }
-        else{
-            shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
-            shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
-            /* the last shift is signed */
-            shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
-            addSign(result, MSB32, sign);
-        }
-    }
-    else{   /* 1 <= shCount <= 7 */
-        if(shCount <= 2){
-            shiftRLong(left, LSB, result, sign);
-            if(shCount == 2)
-                shiftRLong(result, LSB, result, sign);
-        }
-        else{
-            shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
-            shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
-            shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
-        }
+    while(size--) {
+        emitpcode(poc,    popGet(AOP(reg),offset));
+        offset += endian;
     }
-}
-
-/*-----------------------------------------------------------------*/
-/* genRightShiftLiteral - right shifting by known count            */
-/*-----------------------------------------------------------------*/
-static void genRightShiftLiteral (operand *left,
-                                  operand *right,
-                                  operand *result,
-                                  iCode *ic,
-                                  int sign)
-{    
-    int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
-    int size;
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    freeAsmop(right,NULL,ic,TRUE);
-
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
-
-#if VIEW_SIZE
-    pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
-             AOP_SIZE(left));
-#endif
-
-    size = pic14_getDataSize(left);
-    /* test the LEFT size !!! */
-
-    /* I suppose that the left size >= result size */
-    if(shCount == 0){
-        size = pic14_getDataSize(result);
-        while(size--)
-            movLeft2Result(left, size, result, size, 0);
-    }
-
-    else if(shCount >= (size * 8)){
-        if(sign)
-            /* get sign in acc.7 */
-            MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
-        addSign(result, LSB, sign);
-    } else{
-        switch (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;
-        }
 
-        freeAsmop(left,NULL,ic,TRUE);
-        freeAsmop(result,NULL,ic,TRUE);
-    }
 }
 
 /*-----------------------------------------------------------------*/
-/* genSignedRightShift - right shift of signed number              */
+/* loadSignToC - load the operand's sign bit into CARRY            */
 /*-----------------------------------------------------------------*/
-static void genSignedRightShift (iCode *ic)
-{
-    operand *right, *left, *result;
-    int size, offset;
-    char *l;
-    symbol *tlbl, *tlbl1 ;
-
-    /* we do it the hard way put the shift count in b
-    and loop thru preserving the sign */
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    right = IC_RIGHT(ic);
-    left  = IC_LEFT(ic);
-    result = IC_RESULT(ic);
-
-    aopOp(right,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 ) */  
-
-    pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    pic14_emitcode("inc","b");
-    freeAsmop (right,NULL,ic,TRUE);
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
-
-    /* now move the left to the result if they are not the
-    same */
-    if (!pic14_sameRegs(AOP(left),AOP(result)) && 
-        AOP_SIZE(result) > 1) {
-
-        size = AOP_SIZE(result);
-        offset=0;
-        while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,TRUE);
-            if (*l == '@' && IS_AOP_PREG(result)) {
-
-                pic14_emitcode("mov","a,%s",l);
-                aopPut(AOP(result),"a",offset);
-            } else
-                aopPut(AOP(result),l,offset);
-            offset++;
-        }
-    }
-
-    /* mov the highest order bit to OVR */    
-    tlbl = newiTempLabel(NULL);
-    tlbl1= newiTempLabel(NULL);
-
-    size = AOP_SIZE(result);
-    offset = size - 1;
-    pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
-    pic14_emitcode("rlc","a");
-    pic14_emitcode("mov","ov,c");
-    /* if it is only one byte then */
-    if (size == 1) {
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);
-       pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
-        pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-        pic14_emitcode("mov","c,ov");
-        pic14_emitcode("rrc","a");
-       pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
-        pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-        aopPut(AOP(result),"a",0);
-        goto release ;
-    }
 
-    reAdjustPreg(AOP(result));
-    pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
-    pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
-    pic14_emitcode("mov","c,ov");
-    while (size--) {
-        l = aopGet(AOP(result),offset,FALSE,FALSE);
-        MOVA(l);
-        pic14_emitcode("rrc","a");         
-        aopPut(AOP(result),"a",offset--);
-    }
-    reAdjustPreg(AOP(result));
-    pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
-    pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
+static void loadSignToC (operand *op)
+{
+    FENTRY;
+    assert (op && AOP(op) && AOP_SIZE(op));
 
-release:
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+    emitCLRC;
+    emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),AOP_SIZE(op)-1,FALSE,FALSE),7,0));
+    emitSETC;
 }
 
 /*-----------------------------------------------------------------*/
 /* genRightShift - generate code for right shifting                */
 /*-----------------------------------------------------------------*/
-static void genRightShift (iCode *ic)
+static void genGenericShift (iCode *ic, int shiftRight)
 {
     operand *right, *left, *result;
     sym_link *retype ;
-    int size, offset;
-    char *l;
-    symbol *tlbl, *tlbl1 ;
+    int size;
+    symbol *tlbl, *tlbl1, *inverselbl;
 
+    FENTRY;
     /* if signed then we do it the hard way preserve the
     sign bit moving it inwards */
     retype = getSpec(operandType(IC_RESULT(ic)));
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    if (!SPEC_USIGN(retype)) {
-        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
@@ -6661,595 +5000,599 @@ static void genRightShift (iCode *ic)
     result = IC_RESULT(ic);
 
     aopOp(right,ic,FALSE);
+    aopOp(left,ic,FALSE);
+    aopOp(result,ic,FALSE);
 
-    /* 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) {
-        genRightShiftLiteral (left,right,result,ic, 0);
+        int lit = (int) ulFromVal (AOP(right)->aopu.aop_lit);
+        if (lit < 0)
+        {
+            lit = -lit;
+            shiftRight = !shiftRight;
+        }
+
+        if (shiftRight)
+            shiftRight_Left2ResultLit (left, result, lit, !SPEC_USIGN(operandType(left)));
+        else
+            shiftLeft_Left2ResultLit (left, result, lit);
+        //genRightShiftLiteral (left,right,result,ic, 0);
         return ;
     }
 
-    /* shift count is unknown then we have to form 
+    /* 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 ) */  
+    largest size of an object can be only 32 bits ) */
 
-    pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    pic14_emitcode("inc","b");
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+    /* we must not overwrite the shift counter */
+    assert (!pic14_sameRegs(AOP(right),AOP(result)));
 
     /* now move the left to the result if they are not the
     same */
-    if (!pic14_sameRegs(AOP(left),AOP(result)) && 
-        AOP_SIZE(result) > 1) {
-
-        size = AOP_SIZE(result);
-        offset=0;
+    if (!pic14_sameRegs(AOP(left),AOP(result)))
+    {
+        size = min(AOP_SIZE(result), AOP_SIZE(left));
         while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,TRUE);
-            if (*l == '@' && IS_AOP_PREG(result)) {
-
-                pic14_emitcode("mov","a,%s",l);
-                aopPut(AOP(result),"a",offset);
-            } else
-                aopPut(AOP(result),l,offset);
-            offset++;
+            mov2w(AOP(left), size);
+            movwf(AOP(result), size);
         }
+        addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(left)));
     }
 
     tlbl = newiTempLabel(NULL);
     tlbl1= newiTempLabel(NULL);
+    inverselbl = NULL;
     size = AOP_SIZE(result);
-    offset = size - 1;
 
-    /* if it is only one byte then */
-    if (size == 1) {
-/*
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);
-       pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
-        pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-        CLRC;
-        pic14_emitcode("rrc","a");
-       pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
-        pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-        aopPut(AOP(result),"a",0);
-*/
-       tlbl = newiTempLabel(NULL);
-       if (!pic14_sameRegs(AOP(left),AOP(result))) {
-         emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
-         emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
-       }
-
-       emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
-       emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
-       emitpLabel(tlbl->key+100+labelOffset);
-       emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
-       emitpcode(POC_ADDLW,  popGetLit(1));
-       emitSKPC;
-       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+    mov2w(AOP(right),0);
+    if (!SPEC_USIGN(operandType(right)))
+    {
+        inverselbl = newiTempLabel(NULL);
+        /* signed shift count -- invert shift direction for c<0 */
+        emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
+        emitpcode(POC_GOTO, popGetLabel(inverselbl->key));
+    } // if
+    emitpcode(POC_SUBLW, popGetLit(0)); /* -count in WREG, 0-x > 0 --> BORROW = !CARRY --> CARRY is clear! */
+    /* check for `a = b >> c' with `-c == 0' */
+    emitSKPNZ;
+    emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
+    emitpLabel(tlbl->key);
+    /* propagate the sign bit inwards for SIGNED result */
+    if (shiftRight && !SPEC_USIGN(operandType(result))) loadSignToC(result);
+    genMultiAsm(shiftRight ? POC_RRF : POC_RLF, result, size, shiftRight);
+    emitpcode(POC_ADDLW,  popGetLit(1));    /* clears CARRY (unless W==0 afterwards) */
+    emitSKPC;
+    emitpcode(POC_GOTO,popGetLabel(tlbl->key));
 
-        goto release ;
-    }
+    if (!SPEC_USIGN(operandType(right)))
+    {
+        symbol *inv_loop = newiTempLabel(NULL);
 
-    reAdjustPreg(AOP(result));
-    pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
-    pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
-    CLRC;
-    while (size--) {
-        l = aopGet(AOP(result),offset,FALSE,FALSE);
-        MOVA(l);
-        pic14_emitcode("rrc","a");         
-        aopPut(AOP(result),"a",offset--);
-    }
-    reAdjustPreg(AOP(result));
+        shiftRight = !shiftRight;   /* invert shift direction */
+
+        /* we came here from the code above -- we are done */
+        emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
+
+        /* emit code for shifting N<0 steps, count is already in W */
+        emitpLabel(inverselbl->key);
+        if (!shiftRight || SPEC_USIGN(operandType(result))) emitCLRC;
+        emitpLabel(inv_loop->key);
+        /* propagate the sign bit inwards for SIGNED result */
+        if (shiftRight && !SPEC_USIGN(operandType(result))) loadSignToC(result);
+        genMultiAsm(shiftRight ? POC_RRF : POC_RLF, result, size, shiftRight);
+        emitpcode(POC_ADDLW, popGetLit(1));
+        emitSKPC;
+        emitpcode(POC_GOTO, popGetLabel(inv_loop->key));
+    } // if
+
+    emitpLabel(tlbl1->key);
 
-    pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
-    pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
+    freeAsmop(left,NULL,ic,TRUE);
+    freeAsmop (right,NULL,ic,TRUE);
+    freeAsmop(result,NULL,ic,TRUE);
+}
+
+static void genRightShift (iCode *ic)
+{
+    genGenericShift(ic, 1);
+}
 
-release:
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop (right,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+static void genLeftShift (iCode *ic)
+{
+    genGenericShift(ic, 0);
 }
 
 /*-----------------------------------------------------------------*/
-/* genUnpackBits - generates code for unpacking bits               */
+/* SetIrp - Set IRP bit                                            */
 /*-----------------------------------------------------------------*/
-static void genUnpackBits (operand *result, char *rname, int ptype)
-{    
-    int shCnt ;
-    int rlen = 0 ;
-    sym_link *etype;
-    int offset = 0 ;
+static void SetIrp(operand *result)
+{
+    FENTRY;
+    if (AOP_TYPE(result) == AOP_LIT) {
+        unsigned lit = (unsigned) double2ul (operandLitValue(result));
+        if (lit&0x100)
+            emitSETIRP;
+        else
+            emitCLRIRP;
+    } else {
+        if ((AOP_TYPE(result) == AOP_PCODE)
+            && (AOP(result)->aopu.pcop->type == PO_LITERAL))
+        {
+            int addrs = PCOL(AOP(result)->aopu.pcop)->lit;
+            if (addrs & 0x100)
+                emitSETIRP;
+            else
+                emitCLRIRP;
+        } else {
+            emitCLRIRP; /* always ensure this is clear as it may have previouly been set */
+            if(AOP_SIZE(result) > 1) {
+                emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
+                emitSETIRP;
+            }
+        }
+    }
+}
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    etype = getSpec(operandType(result));
+static void
+setup_fsr (operand *ptr)
+{
+  mov2w_op(ptr, 0);
+  emitpcode(POC_MOVWF, popCopyReg (&pc_fsr));
 
-    /* read the first byte  */
-    switch (ptype) {
+  /* also setup-up IRP */
+  SetIrp (ptr);
+}
 
+/*-----------------------------------------------------------------*/
+/* emitPtrByteGet - emits code to get a byte into WREG from an     */
+/*                  arbitrary pointer (__code, __data, generic)    */
+/*-----------------------------------------------------------------*/
+static void
+emitPtrByteGet (operand *src, int p_type, bool alreadyAddressed)
+{
+    FENTRY;
+    switch (p_type)
+    {
     case POINTER:
-    case IPOINTER:
-       pic14_emitcode("mov","a,@%s",rname);
-       break;
-       
-    case PPOINTER:
-       pic14_emitcode("movx","a,@%s",rname);
-       break;
-       
     case FPOINTER:
-       pic14_emitcode("movx","a,@dptr");
-       break;
+      if (!alreadyAddressed) setup_fsr (src);
+      emitpcode(POC_MOVFW, popCopyReg (&pc_fsr));
+      break;
 
     case CPOINTER:
-       pic14_emitcode("clr","a");
-       pic14_emitcode("movc","a","@a+dptr");
-       break;
+      assert( AOP_SIZE(src) == 2 );
+      mov2w_op(src, 0);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
+      mov2w_op(src, 1);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+      emitpcode(POC_MOVLW, popGetLit (GPTRTAG_CODE));   /* GPOINTER tag for __code space */
+      call_libraryfunc ("__gptrget1");
+      break;
 
     case GPOINTER:
-       pic14_emitcode("lcall","__gptrget");
-       break;
+      assert( AOP_SIZE(src) == 3 );
+      mov2w_op(src, 0);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
+      mov2w_op(src, 1);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+      mov2w_op(src, 2);
+      call_libraryfunc ("__gptrget1");
+      break;
+
+    default:
+      assert( !"unhandled pointer type" );
+      break;
     }
+}
+
+/*-----------------------------------------------------------------*/
+/* emitPtrByteSet - emits code to set a byte from src through a    */
+/* pointer register INDF (legacy 8051 uses R0, R1, or DPTR).       */
+/*-----------------------------------------------------------------*/
+static void
+emitPtrByteSet (operand *dst, int p_type, bool alreadyAddressed)
+{
+    FENTRY;
+    switch (p_type)
+    {
+    case POINTER:
+    case FPOINTER:
+      if (!alreadyAddressed) setup_fsr (dst);
+      emitpcode(POC_MOVWF, popCopyReg (&pc_fsr));
+      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))  {
+    case CPOINTER:
+      assert( !"trying to assign to __code pointer" );
+      break;
 
-        /* shift right acc */
-        AccRsh(shCnt);
+    case GPOINTER:
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-2));
+      mov2w_op(dst, 0);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
+      mov2w_op(dst, 1);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+      mov2w_op(dst, 2);
+      call_libraryfunc ("__gptrput1");
+      break;
 
-        pic14_emitcode("anl","a,#0x%02x",
-                 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
-        aopPut(AOP(result),"a",offset);
-        return ;
+    default:
+      assert( !"unhandled pointer type" );
+      break;
     }
-
-    /* bit field did not fit in a byte  */
-    rlen = SPEC_BLEN(etype) - 8;
-    aopPut(AOP(result),"a",offset++);
-
-    while (1)  {
-
-       switch (ptype) {
-       case POINTER:
-       case IPOINTER:
-           pic14_emitcode("inc","%s",rname);
-           pic14_emitcode("mov","a,@%s",rname);
-           break;
-           
-       case PPOINTER:
-           pic14_emitcode("inc","%s",rname);
-           pic14_emitcode("movx","a,@%s",rname);
-           break;
-
-       case FPOINTER:
-           pic14_emitcode("inc","dptr");
-           pic14_emitcode("movx","a,@dptr");
-           break;
-           
-       case CPOINTER:
-           pic14_emitcode("clr","a");
-           pic14_emitcode("inc","dptr");
-           pic14_emitcode("movc","a","@a+dptr");
-           break;
-           
-       case GPOINTER:
-           pic14_emitcode("inc","dptr");
-           pic14_emitcode("lcall","__gptrget");
-           break;
-       }
-
-       rlen -= 8;            
-       /* if we are done */
-       if ( rlen <= 0 )
-           break ;
-       
-       aopPut(AOP(result),"a",offset++);
-                                     
-    }
-    
-    if (rlen) {
-       pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
-       aopPut(AOP(result),"a",offset);        
-    }
-    
-    return ;
 }
 
-
 /*-----------------------------------------------------------------*/
-/* genDataPointerGet - generates code when ptr offset is known     */
+/* genUnpackBits - generates code for unpacking bits               */
 /*-----------------------------------------------------------------*/
-static void genDataPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
+static void genUnpackBits (operand *result, operand *left, int ptype, iCode *ifx)
 {
-  int size , offset = 0;
-
+  int rsize;            /* result size */
+  sym_link *etype;      /* bitfield type information */
+  int blen;             /* bitfield length */
+  int bstr;             /* bitfield starting bit within byte */
 
+  FENTRY;
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  etype = getSpec(operandType(result));
+  rsize = getSize (operandType (result));
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
+
+  /* single bit field case */
+  if (blen == 1) {
+    if (ifx) { /* that is for an if statement */
+      pCodeOp *pcop;
+      resolvedIfx rIfx;
+      resolveIfx(&rIfx,ifx);
+      if (ptype == -1) /* direct */
+    pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
+      else
+    pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
+      emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
+      emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+      ifx->generated=1;
+    } else {
+      int i;
+      assert (!pic14_sameRegs (AOP(result), AOP(left)));
+      for (i=0; i < AOP_SIZE(result); i++)
+    emitpcode (POC_CLRF, popGet (AOP(result), i));
+
+      switch (ptype)
+      {
+      case -1:
+        emitpcode(POC_BTFSC,newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0));
+    /* adjust result below */
+        break;
+
+      case POINTER:
+      case FPOINTER:
+      case GPOINTER:
+      case CPOINTER:
+        emitPtrByteGet (left, ptype, FALSE);
+    emitpcode(POC_ANDLW, popGetLit (1UL << bstr));
+    emitSKPZ;
+    /* adjust result below */
+        break;
+
+      default:
+        assert( !"unhandled pointer type" );
+      } // switch
+
+      /* move sign-/zero extended bit to result */
+      if (SPEC_USIGN(OP_SYM_ETYPE(left))) {
+    emitpcode (POC_INCF, popGet (AOP(result), 0));
+      } else {
+    emitpcode (POC_DECF, popGet (AOP(result), 0));
+      }
+      addSign (result, 1, !SPEC_USIGN(OP_SYM_ETYPE(left)));
+    }
+    return;
+  }
+  else if (blen <= 8 && ((blen + bstr) <= 8))
+  {
+    /* blen > 1 */
+    int i;
 
+    for (i=0; i < AOP_SIZE(result); i++)
+      emitpcode (POC_CLRF, popGet (AOP(result), i));
 
-  /* optimization - most of the time, left and result are the same
-   * address, but different types. for the pic code, we could omit
-   * the following
-   */
+    switch (ptype)
+    {
+    case -1:
+      mov2w(AOP(left), 0);
+      break;
 
-  aopOp(result,ic,TRUE);
+    case POINTER:
+    case FPOINTER:
+    case GPOINTER:
+    case CPOINTER:
+      emitPtrByteGet (left, ptype, FALSE);
+      break;
 
-  emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
+    default:
+      assert( !"unhandled pointer type" );
+    } // switch
 
-  size = AOP_SIZE(result);
+    if (blen < 8)
+      emitpcode(POC_ANDLW, popGetLit ((((1UL << blen)-1) << bstr) & 0x00ff));
+    movwf(AOP(result), 0);
+    AccRsh (popGet(AOP(result), 0), bstr, 1); /* zero extend the bitfield */
 
-  while (size--) {
-    emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
-    offset++;
+    if (!SPEC_USIGN(OP_SYM_ETYPE(left)) && (bstr + blen != 8))
+    {
+      /* signed bitfield */
+      assert (bstr + blen > 0);
+      emitpcode(POC_MOVLW, popGetLit (0x00ff << (bstr + blen)));
+      emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE), bstr + blen - 1, 0));
+      emitpcode(POC_IORWF, popGet(AOP(result),0));
+    }
+    addSign (result, 1, !SPEC_USIGN(OP_SYM_ETYPE(left)));
+    return;
   }
 
-  freeAsmop(left,NULL,ic,TRUE);
-  freeAsmop(result,NULL,ic,TRUE);
+  assert( !"bitfields larger than 8 bits or crossing byte boundaries are not yet supported" );
 }
 
+#if 1
 /*-----------------------------------------------------------------*/
-/* genNearPointerGet - pic14_emitcode for near pointer fetch             */
+/* genDataPointerGet - generates code when ptr offset is known     */
 /*-----------------------------------------------------------------*/
-static void genNearPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
+static void genDataPointerGet (operand *left,
+    operand *result,
+    iCode *ic)
 {
-    asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname ;
-    sym_link *rtype, *retype;
-    sym_link *ltype = operandType(left);    
-    char buffer[80];
+    int size , offset = 0;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    rtype = operandType(result);
-    retype= getSpec(rtype);
-    
-    aopOp(left,ic,FALSE);
-    
-    /* if left is rematerialisable and
-       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_IMMD &&
-       !IS_BITVAR(retype)         &&
-       DCL_TYPE(ltype) == POINTER) {
-       genDataPointerGet (left,result,ic);
-       return ;
-    }
-    
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-       /* 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 */
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       aop = newAsmop(0);
-       preg = getFreePtr(ic,&aop,FALSE);
-       pic14_emitcode("mov","%s,%s",
-               preg->name,
-               aopGet(AOP(left),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = aopGet(AOP(left),0,FALSE,FALSE);
-    
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp (result,ic,FALSE);
-    
-      /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-       genUnpackBits (result,rname,POINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(result);
-       int offset = 0 ;        
-       
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       while (size--) {
-           if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
+    /* optimization - most of the time, left and result are the same
+    * address, but different types. for the pic code, we could omit
+    * the following
+    */
+    aopOp(result,ic,TRUE);
 
-               pic14_emitcode("mov","a,@%s",rname);
-               aopPut(AOP(result),"a",offset);
-           } else {
-               sprintf(buffer,"@%s",rname);
-               aopPut(AOP(result),buffer,offset);
-           }
-           offset++ ;
-           if (size)
-               pic14_emitcode("inc","%s",rname);
-       }
-    }
+    if (pic14_sameRegs (AOP(left), AOP(result)))
+        return;
 
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* we had to allocate for this iCode */
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       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 */
-    DEBUGpic14_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--)
-               pic14_emitcode("dec","%s",rname);
-       }
+    DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+    //emitpcode(POC_MOVFW, popGet(AOP(left),0));
+
+    size = AOP_SIZE(result);
+    if (size > getSize(OP_SYM_ETYPE(left))) size = getSize(OP_SYM_ETYPE(left));
+
+    offset = 0;
+    while (size--) {
+        emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+        emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+        offset++;
     }
 
-    /* done */
+    freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
-     
 }
+#endif
 
 /*-----------------------------------------------------------------*/
-/* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
+/* genNearPointerGet - pic14_emitcode for near pointer fetch       */
 /*-----------------------------------------------------------------*/
-static void genPagedPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
+static void genNearPointerGet (operand *left,
+                               operand *result,
+                               iCode *ic)
 {
     asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname ;
-    sym_link *rtype, *retype;    
+    sym_link *ltype = operandType(left);
+    sym_link *rtype = operandType(result);
+    sym_link *retype= getSpec(rtype);      /* bitfield type information */
+    int direct = 0;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    rtype = operandType(result);
-    retype= getSpec(rtype);
-    
+
     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);
-       pic14_emitcode("mov","%s,%s",
-               preg->name,
-               aopGet(AOP(left),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = aopGet(AOP(left),0,FALSE,FALSE);
-    
-    freeAsmop(left,NULL,ic,TRUE);
+    /* if left is rematerialisable and
+    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 &&  //AOP_TYPE(left) == AOP_IMMD &&
+        !IS_BITVAR(retype)         &&
+        PIC_IS_DATA_PTR(ltype)) {
+        genDataPointerGet (left,result,ic);
+        return ;
+    }
+
+    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     aopOp (result,ic,FALSE);
 
-    /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-       genUnpackBits (result,rname,PPOINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(result);
-       int offset = 0 ;        
-       
-       while (size--) {
-           
-           pic14_emitcode("movx","a,@%s",rname);
-           aopPut(AOP(result),"a",offset);
-           
-           offset++ ;
-           
-           if (size)
-               pic14_emitcode("inc","%s",rname);
-       }
+    /* Check if can access directly instead of via a pointer */
+    if ((AOP_TYPE(left) == AOP_PCODE)
+        && (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
+        && (AOP_SIZE(result) == 1))
+    {
+        direct = 1;
     }
 
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* we had to allocate for this iCode */
-       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--)
-               pic14_emitcode("dec","%s",rname);
-       }
+    if (IS_BITFIELD(getSpec(operandType(result))))
+    {
+        genUnpackBits (result,left,direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
+        goto release;
     }
 
-    /* done */
-    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));
+    /* If the pointer value is not in a the FSR then need to put it in */
+    /* Must set/reset IRP bit for use with FSR. */
+    if (!direct)
+      setup_fsr (left);
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+//  sym_link *etype;
+    /* if bitfield then unpack the bits */
+    {
+        /* we have can just get the values */
+        int size = AOP_SIZE(result);
+        int offset = 0 ;
 
-    aopOp(left,ic,FALSE);
+        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    /* 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)
-            pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+        while(size--) {
+            if (direct)
+                emitpcode(POC_MOVWF,popGet(AOP(left),0));
+            else
+                emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+            if (AOP_TYPE(result) == AOP_LIT) {
+                emitpcode(POC_MOVLW,popGet(AOP(result),offset));
+            } else {
+                emitpcode(POC_MOVWF,popGet(AOP(result),offset));
             }
+            if (size && !direct)
+                emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+            offset++;
         }
     }
-    /* so dptr know contains the address */
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE);
-
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genUnpackBits(result,"dptr",FPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
 
-        while (size--) {
-            pic14_emitcode("movx","a,@dptr");
-            aopPut(AOP(result),"a",offset++);
-            if (size)
-                pic14_emitcode("inc","dptr");
+    /* now some housekeeping stuff */
+    if (aop) {
+        /* we had to allocate for this iCode */
+        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        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 */
+        DEBUGpic14_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--)
+                emitpcode(POC_DECF, popCopyReg(&pc_fsr));
         }
     }
 
+release:
+    /* done */
+    freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
+
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_emitcodePointerGet - gget value from code space                  */
+/* genGenPointerGet - gget value from generic pointer space        */
 /*-----------------------------------------------------------------*/
-static void pic14_emitcodePointerGet (operand *left,
-                                operand *result, iCode *ic)
+static void genGenPointerGet (operand *left,
+                              operand *result, iCode *ic)
 {
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(result));
-
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
     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)
-            pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
-            }
-        }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(left,NULL,ic,TRUE);
     aopOp(result,ic,FALSE);
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genUnpackBits(result,"dptr",CPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
 
-        while (size--) {
-            pic14_emitcode("clr","a");
-            pic14_emitcode("movc","a,@a+dptr");
-            aopPut(AOP(result),"a",offset++);
-            if (size)
-                pic14_emitcode("inc","dptr");
-        }
+    DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+    if (IS_BITFIELD(getSpec(operandType(result))))
+    {
+      genUnpackBits (result, left, GPOINTER, ifxForOp (IC_RESULT(ic), ic));
+      return;
+    }
+
+    {
+      /* emit call to __gptrget */
+      char *func[] = {NULL, "__gptrget1", "__gptrget2", "__gptrget3", "__gptrget4"};
+      int size = AOP_SIZE(result);
+      int idx = 0;
+
+      assert (size > 0 && size <= 4);
+
+      /* pass arguments */
+      assert (AOP_SIZE(left) == 3);
+      mov2w(AOP(left), 0);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
+      mov2w(AOP(left), 1);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+      mov2w(AOP(left), 2);
+      call_libraryfunc (func[size]);
+
+      /* save result */
+      movwf (AOP(result), --size);
+      while (size--) {
+        emitpcode (POC_MOVFW,popRegFromIdx (Gstack_base_addr - idx++));
+        movwf (AOP(result), size);
+      } // while
     }
 
+    freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
+
 }
 
 /*-----------------------------------------------------------------*/
-/* genGenPointerGet - gget value from generic pointer space        */
+/* genConstPointerGet - get value from const generic pointer space */
 /*-----------------------------------------------------------------*/
-static void genGenPointerGet (operand *left,
-                              operand *result, iCode *ic)
+static void genConstPointerGet (operand *left,
+                                operand *result, iCode *ic)
 {
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(result));
+    //sym_link *retype = getSpec(operandType(result));
+    #if 0
+    symbol *albl, *blbl;//, *clbl;
+    pCodeOp *pcop;
+    #endif
+    PIC_OPCODE poc;
+    int i, size, lit;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     aopOp(left,ic,FALSE);
+    aopOp(result,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) {
-            pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
-           pic14_emitcode("mov","b,#%d",pointerCode(retype));
-       }
-        else { /* we need to get it byte by byte */
-         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
-         //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
-         //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
-         pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
-         pic14_emitcode("movwf","FSR");
-         /*
-            pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
-               pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
-            }
-            else
-            {
-               pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
-            }
-         */
-        }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE); 
+    size = AOP_SIZE(result);
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genUnpackBits(result,"dptr",GPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
+    DEBUGpic14_AopType(__LINE__,left,NULL,result);
 
-        while (size--) {
-         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+    DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
 
-         emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
-         if(size)
-           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
-/*
-         pic14_emitcode("movf","indf,w");
-         pic14_emitcode("movwf","%s",
-                  aopGet(AOP(result),offset++,FALSE,FALSE));
-         if (size)
-           pic14_emitcode("incf","fsr,f");
-*/
-        }
+    lit = op_isLitLike (left);
+    poc = lit ? POC_MOVLW : POC_MOVFW;
+
+    if (IS_BITFIELD(getSpec(operandType(result))))
+    {
+        genUnpackBits (result, left, lit ? -1 : CPOINTER, ifxForOp (IC_RESULT(ic), ic));
+        goto release;
+    }
+
+    {
+        char *func[] = { NULL, "__gptrget1", "__gptrget2", "__gptrget3", "__gptrget4" };
+        int size = min(getSize(OP_SYM_ETYPE(left)), AOP_SIZE(result));
+        assert (size > 0 && size <= 4);
+
+        mov2w_op(left, 0);
+        emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
+        mov2w_op(left, 1);
+        emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+        emitpcode(POC_MOVLW, popGetLit (GPTRTAG_CODE)); /* GPOINTER tag for __code space */
+        call_libraryfunc (func[size]);
+
+        movwf(AOP(result),size-1);
+        for (i = 1; i < size; i++)
+        {
+            emitpcode(POC_MOVFW, popRegFromIdx (Gstack_base_addr+1-i));
+            movwf(AOP(result),size - 1 - i);
+        } // for
     }
 
+release:
+    freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
-}
 
+}
 /*-----------------------------------------------------------------*/
 /* genPointerGet - generate code for pointer get                   */
 /*-----------------------------------------------------------------*/
@@ -7257,8 +5600,9 @@ static void genPointerGet (iCode *ic)
 {
     operand *left, *result ;
     sym_link *type, *etype;
-    int p_type;
+    int p_type = -1;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     left = IC_LEFT(ic);
@@ -7268,53 +5612,68 @@ static void genPointerGet (iCode *ic)
     move it to the correct pointer register */
     type = operandType(left);
     etype = getSpec(type);
+
+    if (IS_PTR_CONST(type))
+        DEBUGpic14_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 */
-       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));
+
+        DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
+
+        if (SPEC_OCLS(etype)->codesp ) {
+            DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
+            //p_type = CPOINTER ;
+        }
+        else
+            if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
+                DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
+            /*p_type = FPOINTER ;*/
+            else
+                if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
+                    DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
+                /*        p_type = PPOINTER; */
+                else
+                    if (SPEC_OCLS(etype) == idata )
+                        DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
+                    /*      p_type = IPOINTER; */
+                    else
+                        DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
+                    /*      p_type = POINTER ; */
     }
 
     /* now that we have the pointer type we assign
     the pointer values */
     switch (p_type) {
 
-    case POINTER:      
-    case IPOINTER:
-       genNearPointerGet (left,result,ic);
-       break;
-
+    case POINTER:
+    case FPOINTER:
+    //case IPOINTER:
+        genNearPointerGet (left,result,ic);
+        break;
+/*
     case PPOINTER:
-       genPagedPointerGet(left,result,ic);
-       break;
+        genPagedPointerGet(left,result,ic);
+        break;
 
     case FPOINTER:
-       genFarPointerGet (left,result,ic);
-       break;
-
+        genFarPointerGet (left,result,ic);
+        break;
+*/
     case CPOINTER:
-       pic14_emitcodePointerGet (left,result,ic);
-       break;
+        genConstPointerGet (left,result,ic);
+        break;
 
     case GPOINTER:
-       genGenPointerGet (left,result,ic);
-       break;
+        genGenPointerGet (left,result,ic);
+        break;
+    default:
+        assert ( !"unhandled pointer type" );
+        break;
     }
 
 }
@@ -7322,206 +5681,244 @@ static void genPointerGet (iCode *ic)
 /*-----------------------------------------------------------------*/
 /* genPackBits - generates code for packed bit storage             */
 /*-----------------------------------------------------------------*/
-static void genPackBits (sym_link    *etype ,
-                         operand *right ,
-                         char *rname, int p_type)
+static void genPackBits(sym_link *etype,operand *result,operand *right,int p_type)
 {
-    int shCount = 0 ;
-    int offset = 0  ;
-    int rLen = 0 ;
-    int blen, bstr ;   
-    char *l ;
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    blen = SPEC_BLEN(etype);
-    bstr = SPEC_BSTR(etype);
-
-    l = aopGet(AOP(right),offset++,FALSE,FALSE);
-    MOVA(l);   
-
-    /* if the bit lenth is less than or    */
-    /* it exactly fits a byte then         */
-    if (SPEC_BLEN(etype) <= 8 )  {
-        shCount = SPEC_BSTR(etype) ;
-
-        /* shift left acc */
-        AccLsh(shCount);
-
-        if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
-
+  int blen;             /* bitfield length */
+  int bstr;             /* bitfield starting bit within byte */
+  int litval;           /* source literal value (if AOP_LIT) */
+  unsigned char mask;   /* bitmask within current byte */
 
-            switch (p_type) {
-                case POINTER:
-                    pic14_emitcode ("mov","b,a");
-                    pic14_emitcode("mov","a,@%s",rname);
-                    break;
-
-                case FPOINTER:
-                    pic14_emitcode ("mov","b,a");
-                    pic14_emitcode("movx","a,@dptr");
-                    break;
-
-                case GPOINTER:
-                    pic14_emitcode ("push","b");
-                    pic14_emitcode ("push","acc");
-                    pic14_emitcode ("lcall","__gptrget");
-                    pic14_emitcode ("pop","b");
-                    break;
-            }
+  FENTRY;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-            pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
-                      ((unsigned char)(0xFF << (blen+bstr)) | 
-                       (unsigned char)(0xFF >> (8-bstr)) ) );
-            pic14_emitcode ("orl","a,b");
-            if (p_type == GPOINTER)
-                pic14_emitcode("pop","b");
-        }
-    }
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
 
-    switch (p_type) {
-        case POINTER:
-            pic14_emitcode("mov","@%s,a",rname);
-            break;
+  /* If the bitfield length is less than a byte and does not cross byte boundaries */
+  if ((blen <= 8) && ((bstr + blen) <= 8))
+  {
+    mask = ((unsigned char) (0xFF << (blen + bstr)) |
+        (unsigned char) (0xFF >> (8 - bstr)));
 
-        case FPOINTER:
-            pic14_emitcode("movx","@dptr,a");
-            break;
+    if (AOP_TYPE (right) == AOP_LIT)
+    {
+      /* Case with a bitfield length <8 and literal source */
+      int lit = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+      if (blen == 1) {
+        pCodeOp *pcop;
 
-        case GPOINTER:
-            DEBUGpic14_emitcode(";lcall","__gptrput");
-            break;
-    }
+    switch (p_type)
+    {
+    case -1:
+      if (AOP(result)->type == AOP_PCODE)
+        pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
+      else
+        pcop = popGet(AOP(result),0);
+      emitpcode(lit?POC_BSF:POC_BCF,pcop);
+      break;
 
-    /* if we r done */
-    if ( SPEC_BLEN(etype) <= 8 )
-        return ;
+    case POINTER:
+    case FPOINTER:
+      setup_fsr (result);
+      emitpcode(lit?POC_BSF:POC_BCF,newpCodeOpBit(PCOP(&pc_indf)->name,bstr,0));
+      break;
 
-    pic14_emitcode("inc","%s",rname);
-    rLen = SPEC_BLEN(etype) ;     
+    case CPOINTER:
+      assert( !"trying to assign to bitfield via pointer to __code space" );
+      break;
 
-    /* now generate for lengths greater than one byte */
-    while (1) {
+    case GPOINTER:
+      emitPtrByteGet(result, p_type, FALSE);
+      if (lit) {
+        emitpcode(POC_IORLW, newpCodeOpLit (1UL << bstr));
+      } else {
+        emitpcode(POC_ANDLW, newpCodeOpLit ((~(1UL << bstr)) & 0x0ff));
+      }
+      emitPtrByteSet(result, p_type, TRUE);
+      break;
 
-        l = aopGet(AOP(right),offset++,FALSE,TRUE);
+    default:
+      assert( !"unhandled pointer type" );
+      break;
+    } // switch (p_type)
+      } else {
+        /* blen > 1 */
+    litval = lit << bstr;
+    litval &= (~mask) & 0x00ff;
 
-        rLen -= 8 ;
-        if (rLen <= 0 )
-            break ;
+    switch (p_type)
+    {
+    case -1:
+      mov2w (AOP(result), 0);
+      if ((litval|mask) != 0x00ff)
+        emitpcode(POC_ANDLW, popGetLit (mask));
+      if (litval != 0x00)
+        emitpcode(POC_IORLW, popGetLit (litval));
+      movwf (AOP(result), 0);
+      break;
 
-        switch (p_type) {
-            case POINTER:
-                if (*l == '@') {
-                    MOVA(l);
-                    pic14_emitcode("mov","@%s,a",rname);
-                } else
-                    pic14_emitcode("mov","@%s,%s",rname,l);
-                break;
+    case POINTER:
+    case FPOINTER:
+    case GPOINTER:
+      emitPtrByteGet(result, p_type, FALSE);
+      if ((litval|mask) != 0x00ff)
+        emitpcode(POC_ANDLW, popGetLit (mask));
+      if (litval != 0x00)
+        emitpcode(POC_IORLW, popGetLit (litval));
+      emitPtrByteSet(result, p_type, TRUE);
+      break;
 
-            case FPOINTER:
-                MOVA(l);
-                pic14_emitcode("movx","@dptr,a");
-                break;
+    case CPOINTER:
+      assert( !"trying to assign to bitfield via pointer to __code space" );
+      break;
 
-            case GPOINTER:
-                MOVA(l);
-                DEBUGpic14_emitcode(";lcall","__gptrput");
-                break;  
-        }   
-        pic14_emitcode ("inc","%s",rname);
+    default:
+      assert( !"unhandled pointer type" );
+      break;
+    } // switch
+      } // if (blen > 1)
     }
+    else
+    {
+      /* right is no literal */
+      if (blen==1) {
+        switch (p_type)
+    {
+    case -1:
+      /* Note more efficient code, of pre clearing bit then only setting it if required,
+       * can only be done if it is known that the result is not a SFR */
+      emitpcode(POC_RRFW,popGet(AOP(right),0));
+      emitSKPC;
+      emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+      emitSKPNC;
+      emitpcode(POC_BSF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+      break;
 
-    MOVA(l);
+    case POINTER:
+    case FPOINTER:
+    case GPOINTER:
+      emitPtrByteGet (result, p_type, FALSE);
+      emitpcode(POC_BTFSS, newpCodeOpBit (aopGet(AOP(right), 0, FALSE, FALSE), bstr, 0));
+      emitpcode(POC_ANDLW, newpCodeOpLit (~(1UL << bstr) & 0x0ff));
+      emitpcode(POC_BTFSC, newpCodeOpBit (aopGet(AOP(right), 0, FALSE, FALSE), bstr, 0));
+      emitpcode(POC_IORLW, newpCodeOpLit ((1UL << bstr) & 0x0ff));
+      emitPtrByteSet (result, p_type, TRUE);
+      break;
 
-    /* last last was not complete */
-    if (rLen)   {
-        /* save the byte & read byte */
-        switch (p_type) {
-            case POINTER:
-                pic14_emitcode ("mov","b,a");
-                pic14_emitcode("mov","a,@%s",rname);
-                break;
-
-            case FPOINTER:
-                pic14_emitcode ("mov","b,a");
-                pic14_emitcode("movx","a,@dptr");
-                break;
-
-            case GPOINTER:
-                pic14_emitcode ("push","b");
-                pic14_emitcode ("push","acc");
-                pic14_emitcode ("lcall","__gptrget");
-                pic14_emitcode ("pop","b");
-                break;
-        }
+    case CPOINTER:
+      assert( !"trying to assign to bitfield via pointer to __code space" );
+      break;
 
-        pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
-        pic14_emitcode ("orl","a,b");
-    }
+    default:
+      assert( !"unhandled pointer type" );
+      break;
+    } // switch
+    return;
+      } else {
+    /* Case with a bitfield 1 < length <= 8 and arbitrary source */
+    pCodeOp *temp = popGetTempReg ();
 
-    if (p_type == GPOINTER)
-        pic14_emitcode("pop","b");
+    mov2w (AOP(right), 0);
+    if (blen < 8) {
+      emitpcode (POC_ANDLW, popGetLit ((1UL << blen)-1));
+    }
+    emitpcode(POC_MOVWF, temp);
+    if (bstr) {
+      AccLsh (temp, bstr);
+    }
 
-    switch (p_type) {
+    switch (p_type)
+    {
+    case -1:
+      mov2w (AOP(result), 0);
+      emitpcode(POC_ANDLW, popGetLit (mask));
+      emitpcode(POC_IORFW, temp);
+      movwf (AOP(result), 0);
+      break;
 
     case POINTER:
-       pic14_emitcode("mov","@%s,a",rname);
-       break;
-       
     case FPOINTER:
-       pic14_emitcode("movx","@dptr,a");
-       break;
-       
     case GPOINTER:
-       DEBUGpic14_emitcode(";lcall","__gptrput");
-       break;                  
-    }
+      emitPtrByteGet (result, p_type, FALSE);
+      emitpcode(POC_ANDLW, popGetLit (mask));
+      emitpcode(POC_IORFW, temp);
+      emitPtrByteSet (result, p_type, TRUE);
+      break;
+
+    case CPOINTER:
+      assert( !"trying to assign to bitfield via pointer to __code space" );
+      break;
+
+    default:
+      assert( !"unhandled pointer type" );
+      break;
+    } // switch
+
+    popReleaseTempReg (temp);
+      } // if (blen > 1)
+    } // if (AOP(right)->type != AOP_LIT)
+    return;
+  } // if (blen <= 8 && ((blen + bstr) <= 8))
+
+  assert( !"bitfields larger than 8 bits or crossing byte boundaries are not yet supported" );
 }
+
 /*-----------------------------------------------------------------*/
 /* genDataPointerSet - remat pointer to data space                 */
 /*-----------------------------------------------------------------*/
 static void genDataPointerSet(operand *right,
-                             operand *result,
-                             iCode *ic)
+    operand *result,
+    iCode *ic)
 {
     int size, offset = 0 ;
-    char *l, buffer[256];
+    int ressize;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     aopOp(right,ic,FALSE);
-    
-    l = aopGet(AOP(result),0,FALSE,TRUE);
-    size = AOP_SIZE(right);
-    // tsd, was l+1 - the underline `_' prefix was being stripped
-    while (size--) {
-       if (offset)
-           sprintf(buffer,"(%s + %d)",l,offset);
-       else
-           sprintf(buffer,"%s",l);
+    aopOp(result,ic,FALSE);
 
-       if (AOP_TYPE(right) == AOP_LIT) {
-         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
-         lit = lit >> (8*offset);
-         if(lit&0xff) {
-           pic14_emitcode("movlw","%d",lit);
-           pic14_emitcode("movwf","%s",buffer);
+    assert (IS_SYMOP(result));
+    assert (IS_PTR(OP_SYM_TYPE(result)));
+
+    if (AOP_TYPE(right) == AOP_LIT)
+      size = 4;
+    else
+      size = AOP_SIZE(right);
+    ressize = getSize(OP_SYM_ETYPE(result));
+    if (size > ressize) size = ressize;
+    //fprintf (stderr, "%s:%u: size(right): %d, size(result): %d\n", __FUNCTION__,__LINE__, AOP_SIZE(right), ressize);
 
-           emitpcode(POC_MOVLW, popGetLit(lit&0xff));
-           emitpcode(POC_MOVWF, popRegFromString(buffer));
+    //assert( !"what's going on here?" );
 
-         } else {
-           pic14_emitcode("clrf","%s",buffer);
-           emitpcode(POC_CLRF, popRegFromString(buffer));
-         }
-       }else {
-         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-         pic14_emitcode("movwf","%s",buffer);
+    /*
+    if ( AOP_TYPE(result) == AOP_PCODE) {
+    fprintf(stderr,"genDataPointerSet   %s, %d\n",
+    AOP(result)->aopu.pcop->name,
+    PCOI(AOP(result)->aopu.pcop)->offset);
+    }
+    */
 
-         emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
-         emitpcode(POC_MOVWF, popRegFromString(buffer));
+    // tsd, was l+1 - the underline `_' prefix was being stripped
+    while (size--) {
+        emitpComment ("%s:%u: size=%d/%d, offset=%d, AOP_TYPE(res)=%d", __FILE__,__LINE__, size, ressize, offset, AOP_TYPE(result));
 
-       }
+        if (AOP_TYPE(right) == AOP_LIT) {
+            unsigned int lit = pic14aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset);
+            //fprintf (stderr, "%s:%u: lit %d 0x%x\n", __FUNCTION__,__LINE__, lit, lit);
+            if(lit&0xff) {
+                emitpcode(POC_MOVLW, popGetLit(lit&0xff));
+                emitpcode(POC_MOVWF, popGet(AOP(result), offset));
+            } else {
+                emitpcode(POC_CLRF, popGet(AOP(result), offset));
+            }
+        } else {
+            //fprintf (stderr, "%s:%u: no lit\n", __FUNCTION__,__LINE__);
+            emitpcode(POC_MOVFW, popGet(AOP(right), offset));
+            emitpcode(POC_MOVWF, popGet(AOP(result), offset));
+        }
 
-       offset++;
+        offset++;
     }
 
     freeAsmop(right,NULL,ic,TRUE);
@@ -7529,90 +5926,84 @@ static void genDataPointerSet(operand *right,
 }
 
 /*-----------------------------------------------------------------*/
-/* genNearPointerSet - pic14_emitcode for near pointer put                */
+/* genNearPointerSet - pic14_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 *retype = getSpec(operandType(right));
+    sym_link *letype = getSpec(ptype);
+    int direct = 0;
 
-    
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    retype= getSpec(operandType(right));
 
+    FENTRY;
+    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     aopOp(result,ic,FALSE);
-    
+
+#if 1
     /* if the result is rematerializable &
-       in data space & not a bit variable */
-    if (AOP_TYPE(result) == AOP_IMMD &&
-       DCL_TYPE(ptype) == POINTER   &&
-       !IS_BITVAR(retype)) {
-       genDataPointerSet (right,result,ic);
-       return;
+    in data space & not a bit variable */
+    //if (AOP_TYPE(result) == AOP_IMMD &&
+    if (AOP_TYPE(result) == AOP_PCODE &&
+        PIC_IS_DATA_PTR(ptype) &&
+        !IS_BITVAR (retype) &&
+        !IS_BITVAR (letype)) {
+        genDataPointerSet (right,result,ic);
+        freeAsmop(result,NULL,ic,TRUE);
+        return;
     }
+#endif
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    aopOp(right,ic,FALSE);
+    DEBUGpic14_AopType(__LINE__,NULL,right,result);
 
-    /* if the value is already in a pointer register
-    then don't need anything more */
-    if (!AOP_INPREG(AOP(result))) {
-        /* otherwise get a free pointer register */
-        //aop = newAsmop(0);
-        //preg = getFreePtr(ic,&aop,FALSE);
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       //pic14_emitcode("mov","%s,%s",
-        //         preg->name,
-        //         aopGet(AOP(result),0,FALSE,TRUE));
-        //rname = preg->name ;
-       pic14_emitcode("movwf","fsr");
-    }// else
-    //   rname = aopGet(AOP(result),0,FALSE,FALSE);
-
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp (right,ic,FALSE);
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    /* Check if can access directly instead of via a pointer */
+    if ((AOP_TYPE(result) == AOP_PCODE)
+        && (AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
+        && (AOP_SIZE(right) == 1))
+    {
+        direct = 1;
+    }
 
-    /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) {
-      werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-            "The programmer is obviously confused");
-      //genPackBits (retype,right,rname,POINTER);
-      exit(1);
+    if (IS_BITFIELD (letype))
+    {
+      genPackBits (letype, result, right, direct?-1:POINTER);
+      return;
     }
-    else {
+
+    /* If the pointer value is not in a the FSR then need to put it in */
+    /* Must set/reset IRP bit for use with FSR. */
+    /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
+    if (!direct)
+        setup_fsr (result);
+
+    {
         /* we have can just get the values */
         int size = AOP_SIZE(right);
-        int offset = 0 ;    
+        int offset = 0 ;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
         while (size--) {
-            l = aopGet(AOP(right),offset,FALSE,TRUE);
+            char *l = aopGet(AOP(right),offset,FALSE,TRUE);
             if (*l == '@' ) {
-             //MOVA(l);
-             //pic14_emitcode("mov","@%s,a",rname);
-             pic14_emitcode("movf","indf,w ;1");
+                emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
             } else {
-
-             if (AOP_TYPE(right) == AOP_LIT) {
-               unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
-               if(lit) {
-                 pic14_emitcode("movlw","%s",l);
-                 pic14_emitcode("movwf","indf ;2");
-               } else 
-                 pic14_emitcode("clrf","indf");
-             }else {
-               pic14_emitcode("movf","%s,w",l);
-               pic14_emitcode("movwf","indf ;2");
-             }
-           //pic14_emitcode("mov","@%s,%s",rname,l);
-           }
-            if (size)
-             pic14_emitcode("incf","fsr,f ;3");
-           //pic14_emitcode("inc","%s",rname);
+                if (AOP_TYPE(right) == AOP_LIT) {
+                    emitpcode(POC_MOVLW,popGet(AOP(right),offset));
+                } else {
+                    emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+                }
+                if (direct)
+                    emitpcode(POC_MOVWF,popGet(AOP(result),0));
+                else
+                    emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
+            }
+            if (size && !direct)
+                emitpcode(POC_INCF,popCopyReg(&pc_fsr));
             offset++;
         }
     }
@@ -7622,232 +6013,105 @@ static void genNearPointerSet (operand *right,
     if (aop) {
         /* we had to allocate for this iCode */
         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 */
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
         if (AOP_SIZE(right) > 1 &&
             !OP_SYMBOL(result)->remat &&
             ( OP_SYMBOL(result)->liveTo > ic->seq ||
-              ic->depth )) {
+            ic->depth )) {
             int size = AOP_SIZE(right) - 1;
             while (size--)
-             pic14_emitcode("decf","fsr,f");
-             //pic14_emitcode("dec","%s",rname);
+                emitpcode(POC_DECF, popCopyReg(&pc_fsr));
         }
     }
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* done */
-    freeAsmop(right,NULL,ic,TRUE);
-
-
-}
-
-/*-----------------------------------------------------------------*/
-/* genPagedPointerSet - pic14_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;
-       
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-    retype= getSpec(operandType(right));
-    
-    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);
-       pic14_emitcode("mov","%s,%s",
-               preg->name,
-               aopGet(AOP(result),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = aopGet(AOP(result),0,FALSE,FALSE);
-    
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp (right,ic,FALSE);
-
-    /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-       genPackBits (retype,right,rname,PPOINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(right);
-       int offset = 0 ;        
-       
-       while (size--) {
-           l = aopGet(AOP(right),offset,FALSE,TRUE);
-           
-           MOVA(l);
-           pic14_emitcode("movx","@%s,a",rname);
-
-           if (size)
-               pic14_emitcode("inc","%s",rname);
-
-           offset++;
-       }
-    }
-    
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* we had to allocate for this iCode */
-       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--)
-               pic14_emitcode("dec","%s",rname);
-       }
-    }
 
-    /* done */
     freeAsmop(right,NULL,ic,TRUE);
-    
-       
-}
-
-/*-----------------------------------------------------------------*/
-/* genFarPointerSet - set value from far space                     */
-/*-----------------------------------------------------------------*/
-static void genFarPointerSet (operand *right,
-                              operand *result, iCode *ic)
-{
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(right));
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    aopOp(result,ic,FALSE);
-
-    /* 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)
-            pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
-            pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
-            }
-        }
-    }
-    /* so dptr know contains the address */
     freeAsmop(result,NULL,ic,TRUE);
-    aopOp(right,ic,FALSE);
-
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genPackBits(retype,right,"dptr",FPOINTER);
-    else {
-        size = AOP_SIZE(right);
-        offset = 0 ;
-
-        while (size--) {
-            char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
-            MOVA(l);
-            pic14_emitcode("movx","@dptr,a");
-            if (size)
-                pic14_emitcode("inc","dptr");
-        }
-    }
-
-    freeAsmop(right,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genGenPointerSet - set value from generic pointer space         */
 /*-----------------------------------------------------------------*/
-static void genGenPointerSet (operand *right,
-                              operand *result, iCode *ic)
+static void genGenPointerSet (operand *right, operand *result, iCode *ic)
 {
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(right));
+    sym_link *retype = getSpec(operandType(result));
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-
+    aopOp(right,ic,FALSE);
     aopOp(result,ic,FALSE);
 
-    /* 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) {
-            pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
-            pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
-        }
-        else { /* we need to get it byte by byte */
-         char *l = aopGet(AOP(result),0,FALSE,FALSE);
-
-         if(strcmp("FSR",l))
-           emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
-         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
 
-         if(strcmp("FSR",l))
-           pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
+    DEBUGpic14_AopType(__LINE__,right,NULL,result);
 
-         pic14_emitcode("movwf","INDF");
-        }
+    if (IS_BITFIELD(retype))
+    {
+      genPackBits (retype, result, right, GPOINTER);
+      return;
     }
-    /* so dptr know contains the address */
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp(right,ic,FALSE);
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genPackBits(retype,right,"dptr",GPOINTER);
-    else {
-        size = AOP_SIZE(right);
-        offset = 0 ;
-
-        while (--size) {
-         //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
-           if(size)
-             pic14_emitcode("incf","fsr,f");
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
-           pic14_emitcode("movwf","indf");
-            //MOVA(l);
-            //DEBUGpic14_emitcode(";lcall","__gptrput");
-            //if (size)
-            //    pic14_emitcode("inc","dptr");
+    {
+      /* emit call to __gptrput */
+      char *func[] = {NULL, "__gptrput1", "__gptrput2", "__gptrput3", "__gptrput4"};
+      int size = AOP_SIZE(right);
+      int idx = 0;
+
+      /* The following assertion fails for
+       *   struct foo { char a; char b; } bar;
+       *   void demo(struct foo *dst, char c) { dst->b = c; }
+       * as size will be 1 (sizeof(c)), whereas dst->b will be accessed
+       * using (((char *)dst)+1), whose OP_SYM_ETYPE still is struct foo
+       * of size 2.
+       * The frontend seems to guarantee that IC_LEFT has the correct size,
+       * it works fine both for larger and smaller types of `char c'.
+       * */
+      //assert (size == getSize(OP_SYM_ETYPE(result)));
+      assert (size > 0 && size <= 4);
+
+      /* pass arguments */
+      /* - value (MSB in Gstack_base_addr-2, growing downwards) */
+      {
+        int off = size;
+        idx = 2;
+        while (off--)
+        {
+          mov2w_op (right, off);
+          emitpcode (POC_MOVWF, popRegFromIdx (Gstack_base_addr - idx++));
         }
+        idx = 0;
+      }
+      /* - address */
+      assert (AOP_SIZE(result) == 3);
+      mov2w(AOP(result), 0);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr - 1));
+      mov2w(AOP(result), 1);
+      emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+      mov2w(AOP(result), 2);
+      call_libraryfunc (func[size]);
     }
 
     freeAsmop(right,NULL,ic,TRUE);
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genPointerSet - stores the value into a pointer location        */
 /*-----------------------------------------------------------------*/
 static void genPointerSet (iCode *ic)
-{    
+{
     operand *right, *result ;
     sym_link *type, *etype;
     int p_type;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     right = IC_RIGHT(ic);
@@ -7862,23 +6126,23 @@ static void genPointerSet (iCode *ic)
         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
@@ -7886,23 +6150,27 @@ static void genPointerSet (iCode *ic)
     switch (p_type) {
 
     case POINTER:
-    case IPOINTER:
-       genNearPointerSet (right,result,ic);
-       break;
-
+    case FPOINTER:
+    //case IPOINTER:
+        genNearPointerSet (right,result,ic);
+        break;
+/*
     case PPOINTER:
-       genPagedPointerSet (right,result,ic);
-       break;
+        genPagedPointerSet (right,result,ic);
+        break;
 
     case FPOINTER:
-       genFarPointerSet (right,result,ic);
-       break;
-
+        genFarPointerSet (right,result,ic);
+        break;
+*/
     case GPOINTER:
-       genGenPointerSet (right,result,ic);
-       break;
-    }
+        genGenPointerSet (right,result,ic);
+        break;
 
+    default:
+        werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+            "genPointerSet: illegal pointer type");
+    }
 }
 
 /*-----------------------------------------------------------------*/
@@ -7913,7 +6181,9 @@ static void genIfx (iCode *ic, iCode *popIc)
     operand *cond = IC_COND(ic);
     int isbit =0;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
     aopOp(cond,ic,FALSE);
 
     /* get the value into acc */
@@ -7921,33 +6191,54 @@ static void genIfx (iCode *ic, iCode *popIc)
         pic14_toBoolean(cond);
     else
         isbit = 1;
-    /* the result is now in the accumulator */
-    freeAsmop(cond,NULL,ic,TRUE);
 
     /* if there was something to be popped then do it */
     if (popIc)
         genIpop(popIc);
 
-    /* if the condition is  a bit variable */
-    if (isbit && IS_ITEMP(cond) && 
-       SPIL_LOC(cond)) {
-      genIfxJump(ic,SPIL_LOC(cond)->rname);
-      DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
+    if (isbit)
+    {
+        /* This assumes that CARRY is set iff cond is true */
+        if (IC_TRUE(ic))
+        {
+            assert (!IC_FALSE(ic));
+            emitpcode(POC_BTFSC, popGet(AOP(cond), 0));
+            //emitSKPNC;
+            emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key));
+        } else {
+            assert (IC_FALSE(ic));
+            emitpcode(POC_BTFSS, popGet(AOP(cond), 0));
+            //emitSKPC;
+            emitpcode(POC_GOTO, popGetLabel(IC_FALSE(ic)->key));
+        }
+        if (0)
+        {
+            static int hasWarned = 0;
+            if (!hasWarned)
+            {
+                fprintf (stderr, "WARNING: using untested code for %s:%u -- please check the .asm output and report bugs.\n", ic->filename, ic->lineno);
+                hasWarned = 1;
+            }
+        }
     }
-    else {
-      /*
-       if (isbit && !IS_ITEMP(cond))
-         DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
-       else
-         DEBUGpic14_emitcode ("; isbit","a");
-      */
-
-       if (isbit && !IS_ITEMP(cond))
-           genIfxJump(ic,OP_SYMBOL(cond)->rname);
-       else
-           genIfxJump(ic,"a");
+    else
+    {
+        /* now Z is set iff !cond */
+        if (IC_TRUE(ic))
+        {
+            assert (!IC_FALSE(ic));
+            emitSKPZ;
+            emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key));
+        } else {
+            emitSKPNZ;
+            emitpcode(POC_GOTO, popGetLabel(IC_FALSE(ic)->key));
+        }
     }
+
     ic->generated = 1;
+
+    /* the result is now in the accumulator */
+    freeAsmop(cond,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7955,102 +6246,73 @@ static void genIfx (iCode *ic, iCode *popIc)
 /*-----------------------------------------------------------------*/
 static void genAddrOf (iCode *ic)
 {
-    symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+    operand *right, *result, *left;
     int size, offset ;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    aopOp(IC_RESULT(ic),ic,FALSE);
 
-    /* if the operand is on the stack then we 
-    need to get the stack offset of this
-    variable */
-    if (sym->onStack) {
-        /* if it has an offset then we need to compute
-        it */
-        if (sym->stack) {
-            pic14_emitcode("mov","a,_bp");
-            pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
-            aopPut(AOP(IC_RESULT(ic)),"a",0);       
-        } else {
-            /* we can just move _bp */
-            aopPut(AOP(IC_RESULT(ic)),"_bp",0);
-        }
-        /* fill the result with zero */
-        size = AOP_SIZE(IC_RESULT(ic)) - 1;
-        
-        
-        if (options.stack10bit && size < (FPTRSIZE - 1))
-        {
-            fprintf(stderr, 
-                   "*** warning: pointer to stack var truncated.\n");
-        }
-        
-        offset = 1;
-        while (size--)
-        {
-            /* Yuck! */
-            if (options.stack10bit && offset == 2)
-            {
-                aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
-            }
-            else
-            {
-               aopPut(AOP(IC_RESULT(ic)),zero,offset++);
-            }
-        }
+    //aopOp(IC_RESULT(ic),ic,FALSE);
 
-        goto release;
+    aopOp((left=IC_LEFT(ic)),ic,FALSE);
+    aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+    aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+    DEBUGpic14_AopType(__LINE__,left,right,result);
+    assert (IS_SYMOP (left));
+
+    /* sanity check: generic pointers to code space are not yet supported,
+     * pionters to codespace must not be assigned addresses of __data values. */
+ #if 0
+    fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name);
+    fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result)));
+    fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result)));
+    fprintf (stderr, "left->type   : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left)));
+    fprintf (stderr, "left->etype  : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left)));
+#endif
+
+    if (IS_SYMOP(result) && IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) {
+      fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n",
+        IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+        OP_SYMBOL(left)->name);
+    } else if (IS_SYMOP(result) && !IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) {
+      fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n",
+        IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+        OP_SYMBOL(left)->name);
     }
 
-    /* object not on stack then we need the name */
     size = AOP_SIZE(IC_RESULT(ic));
+    if (IS_SYMOP(result) && IS_GENPTR(OP_SYM_TYPE(result))) {
+        /* strip tag */
+        if (size > GPTRSIZE-1) size = GPTRSIZE-1;
+    }
     offset = 0;
 
     while (size--) {
-        char s[SDCC_NAME_MAX];
-        if (offset) 
-            sprintf(s,"#(%s >> %d)",
-                    sym->rname,
-                    offset*8);
-        else
-            sprintf(s,"#%s",sym->rname);
-        aopPut(AOP(IC_RESULT(ic)),s,offset++);
-    }
-
-release:
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-
-}
+        /* fixing bug #863624, reported from (errolv) */
+        emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
+        emitpcode(POC_MOVWF, popGet(AOP(result), offset));
 
 #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 = aopGet(AOP(right),offset++,FALSE,FALSE);
-       MOVA(l);
-       pic14_emitcode ("push","acc");
+        emitpcode(POC_MOVLW, popGet(AOP(left),offset));
+        emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+#endif
+        offset++;
     }
-    
-    freeAsmop(right,NULL,ic,FALSE);
-    /* now assign DPTR to result */
-    aopOp(result,ic,FALSE);
-    size = AOP_SIZE(result);
-    while (size--) {
-       pic14_emitcode ("pop","acc");
-       aopPut(AOP(result),"a",--offset);
+
+    if (IS_SYMOP(result) && IS_GENPTR(OP_SYM_TYPE(result)))
+    {
+        /* provide correct tag */
+        int isCode = IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))));
+        emitpcode (POC_MOVLW, popGetLit (isCode ? GPTRTAG_CODE : GPTRTAG_DATA));
+        movwf (AOP(result), 2);
     }
-    freeAsmop(result,NULL,ic,FALSE);
-       
+
+    freeAsmop(left,NULL,ic,FALSE);
+    freeAsmop(result,NULL,ic,TRUE);
+
 }
-#endif
 
 /*-----------------------------------------------------------------*/
 /* genAssign - generate code for assignment                        */
@@ -8058,12 +6320,13 @@ static void genFarFarAssign (operand *result, operand *right, iCode *ic)
 static void genAssign (iCode *ic)
 {
     operand *result, *right;
-    int size, offset ;
-       unsigned long lit = 0L;
+    int size, offset,know_W;
+    unsigned long lit = 0L;
 
     result = IC_RESULT(ic);
     right  = IC_RIGHT(ic) ;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     /* if they are the same */
@@ -8073,54 +6336,76 @@ static void genAssign (iCode *ic)
     aopOp(right,ic,FALSE);
     aopOp(result,ic,TRUE);
 
-    /* if they are the same registers */
-    if (pic14_sameRegs(AOP(right),AOP(result)))
-        goto release;
+    DEBUGpic14_AopType(__LINE__,NULL,right,result);
+
+    /* if they are the same registers */
+    if (pic14_sameRegs(AOP(right),AOP(result)))
+        goto release;
+
+    /* special case: assign from __code */
+    if (!IS_ITEMP(right)                /* --> iTemps never reside in __code */
+        && IS_SYMOP (right)         /* --> must be an immediate (otherwise we would be in genConstPointerGet) */
+        && !IS_FUNC(OP_SYM_TYPE(right))     /* --> we would want its address instead of the first instruction */
+        && !IS_CODEPTR(OP_SYM_TYPE(right))  /* --> get symbols address instread */
+        && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right)))))
+    {
+      emitpComment ("genAssign from CODESPACE");
+      genConstPointerGet (right, result, ic);
+      goto release;
+    }
+
+    /* just for symmetry reasons... */
+    if (!IS_ITEMP(result)
+        && IS_SYMOP (result)
+        && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result)))))
+    {
+      assert ( !"cannot write to CODESPACE" );
+    }
 
     /* if the result is a bit */
     if (AOP_TYPE(result) == AOP_CRY) {
 
-        /* if the right size is a literal then
+    /* if the right size is a literal then
         we know what the value is */
         if (AOP_TYPE(right) == AOP_LIT) {
-         
-         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
-                     popGet(AOP(result),0,FALSE,FALSE));
-
-            if (((int) operandLitValue(right))) 
-             pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
-                      AOP(result)->aopu.aop_dir,
-                      AOP(result)->aopu.aop_dir);
+
+            emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+                popGet(AOP(result),0));
+
+            if (((int) operandLitValue(right)))
+                pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
+                AOP(result)->aopu.aop_dir,
+                AOP(result)->aopu.aop_dir);
             else
-             pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
-                AOP(result)->aopu.aop_dir,
-                AOP(result)->aopu.aop_dir);
+                pic14_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) {
-         emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
-         emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
-         emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
-
-         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
-                  AOP(result)->aopu.aop_dir,
-                  AOP(result)->aopu.aop_dir);
-         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
-                  AOP(right)->aopu.aop_dir,
-                  AOP(right)->aopu.aop_dir);
-         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
-                  AOP(result)->aopu.aop_dir,
-                  AOP(result)->aopu.aop_dir);
-         goto release ;
+            emitpcode(POC_BCF,    popGet(AOP(result),0));
+            emitpcode(POC_BTFSC,  popGet(AOP(right),0));
+            emitpcode(POC_BSF,    popGet(AOP(result),0));
+
+            pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
+                AOP(result)->aopu.aop_dir,
+                AOP(result)->aopu.aop_dir);
+            pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
+                AOP(right)->aopu.aop_dir,
+                AOP(right)->aopu.aop_dir);
+            pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
+                AOP(result)->aopu.aop_dir,
+                AOP(result)->aopu.aop_dir);
+            goto release ;
         }
 
         /* we need to or */
-       emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
+        emitpcode(POC_BCF,    popGet(AOP(result),0));
         pic14_toBoolean(right);
-       emitSKPZ;
-       emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
+        emitSKPZ;
+        emitpcode(POC_BSF,    popGet(AOP(result),0));
         //aopPut(AOP(result),"a",0);
         goto release ;
     }
@@ -8129,50 +6414,50 @@ static void genAssign (iCode *ic)
     /* general case */
     size = AOP_SIZE(result);
     offset = 0 ;
-    if(AOP_TYPE(right) == AOP_LIT)
-       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-    if((AOP_TYPE(result) != AOP_REG) &&
-       (AOP_TYPE(right) == AOP_LIT) &&
-       !IS_FLOAT(operandType(right)) &&
-       (lit < 256L)){
-
-       while (size--) {
-         if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
-           //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
-             emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
-           }else {
-             emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
-             emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
-             //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
-             //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
-           }
-       }
-    } else {
-       while (size--) {
-         if(AOP_TYPE(right) == AOP_LIT) {
-           emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
-
-         } else if (AOP_TYPE(right) == AOP_CRY) {
-           emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
-           if(offset == 0) {
-             emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
-             emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
-           }
-         } else {
-           emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
-         }
-           
-         //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
-         offset++;
-       }
-    }
-    
+    if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
+        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        if(aopIdx(AOP(result),0) == 4) {
+            DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+            emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+            emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+            goto release;
+        } else
+            DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
+    }
+
+    know_W=-1;
+    while (size--) {
+
+        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        if(AOP_TYPE(right) == AOP_LIT) {
+            lit = (unsigned long)pic14aopLiteral(AOP(right)->aopu.aop_lit, offset) & 0x0ff;
+            if(lit&0xff) {
+                if(know_W != (int)(lit&0xff))
+                    emitpcode(POC_MOVLW,popGetLit(lit&0xff));
+                know_W = lit&0xff;
+                emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+            } else
+                emitpcode(POC_CLRF, popGet(AOP(result),offset));
+
+        } else if (AOP_TYPE(right) == AOP_CRY) {
+            emitpcode(POC_CLRF, popGet(AOP(result),offset));
+            if(offset == 0) {
+                emitpcode(POC_BTFSS, popGet(AOP(right),0));
+                emitpcode(POC_INCF, popGet(AOP(result),0));
+            }
+        } else {
+            mov2w_op (right, offset);
+            emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+        }
+
+        offset++;
+    }
+
+
 release:
     freeAsmop (right,NULL,ic,FALSE);
     freeAsmop (result,NULL,ic,TRUE);
-}   
+}
 
 /*-----------------------------------------------------------------*/
 /* genJumpTab - genrates code for jump table                       */
@@ -8182,6 +6467,7 @@ static void genJumpTab (iCode *ic)
     symbol *jtab;
     char *l;
 
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     aopOp(IC_JTCOND(ic),ic,FALSE);
@@ -8197,166 +6483,39 @@ static void genJumpTab (iCode *ic)
     pic14_emitcode("jmp","@a+dptr");
     pic14_emitcode("","%05d_DS_:",jtab->key+100);
 
+    emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
+    emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
-    emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
+    emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
     emitSKPNC;
     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
-    emitpLabel(jtab->key+100+labelOffset);
+    emitpLabel(jtab->key);
 
     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
 
     /* now generate the jump labels */
     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
-         jtab = setNextItem(IC_JTLABELS(ic))) {
+    jtab = setNextItem(IC_JTLABELS(ic))) {
         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
-       emitpcode(POC_GOTO,popGetLabel(jtab->key));
-       
-    }
-
-}
-
-/*-----------------------------------------------------------------*/
-/* genMixedOperation - gen code for operators between mixed types  */
-/*-----------------------------------------------------------------*/
-/*
-  TSD - Written for the PIC port - but this unfortunately is buggy.
-  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 
-  iCode tree, I'm going to not be using this routine :(.
-*/
-static int genMixedOperation (iCode *ic)
-{
-#if 0
-  operand *result = IC_RESULT(ic);
-  sym_link *ctype = operandType(IC_LEFT(ic));
-  operand *right = IC_RIGHT(ic);
-  int ret = 0;
-  int big,small;
-  int offset;
-
-  iCode *nextic;
-  operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
-
-  pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
-
-  nextic = ic->next;
-  if(!nextic)
-    return 0;
-
-  nextright = IC_RIGHT(nextic);
-  nextleft  = IC_LEFT(nextic);
-  nextresult = IC_RESULT(nextic);
-
-  aopOp(right,ic,FALSE);
-  aopOp(result,ic,FALSE);
-  aopOp(nextright,  nextic, FALSE);
-  aopOp(nextleft,   nextic, FALSE);
-  aopOp(nextresult, nextic, FALSE);
-
-  if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
-
-    operand *t = right;
-    right = nextright;
-    nextright = t; 
-
-    pic14_emitcode(";remove right +","");
-
-  } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
-/*
-    operand *t = right;
-    right = nextleft;
-    nextleft = t; 
-*/
-    pic14_emitcode(";remove left +","");
-  } else
-    return 0;
-
-  big = AOP_SIZE(nextleft);
-  small = AOP_SIZE(nextright);
+        emitpcode(POC_GOTO,popGetLabel(jtab->key));
 
-  switch(nextic->op) {
-
-  case '+':
-    pic14_emitcode(";optimize a +","");
-    /* if unsigned or not an integral type */
-    if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
-      pic14_emitcode(";add a bit to something","");
-    } else {
-
-      pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
-
-      if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
-       pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
-       pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
-      } else
-       pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
-
-      offset = 0;
-      while(--big) {
-
-       offset++;
-
-       if(--small) {
-         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
-           pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-           pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
-         }
-
-         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-         emitSKPNC;
-         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                  AOP(IC_RIGHT(nextic))->aopu.aop_dir,
-                  AOP(IC_RIGHT(nextic))->aopu.aop_dir);
-         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
-
-       } else {
-         pic14_emitcode("rlf","known_zero,w");
-
-         /*
-           if right is signed
-             btfsc  right,7
-               addlw ff
-         */
-         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
-           pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
-           pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
-         } else {
-           pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
-         }
-       }
-      }
-      ret = 1;
     }
-  }
-  ret = 1;
-
-release:
-  freeAsmop(right,NULL,ic,TRUE);
-  freeAsmop(result,NULL,ic,TRUE);
-  freeAsmop(nextright,NULL,ic,TRUE);
-  freeAsmop(nextleft,NULL,ic,TRUE);
-  if(ret)
-    nextic->generated = 1;
 
-  return ret;
-#else
-  return 0;
-#endif
 }
+
 /*-----------------------------------------------------------------*/
 /* genCast - gen code for casting                                  */
 /*-----------------------------------------------------------------*/
 static void genCast (iCode *ic)
 {
     operand *result = IC_RESULT(ic);
-    sym_link *ctype = operandType(IC_LEFT(ic));
+    sym_link *restype = operandType(result);
+    sym_link *rtype = operandType(IC_RIGHT(ic));
     operand *right = IC_RIGHT(ic);
     int size, offset ;
 
+    FENTRY;
     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* if they are equivalent then do nothing */
     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
@@ -8365,45 +6524,103 @@ static void genCast (iCode *ic)
     aopOp(right,ic,FALSE) ;
     aopOp(result,ic,FALSE);
 
+    DEBUGpic14_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) {
+        assert(!"assigning to bit variables is not supported");
+    }
 
-         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
-                     popGet(AOP(result),0,FALSE,FALSE));
+    if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
+        int offset = 1;
+        size = AOP_SIZE(result);
 
-            if (((int) operandLitValue(right))) 
-             pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
-                      AOP(result)->aopu.aop_dir,
-                      AOP(result)->aopu.aop_dir);
-            else
-             pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
-                      AOP(result)->aopu.aop_dir,
-                      AOP(result)->aopu.aop_dir);
+        DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-            goto release;
-        }
+        emitpcode(POC_CLRF,   popGet(AOP(result),0));
+        emitpcode(POC_BTFSC,  popGet(AOP(right),0));
+        emitpcode(POC_INCF,   popGet(AOP(result),0));
 
-        /* the right is also a bit variable */
-        if (AOP_TYPE(right) == AOP_CRY) {
+        while (size--)
+            emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
 
-         emitCLRC;
-         emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
+        goto release;
+    }
 
-         pic14_emitcode("clrc","");
-         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                  AOP(right)->aopu.aop_dir,
-                  AOP(right)->aopu.aop_dir);
-            aopPut(AOP(result),"c",0);
-            goto release ;
+    if (IS_PTR(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);
+      DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+      /* warn if we discard generic opinter tag */
+      if (!IS_GENPTR(restype) && IS_GENPTR(rtype) && (AOP_SIZE(result) < AOP_SIZE(right)))
+      {
+        //fprintf (stderr, "%s:%u: discarding generic pointer type tag\n", __FUNCTION__, __LINE__);
+      } // if
+
+      max = size;
+      while (size--)
+      {
+        mov2w_op (right, size);
+        movwf (AOP(result), size);
+      } // while
+
+      /* upcast into generic pointer type? */
+      if (IS_GENPTR(restype)
+        && (size < AOP_SIZE(result))
+        && (!IS_GENPTR(rtype) || AOP_SIZE(right) < GPTRSIZE))
+      {
+        //fprintf (stderr, "%s:%u: must determine pointer type\n", __FUNCTION__, __LINE__);
+        if (IS_PTR(rtype))
+        {
+          switch (DCL_TYPE(rtype))
+          {
+          case POINTER: /* __data */
+          case FPOINTER:    /* __data */
+        assert (AOP_SIZE(right) == 2);
+        tag = GPTRTAG_DATA;
+        break;
+
+          case CPOINTER:    /* __code */
+        assert (AOP_SIZE(right) == 2);
+        tag = GPTRTAG_CODE;
+        break;
+
+          case GPOINTER:    /* unknown destination, __data or __code */
+        /* assume __data space (address of immediate) */
+        assert (AOP_TYPE(right) == AOP_PCODE && AOP(right)->aopu.pcop->type == PO_IMMEDIATE);
+        if (AOP(right)->code)
+          tag = GPTRTAG_CODE;
+        else
+          tag = GPTRTAG_DATA;
+        break;
+
+          default:
+        assert (!"unhandled pointer type");
+          } // switch
+        } else {
+          /* convert other values into pointers to __data space */
+          tag = GPTRTAG_DATA;
         }
 
-        /* we need to or */
-        pic14_toBoolean(right);
-        aopPut(AOP(result),"a",0);
-        goto release ;
+        assert (AOP_SIZE(result) == 3);
+        if (tag == 0) {
+          emitpcode(POC_CLRF, popGet(AOP(result), 2));
+        } else {
+          emitpcode(POC_MOVLW, popGetLit(tag));
+          movwf(AOP(result), 2);
+        }
+      } else {
+        addSign(result, max, 0);
+      } // if
+      goto release;
     }
 
     /* if they are the same size : or less */
@@ -8413,172 +6630,52 @@ static void genCast (iCode *ic)
         if (pic14_sameRegs(AOP(right),AOP(result)))
             goto release;
 
-        /* if they in different places then copy */
-        size = AOP_SIZE(result);
-        offset = 0 ;
-        while (size--) {
-            aopPut(AOP(result),
-                   aopGet(AOP(right),offset,FALSE,FALSE),
-                   offset);
-            offset++;
-        }
-        goto release;
-    }
+        DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+        if (IS_PTR_CONST(rtype))
+            DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
+        if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+            DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
 
+        if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+            emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
+            emitpcode(POC_MOVWF, popGet(AOP(result),0));
+            emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0));
+            emitpcode(POC_MOVWF, popGet(AOP(result),1));
+            if(AOP_SIZE(result) <2)
+                fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
 
-    /* if the result is of type pointer */
-    if (IS_PTR(ctype)) {
-
-       int p_type;
-       sym_link *type = operandType(right);
-       sym_link *etype = getSpec(type);
-
-       /* 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 */
-           size = GPTRSIZE - 1; 
-           offset = 0 ;
-           while (size--) {
-               aopPut(AOP(result),
-                      aopGet(AOP(right),offset,FALSE,FALSE),
-                      offset);
-               offset++;
-           }
-           /* the last byte depending on type */
-           switch (p_type) {
-           case IPOINTER:
-           case POINTER:
-               l = zero;
-               break;
-           case FPOINTER:
-               l = one;
-               break;
-           case CPOINTER:
-               l = "#0x02";
-               break;                          
-           case PPOINTER:
-               l = "#0x03";
-               break;
-               
-           default:
-               /* this should never happen */
-               werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                      "got unknown pointer type");
-               exit(1);
-           }
-           aopPut(AOP(result),l, GPTRSIZE - 1);            
-           goto release ;
-       }
-       
-       /* just copy the pointers */
-       size = AOP_SIZE(result);
-       offset = 0 ;
-       while (size--) {
-           aopPut(AOP(result),
-                  aopGet(AOP(right),offset,FALSE,FALSE),
-                  offset);
-           offset++;
-       }
-       goto release ;
-    }
-    
-
-    if (AOP_TYPE(right) == AOP_CRY) {
-      int offset = 1;
-      size = AOP_SIZE(right);
+        } else {
 
-      emitpcode(POC_CLRF,   popGet(AOP(result),0,FALSE,FALSE));
-      emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
-      emitpcode(POC_INCF,   popGet(AOP(result),0,FALSE,FALSE));
+            /* if they in different places then copy */
+            size = AOP_SIZE(result);
+            offset = 0 ;
+            while (size--) {
+                emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+                emitpcode(POC_MOVWF, popGet(AOP(result),offset));
 
-      pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
-      pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-              AOP(right)->aopu.aop_dir,
-              AOP(right)->aopu.aop_dir);
-      pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
-      while (size--) {
-       pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
-       emitpcode(POC_CLRF,   popGet(AOP(result),offset++,FALSE,FALSE));
-      }
-      goto release;
+                //aopPut(AOP(result),
+                // aopGet(AOP(right),offset,FALSE,FALSE),
+                // offset);
+
+                offset++;
+            }
+        }
+        goto release;
     }
 
     /* so we now know that the size of destination is greater
-    than the size of the source.
-    Now, if the next iCode is an operator then we might be
-    able to optimize the operation without performing a cast.
-    */
-    if(genMixedOperation(ic))
-      goto release;
+    than the size of the source. */
 
-    
     /* we move to result for the size of source */
     size = AOP_SIZE(right);
     offset = 0 ;
     while (size--) {
-      pic14_emitcode(";","%d",__LINE__);
-        aopPut(AOP(result),
-               aopGet(AOP(right),offset,FALSE,FALSE),
-               offset);
+        emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
+        emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
         offset++;
     }
 
-    /* now depending on the sign of the destination */
-    size = AOP_SIZE(result) - AOP_SIZE(right);
-    /* if unsigned or not an integral type */
-    if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
-      while (size--) {
-         emitpcode(POC_CLRF,   popGet(AOP(result),offset,FALSE,FALSE));
-         pic14_emitcode("clrf","%s  ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
-         offset++;
-      }
-    } else {
-      /* we need to extend the sign :{ */
-      //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
-      //MOVA(l);
-
-      emitpcode(POC_CLRW,    NULL);
-      emitpcode(POC_BTFSC,   popGet(AOP(right),0,FALSE,FALSE));
-      emitpcode(POC_MOVLW,   popGetLit(0xff));
-
-        pic14_emitcode("clrw","");
-       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                AOP(right)->aopu.aop_dir,
-                AOP(right)->aopu.aop_dir);
-        pic14_emitcode("movlw","0xff");
-        while (size--) {
-         emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
-         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-         offset++;
-         // aopPut(AOP(result),"a",offset++);
-       }
-
-    }
-
-    /* we are done hurray !!!! */
+    addSign (result, AOP_SIZE(right), !SPEC_USIGN(rtype));
 
 release:
     freeAsmop(right,NULL,ic,TRUE);
@@ -8592,57 +6689,40 @@ release:
 static int genDjnz (iCode *ic, iCode *ifx)
 {
     symbol *lbl, *lbl1;
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     if (!ifx)
-       return 0;
-    
-    /* if the if condition has a false label
-       then we cannot save */
+        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 
-       a = a - 1 */
+        /* 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 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);
 
     aopOp(IC_RESULT(ic),ic,FALSE);
-    
-    if (IS_AOP_PREG(IC_RESULT(ic))) {
-       pic14_emitcode("dec","%s",
-                aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-       pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-       pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
-    } else {   
-
-
-      emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-      emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-
-      pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-      pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
 
-    }
-/*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
-/*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
-/*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
-/*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
+    emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
+    emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
 
-    
     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
     ifx->generated = 1;
     return 1;
@@ -8652,297 +6732,353 @@ static int genDjnz (iCode *ic, iCode *ifx)
 /* genReceive - generate code for a receive iCode                  */
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode *ic)
-{    
+{
+    FENTRY;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    if (isOperandInFarSpace(IC_RESULT(ic)) && 
-       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
-         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
-
-       int size = getSize(operandType(IC_RESULT(ic)));
-       int offset =  fReturnSizePic - size;
-       while (size--) {
-           pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
-                                   fReturn[fReturnSizePic - offset - 1] : "acc"));
-           offset++;
-       }
-       aopOp(IC_RESULT(ic),ic,FALSE);  
-       size = AOP_SIZE(IC_RESULT(ic));
-       offset = 0;
-       while (size--) {
-           pic14_emitcode ("pop","acc");
-           aopPut (AOP(IC_RESULT(ic)),"a",offset++);
-       }
-       
+    if (isOperandInFarSpace(IC_RESULT(ic)) &&
+        ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
+        IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
+
+        int size = getSize(operandType(IC_RESULT(ic)));
+        int offset =  fReturnSizePic - size;
+        while (size--) {
+            pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
+                fReturn[fReturnSizePic - offset - 1] : "acc"));
+            offset++;
+        }
+        aopOp(IC_RESULT(ic),ic,FALSE);
+        size = AOP_SIZE(IC_RESULT(ic));
+        offset = 0;
+        while (size--) {
+            pic14_emitcode ("pop","acc");
+            aopPut (AOP(IC_RESULT(ic)),"a",offset++);
+        }
+
     } else {
-       _G.accInUse++;
-       aopOp(IC_RESULT(ic),ic,FALSE);  
-       _G.accInUse--;
-       assignResultValue(IC_RESULT(ic));       
+        _G.accInUse++;
+        aopOp(IC_RESULT(ic),ic,FALSE);
+        _G.accInUse--;
+        GpsuedoStkPtr = ic->parmBytes; // address used arg on stack
+        assignResultValue(IC_RESULT(ic));
     }
 
     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+    FENTRY;
+    pic14_emitcode ("; genDummyRead","");
+    pic14_emitcode ("; not implemented","");
+
+    ic = ic;
+}
+
 /*-----------------------------------------------------------------*/
 /* genpic14Code - generate code for pic14 based controllers        */
 /*-----------------------------------------------------------------*/
 /*
- * At this point, ralloc.c has gone through the iCode and attempted
- * to optimize in a way suitable for a PIC. Now we've got to generate
- * PIC instructions that correspond to the iCode.
- *
- * Once the instructions are generated, we'll pass through both the
- * peep hole optimizer and the pCode optimizer.
- *-----------------------------------------------------------------*/
+* At this point, ralloc.c has gone through the iCode and attempted
+* to optimize in a way suitable for a PIC. Now we've got to generate
+* PIC instructions that correspond to the iCode.
+*
+* Once the instructions are generated, we'll pass through both the
+* peep hole optimizer and the pCode optimizer.
+*-----------------------------------------------------------------*/
 
 void genpic14Code (iCode *lic)
 {
     iCode *ic;
     int cln = 0;
+    const char *cline;
 
+    FENTRY;
     lineHead = lineCurr = NULL;
 
     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
     addpBlock(pb);
 
     /* if debug information required */
-/*     if (options.debug && currFunc) { */
-    if (currFunc) {
-       cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
-       _G.debugLine = 1;
-       if (IS_STATIC(currFunc->etype)) {
-           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
-           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
-       } else {
-           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
-           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
-       }
-       _G.debugLine = 0;
+    if (options.debug && debugFile && currFunc) {
+        debugFile->writeFunction (currFunc, lic);
     }
 
 
     for (ic = lic ; ic ; ic = ic->next ) {
 
-      DEBUGpic14_emitcode(";ic","");
-       if ( cln != ic->lineno ) {
-           if ( options.debug ) {
-               _G.debugLine = 1;
-               pic14_emitcode("",";C$%s$%d$%d$%d ==.",
-                        FileBaseName(ic->filename),ic->lineno,
-                        ic->level,ic->block);
-               _G.debugLine = 0;
-           }
-           pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
-           cln = ic->lineno ;
-       }
-       /* 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 ) 
-           continue ;
-       
-       /* depending on the operation */
-       switch (ic->op) {
-       case '!' :
-           genNot(ic);
-           break;
-           
-       case '~' :
-           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 destory 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; 
-           
-       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 '+' :
-           genPlus (ic) ;
-           break;
-           
-       case '-' :
-           if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
-               genMinus (ic);
-           break;
-           
-       case '*' :
-           genMult (ic);
-           break;
-           
-       case '/' :
-           genDiv (ic) ;
-           break;
-           
-       case '%' :
-           genMod (ic);
-           break;
-           
-       case '>' :
-           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:
-           
-           /* note these two are xlated by algebraic equivalence
-              during parsing SDCC.y */
-           werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                  "got '>=' or '<=' shouldn't have come here");
-           break;      
-           
-       case EQ_OP:
-           genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
-           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:
+        //DEBUGpic14_emitcode(";ic","");
+        //fprintf (stderr, "in ic loop\n");
+        //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename,
+        //ic->lineno, printCLine(ic->filename, ic->lineno));
+
+        if (!options.noCcodeInAsm && (cln != ic->lineno)) {
+          cln = ic->lineno;
+          //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
+          cline = printCLine (ic->filename, ic->lineno);
+          if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno);
+          addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline));
+          //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline);
+        }
+
+        if (options.iCodeInAsm) {
+          const char *iLine = printILine(ic);
+          emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
+                  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 )
+            continue ;
+
+        /* depending on the operation */
+        switch (ic->op) {
+        case '!' :
+            genNot(ic);
+            break;
+
+        case '~' :
+            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 destory 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;
+
+        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 '+' :
+            genPlus (ic) ;
+            break;
+
+        case '-' :
+            if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
+                genMinus (ic);
+            break;
+
+        case '*' :
+            genMult (ic);
+            break;
+
+        case '/' :
+            genDiv (ic) ;
+            break;
+
+        case '%' :
+            genMod (ic);
+            break;
+
+        case '>' :
+            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:
+
+            /* note these two are xlated by algebraic equivalence
+            during parsing SDCC.y */
+            werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+                "got '>=' or '<=' shouldn't have come here");
+            break;
+
+        case EQ_OP:
+            genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
+            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;
-
-       default :
-           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;
+
+        case DUMMY_READ_VOLATILE:
+            genDummyRead (ic);
+            break;
+
+        default :
+            fprintf(stderr, "UNHANDLED iCode: "); piCode(ic, stderr);
+            ic = ic;
+            break;
         }
     }
-    
 
-    /* now we are ready to call the 
-       peep hole optimizer */
+
+    /* now we are ready to call the
+    peep hole optimizer */
     if (!options.nopeep) {
-      printf("peep hole optimizing\n");
-       peepHole (&lineHead);
+        peepHole (&lineHead);
     }
     /* now do the actual printing */
-    printLine (lineHead,codeOutFile);
+    printLine (lineHead,codeOutBuf);
 
-    printf("printing pBlock\n\n");
+#ifdef PCODE_DEBUG
+    DFPRINTF((stderr,"printing pBlock\n\n"));
     printpBlock(stdout,pb);
+#endif
 
     return;
 }
+
+/* This is not safe, as a AOP_PCODE/PO_IMMEDIATE might be used both as literal
+ * (meaning: representing its own address) or not (referencing its contents).
+ * This can only be decided based on the operand's type. */
+static int
+aop_isLitLike (asmop *aop)
+{
+  assert (aop);
+  if (aop->type == AOP_LIT) return 1;
+  if (aop->type == AOP_IMMD) return 1;
+  if ((aop->type == AOP_PCODE) &&
+        ((aop->aopu.pcop->type == PO_LITERAL)))
+  {
+    /* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW
+     * instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */
+    return 1;
+  }
+  return 0;
+}
+
+int
+op_isLitLike (operand *op)
+{
+  assert (op);
+  if (aop_isLitLike (AOP(op))) return 1;
+  if (IS_SYMOP(op) && IS_FUNC(OP_SYM_TYPE(op))) return 1;
+  if (IS_SYMOP(op) && IS_PTR(OP_SYM_TYPE(op))
+        && (AOP_TYPE(op) == AOP_PCODE)
+        && (AOP(op)->aopu.pcop->type == PO_IMMEDIATE)) {
+    return 1;
+  }
+
+  return 0;
+}
+