* support/regression/tests/structflexarray.c: flexible array members
[fw/sdcc] / src / pic / gen.c
index 8cb10b272a63547a9c6ad399990aea7b582ef9c9..169fc0f3d620bc2bdb6b5aab1db0acde3dc40e94 100644 (file)
@@ -5,6 +5,7 @@
          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
   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>
+#ifndef __sun__
+#if defined(_MSC_VER)
+       #include "pstdint.h"
+#else
+       #include <stdint.h>
+#endif
+#endif
 #include "SDCCglobl.h"
-#include "newalloc.h"
+#include "newalloc.h" 
 
 #include "common.h"
 #include "SDCCpeeph.h"
 #include "pcode.h"
 #include "gen.h"
 
+/* When changing these, you must also update the assembler template
+ * in device/lib/libsdcc/macros.inc */
+#define GPTRTAG_DATA   0x00
+#define GPTRTAG_CODE   0x80
+
+/* The PIC port(s) need not differentiate between POINTER and FPOINTER. */
+#define PIC_IS_DATA_PTR(x)     (IS_DATA_PTR(x) || IS_FARPTR(x))
+#define PIC_IS_FARPTR(x)       (PIC_IS_DATA_PTR(x))
 
 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 void genMult8X8_8 (operand *, operand *,operand *);
-pCode *AssembleLine(char *line);
 extern void printpBlock(FILE *of, pBlock *pb);
 
 static int labelOffset=0;
 extern int debug_verbose;
-static int optimized_for_speed = 0;
+extern int pic14_hasInterrupt;
+//static int optimized_for_speed = 0;
 
 /* max_key keeps track of the largest label number used in 
 a function. This is then used to adjust the label offset
@@ -61,11 +77,11 @@ static int max_key=0;
 static int GpsuedoStkPtr=0;
 
 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
+extern char *get_op( pCodeOp *pcop,char *buff,size_t buf_size);
 unsigned int pic14aopLiteral (value *val, int offset);
 const char *AopType(short type);
-static iCode *ifxForOp ( operand *op, iCode *ic );
 
-#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
+#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff)
 
 /* this is the down and dirty file with all kinds of 
 kludgy & hacky stuff. This is what it is all about
@@ -77,11 +93,10 @@ static char *one  = "#0x01";
 static char *spname = "sp";
 
 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
-//char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
 static char **fReturn = fReturnpic14;
 
-static char *accUse[] = {"a","b"};
+//static char *accUse[] = {"a","b"};
 
 //static short rbank = -1;
 
@@ -113,21 +128,23 @@ static void saverbank (int, iCode *,bool);
 static lineNode *lineHead = NULL;
 static lineNode *lineCurr = NULL;
 
+#if 0
 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};
+#endif
 
-static  pBlock *pb;
+static pBlock *pb;
 
 /*-----------------------------------------------------------------*/
-/*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
-/*                 exponent of 2 is returned, otherwise -1 is      */
-/*                 returned.                                       */
+/*     my_powof2(n) - If `n' is an integaer power of 2, then the          */
+/*                                exponent of 2 is returned, otherwise -1 is      */
+/*                                returned.                                                                       */
 /* note that this is similar to the function `powof2' in SDCCsymt  */
-/* if(n == 2^y)                                                    */
-/*   return y;                                                     */
-/* return -1;                                                      */
+/* if(n == 2^y)                                                                                                   */
+/*      return y;                                                                                                         */
+/* return -1;                                                                                                     */
 /*-----------------------------------------------------------------*/
 static int my_powof2 (unsigned long num)
 {
@@ -148,15 +165,17 @@ static int my_powof2 (unsigned long num)
 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
 {
        
-       DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
+       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) : "-"),
-               ((result) ? AOP_SIZE(result) : 0));
+               ((right)  ? AOP_SIZE(right) : 0));
        
 }
 
@@ -168,7 +187,7 @@ void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand
                ((result) ? AopType(AOP_TYPE(result)) : "-"),
                ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
                ((left)   ? AopType(AOP_TYPE(left)) : "-"),
-               ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
+               ((left)   ? (SPEC_USIGN(operandType(left))       ? 'u' : 's') : '-'),
                ((right)  ? AopType(AOP_TYPE(right)) : "-"),
                ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
        
@@ -178,9 +197,9 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
 {
        va_list ap;
        char lb[INITIAL_INLINEASM];  
-       char *lbp = lb;
+       unsigned char *lbp = (unsigned char *)lb;
        
-       if(!debug_verbose)
+       if(!debug_verbose && !options.debug)
                return;
        
        va_start(ap,fmt);   
@@ -208,13 +227,57 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
        va_end(ap);
 }
 
+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));
+#if 0
+  } else {
+    Safe_vsnprintf (buffer, 4096, fmt, va);
+    fprintf (stderr, "No current pBlock -- discarding comment [%s]\n", buffer);
+#endif
+  }
+  va_end (va);
+}
 
 void emitpLabel(int key)
 {
        addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
 }
 
-void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+/* 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));
@@ -231,13 +294,13 @@ void emitpcodeNULLop(PIC_OPCODE poc)
 
 
 /*-----------------------------------------------------------------*/
-/* pic14_emitcode - writes the code into a file : for now it is simple    */
+/* 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 *lbp = lb;
+       unsigned char *lbp = (unsigned char *)lb;
        
        va_start(ap,fmt);   
        
@@ -265,7 +328,19 @@ void pic14_emitcode (char *inst,char *fmt, ...)
        va_end(ap);
 }
 
+/*-----------------------------------------------------------------*/
+/* pic14_emitDebuggerSymbol - associate the current code location  */
+/*      with a debugger symbol                                                                            */
+/*-----------------------------------------------------------------*/
+void
+pic14_emitDebuggerSymbol (char * debugSym)
+{
+       _G.debugLine = 1;
+       pic14_emitcode ("", ";%s ==.", debugSym);
+       _G.debugLine = 0;
+}
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
 /*-----------------------------------------------------------------*/
@@ -282,7 +357,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
        if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
                (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
        {
-               goto endOfWorld;      
+               goto endOfWorld;          
        }
        
        r0ou = bitVectBitValue(ic->rMask,R0_IDX);
@@ -310,7 +385,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
                /* push it if not already pushed */
                if (!_G.r0Pushed) {
                        //pic14_emitcode ("push","%s",
-                       //          pic14_regWithIdx(R0_IDX)->dname);
+                       //                pic14_regWithIdx(R0_IDX)->dname);
                        _G.r0Pushed++ ;
                }
                
@@ -326,7 +401,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
                /* push it if not already pushed */
                if (!_G.r1Pushed) {
                        //pic14_emitcode ("push","%s",
-                       //          pic14_regWithIdx(R1_IDX)->dname);
+                       //                pic14_regWithIdx(R1_IDX)->dname);
                        _G.r1Pushed++ ;
                }
                
@@ -339,7 +414,7 @@ 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;    
+               (*aopp)->type = AOP_STK;        
                return NULL;
        }
        
@@ -348,9 +423,10 @@ endOfWorld :
                "getFreePtr should never reach here");
        exit(0);
 }
+#endif
 
 /*-----------------------------------------------------------------*/
-/* newAsmop - creates a new asmOp                                  */
+/* newAsmop - creates a new asmOp                                                                 */
 /*-----------------------------------------------------------------*/
 asmop *newAsmop (short type)
 {
@@ -377,7 +453,7 @@ static void genSetDPTR(int n)
 
 /*-----------------------------------------------------------------*/
 /* resolveIfx - converts an iCode ifx into a form more useful for  */
-/*              generating code                                    */
+/*                             generating code                                                                    */
 /*-----------------------------------------------------------------*/
 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
 {
@@ -386,11 +462,11 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
        
        //  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 */
+       resIfx->condition = 1;  /* assume that the ifx is true */
+       resIfx->generated = 0;  /* indicate that the ifx has not been used */
        
        if(!ifx) {
-               resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
+               resIfx->lbl = NULL; /* this is wrong: newiTempLabel(NULL);      / * oops, there is no ifx. so create a label */
                                                                                        /*
                                                                                        DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
                                                                                        __FUNCTION__,__LINE__,resIfx->lbl->key);
@@ -414,17 +490,19 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
        
 }
 /*-----------------------------------------------------------------*/
-/* pointerCode - returns the code for a pointer type               */
+/* pointerCode - returns the code for a pointer type                      */
 /*-----------------------------------------------------------------*/
+#if 0
 static int pointerCode (sym_link *etype)
 {
        
        return PTR_TYPE(SPEC_OCLS(etype));
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
-/* aopForSym - for a true symbol                                   */
+/* aopForSym - for a true symbol                                                                  */
 /*-----------------------------------------------------------------*/
 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
 {
@@ -436,9 +514,10 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
        if (sym->aop)
                return sym->aop;
        
+#if 0
        /* 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   */    
+       /* 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);
@@ -474,8 +553,8 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
        
        if (sym->onStack && options.stack10bit)
        {
-       /* It's on the 10 bit stack, which is located in
-       * far data space.
+               /* It's on the 10 bit stack, which is located in
+               * far data space.
                */
                
                //DEBUGpic14_emitcode(";","%d",__LINE__);
@@ -502,7 +581,8 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
                aop->size = getSize(sym->type); 
                return aop;
        }
-       
+#endif
+
        //DEBUGpic14_emitcode(";","%d",__LINE__);
        /* if in bit space */
        if (IN_BITSPACE(space)) {
@@ -531,7 +611,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
                PCOI(aop->aopu.pcop)->index = 0;
                aop->size = FPTRSIZE; 
                /*
-               sym->aop = aop = newAsmop(AOP_IMMD);    
+               sym->aop = aop = newAsmop(AOP_IMMD);    
                aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
                strcpy(aop->aopu.aop_immd,sym->rname);
                aop->size = FPTRSIZE; 
@@ -540,6 +620,17 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
                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 */
@@ -554,7 +645,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
        
        allocDirReg (IC_LEFT(ic));
        
-       aop->size = FPTRSIZE; 
+       aop->size = FPTRSIZE;
        /*
        DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
        sym->aop = aop = newAsmop(AOP_DPTR);
@@ -568,11 +659,11 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
        if (IN_CODESPACE(space))
                aop->code = 1;
        
-       return aop;     
+       return aop;       
 }
 
 /*-----------------------------------------------------------------*/
-/* aopForRemat - rematerialzes an object                           */
+/* aopForRemat - rematerialzes an object                                                  */
 /*-----------------------------------------------------------------*/
 static asmop *aopForRemat (operand *op) // x symbol *sym)
 {
@@ -583,7 +674,7 @@ static asmop *aopForRemat (operand *op) // x symbol *sym)
        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__);
@@ -608,11 +699,11 @@ static asmop *aopForRemat (operand *op) // x symbol *sym)
                __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
                val, IS_PTR_CONST(operandType(op)));
        
-       //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
+       //      DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
        
        allocDirReg (IC_LEFT(ic));
        
-       return aop;        
+       return aop;              
 }
 
 int aopIdx (asmop *aop, int offset)
@@ -627,7 +718,7 @@ int aopIdx (asmop *aop, int offset)
        
 }
 /*-----------------------------------------------------------------*/
-/* regsInCommon - two operands have some registers in common       */
+/* regsInCommon - two operands have some registers in common      */
 /*-----------------------------------------------------------------*/
 static bool regsInCommon (operand *op1, operand *op2)
 {
@@ -662,7 +753,7 @@ static bool regsInCommon (operand *op1, operand *op2)
 }
 
 /*-----------------------------------------------------------------*/
-/* operandsEqu - equivalent                                        */
+/* operandsEqu - equivalent                                                                       */
 /*-----------------------------------------------------------------*/
 static bool operandsEqu ( operand *op1, operand *op2)
 {
@@ -685,7 +776,8 @@ static bool operandsEqu ( operand *op1, operand *op2)
        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;
        
        
@@ -707,7 +799,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 )
 {
@@ -743,7 +835,6 @@ 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);
@@ -770,7 +861,7 @@ void aopOp (operand *op, iCode *ic, bool result)
        }
        
        /* if this is a true symbol */
-       if (IS_TRUE_SYMOP(op)) {    
+       if (IS_TRUE_SYMOP(op)) {          
                //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
                op->aop = aopForSym(ic,OP_SYMBOL(op),result);
                return ;
@@ -803,13 +894,16 @@ void aopOp (operand *op, iCode *ic, bool result)
                /* rematerialize it NOW */
                if (sym->remat) {
                        
-                       sym->aop = op->aop = aop =
-                               aopForRemat (op);
+                       sym->aop = op->aop = aop = aopForRemat (op);
                        aop->size = getSize(sym->type);
                        //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
                        return;
                }
                
+#if 0
+               /* WREG is not usable as an ordinary operand with PIC architecture,
+                * one might introduce a scratch register that can be used to make
+                * WREG accesible as an operand... disable WREG for now */
                if (sym->accuse) {
                        int i;
                        aop = op->aop = sym->aop = newAsmop(AOP_ACC);
@@ -819,9 +913,10 @@ void aopOp (operand *op, iCode *ic, bool result)
                        DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
                        return;  
                }
+#endif
                
                if (sym->ruonly ) {
-                       if(sym->isptr) {  // && sym->uptr 
+                       if(sym->isptr) {        // && sym->uptr 
                                aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
                                aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
                                
@@ -851,24 +946,36 @@ void aopOp (operand *op, iCode *ic, bool result)
                        }
                }
                
-               /* else spill location  */
-               if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
-                       /* force a new aop if sizes differ */
-                       sym->usl.spillLoc->aop = NULL;
-               }
-               DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
-                       __FUNCTION__,__LINE__,
-                       sym->usl.spillLoc->rname,
-                       sym->rname, sym->usl.spillLoc->offset);
+               /* 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);
-               //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);
+                       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);
                
-               return;
+                       return;
+               }
        }
        
        {
@@ -886,10 +993,10 @@ void aopOp (operand *op, iCode *ic, bool result)
 }
 
 /*-----------------------------------------------------------------*/
-/* freeAsmop - free up the asmop given to an operand               */
+/* freeAsmop - free up the asmop given to an operand                      */
 /*----------------------------------------------------------------*/
 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
-{   
+{      
        asmop *aop ;
        
        if (!op)
@@ -912,7 +1019,7 @@ void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
        case AOP_R0 :
                if (_G.r0Pushed ) {
                        if (pop) {
-                               pic14_emitcode ("pop","ar0");     
+                               pic14_emitcode ("pop","ar0");     
                                _G.r0Pushed--;
                        }
                }
@@ -926,15 +1033,15 @@ void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
                                _G.r1Pushed--;
                        }
                }
-               bitVectUnSetBit(ic->rUsed,R1_IDX);          
+               bitVectUnSetBit(ic->rUsed,R1_IDX);                      
                break;
                
        case AOP_STK :
                {
-                       int sz = aop->size;    
+                       int sz = aop->size;      
                        int stk = aop->aopu.aop_stk + aop->size;
                        bitVectUnSetBit(ic->rUsed,R0_IDX);
-                       bitVectUnSetBit(ic->rUsed,R1_IDX);          
+                       bitVectUnSetBit(ic->rUsed,R1_IDX);                
                        
                        getFreePtr(ic,&aop,FALSE);
                        
@@ -971,7 +1078,7 @@ void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
                        if (_G.r1Pushed) {
                                pic14_emitcode("pop","ar1");
                                _G.r1Pushed--;
-                       }       
+                       }         
                }
        }
 #endif
@@ -981,7 +1088,7 @@ dealloc:
        if (op ) {
                op->aop = NULL;
                if (IS_SYMOP(op)) {
-                       OP_SYMBOL(op)->aop = NULL;    
+                       OP_SYMBOL(op)->aop = NULL;      
                        /* if the symbol has a spill */
                        if (SPIL_LOC(op))
                                SPIL_LOC(op)->aop = NULL;
@@ -990,7 +1097,7 @@ dealloc:
 }
 
 /*-----------------------------------------------------------------*/
-/* aopGet - for fetching value of the aop                          */
+/* aopGet - for fetching value of the aop                                                 */
 /*-----------------------------------------------------------------*/
 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
 {
@@ -1010,9 +1117,9 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
        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);  
+               /* if we need to increment it */           
+               while (offset > aop->coff) {            
+                       pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);    
                        aop->coff++;
                }
                
@@ -1025,10 +1132,10 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
                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);   
+               strcpy(rs,s);   
                return rs;
                
        case AOP_DPTR:
@@ -1044,7 +1151,7 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
                        aop->coff++;
                }
                
-               while (offset < aop->coff) {        
+               while (offset < aop->coff) {            
                        pic14_emitcode("lcall","__decdptr");
                        aop->coff--;
                }
@@ -1091,12 +1198,12 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
                } else
                        sprintf(s,"%s",aop->aopu.aop_dir);
                rs = Safe_calloc(1,strlen(s)+1);
-               strcpy(rs,s);   
+               strcpy(rs,s);   
                return rs;
                
        case AOP_REG:
                //if (dname) 
-               //    return aop->aopu.aop_reg[offset]->dname;
+               //        return aop->aopu.aop_reg[offset]->dname;
                //else
                return aop->aopu.aop_reg[offset]->name;
                
@@ -1111,7 +1218,7 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
        case AOP_LIT:
                sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
                rs = Safe_calloc(1,strlen(s)+1);
-               strcpy(rs,s);   
+               strcpy(rs,s);   
                return rs;
                
        case AOP_STR:
@@ -1128,27 +1235,31 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
                        pCodeOp *pcop = aop->aopu.pcop;
                        DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
                        if(pcop->name) {
-                               DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
-                               //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
-                               sprintf(s,"%s", pcop->name);
+                               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);   
+               strcpy(rs,s);   
                return rs;
                
-       }
-       
-       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-               "aopget got unsupported aop->type");
-       exit(0);
+  }
+  
+  werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+         "aopget got unsupported aop->type");
+  exit(0);
 }
 
 
 /*-----------------------------------------------------------------*/
-/* popGetTempReg - create a new temporary pCodeOp                  */
+/* popGetTempReg - create a new temporary pCodeOp                                 */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetTempReg(void)
 {
@@ -1165,7 +1276,7 @@ pCodeOp *popGetTempReg(void)
 }
 
 /*-----------------------------------------------------------------*/
-/* popGetTempReg - create a new temporary pCodeOp                  */
+/* popReleaseTempReg - create a new temporary pCodeOp                             */
 /*-----------------------------------------------------------------*/
 void popReleaseTempReg(pCodeOp *pcop)
 {
@@ -1175,7 +1286,7 @@ void popReleaseTempReg(pCodeOp *pcop)
        
 }
 /*-----------------------------------------------------------------*/
-/* popGetLabel - create a new pCodeOp of type PO_LABEL             */
+/* popGetLabel - create a new pCodeOp of type PO_LABEL                    */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetLabel(unsigned int key)
 {
@@ -1200,17 +1311,16 @@ pCodeOp *popGetHighLabel(unsigned int key)
 }
 
 /*-----------------------------------------------------------------*/
-/* 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         */
+/* popGetImmd - asm operator to pcode immediate conversion                */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
 {
@@ -1218,9 +1328,10 @@ pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
        return newpCodeOpImmd(name, offset,index, 0, is_func);
 }
 
+extern set *externs;
 
 /*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion              */
+/* popGetWithString - asm operator to pcode operator conversion                           */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetWithString(char *str, int isExtern)
 {
@@ -1234,12 +1345,36 @@ pCodeOp *popGetWithString(char *str, int isExtern)
        
        pcop = newpCodeOp(str,PO_STR);
        PCOS(pcop)->isPublic = isExtern ? 1 : 0;
+
+       return pcop;
+}
+
+pCodeOp *popGetExternal (char *str)
+{
+       pCodeOp *pcop = popGetWithString (str, 1);
        
+       if (str) {
+         symbol *sym;
+         bool found = 0;
+
+         for (sym = setFirstItem (externs); !found && sym; sym = setNextItem (externs))
+         {
+           if (!strcmp (str, sym->rname))
+             found = 1;
+         }
+         
+         if (!found)
+         {
+           sym = newSymbol(str, 0);
+           strncpy(sym->rname, str, SDCC_NAME_MAX);
+           addSet (&externs, sym);
+         } // if
+       }
        return pcop;
 }
 
 /*-----------------------------------------------------------------*/
-/* popRegFromString -                                              */
+/* popRegFromString -                                                                                     */
 /*-----------------------------------------------------------------*/
 pCodeOp *popRegFromString(char *str, int size, int offset)
 {
@@ -1293,7 +1428,7 @@ pCodeOp *popRegFromIdx(int rIdx)
 }
 
 /*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion              */
+/* popGet - asm operator to pcode operator conversion                     */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 {
@@ -1305,7 +1440,10 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* 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;
@@ -1331,18 +1469,8 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
                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);   
-               */
                pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
-               strcpy(pcop->name,aop->aopu.aop_dir);   
+               strcpy(pcop->name,aop->aopu.aop_dir);   
                PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
                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);
@@ -1358,7 +1486,9 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                
        case AOP_REG:
                {
-                       int rIdx = aop->aopu.aop_reg[offset]->rIdx;
+                       int rIdx;
+                       assert (offset < aop->size);
+                       rIdx = aop->aopu.aop_reg[offset]->rIdx;
                        
                        pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
                        PCOR(pcop)->rIdx = rIdx;
@@ -1369,7 +1499,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                        PCOR(pcop)->instance = offset;
                        pcop->type = PCOR(pcop)->r->pc_type;
                        //rs = aop->aopu.aop_reg[offset]->name;
-                       DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
+                       DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
                        return pcop;
                }
                
@@ -1397,11 +1527,28 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                */
                
        case AOP_PCODE:
-               DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
+               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"));
-               pcop = pCodeOpCopy(aop->aopu.pcop);
-               PCOI(pcop)->offset = offset;
+               //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;
        }
        
@@ -1409,8 +1556,39 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                "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                                */
+/* aopPut - puts a string for a aop                                                       */
 /*-----------------------------------------------------------------*/
 void aopPut (asmop *aop, char *s, int offset)
 {
@@ -1448,21 +1626,20 @@ void aopPut (asmop *aop, char *s, int offset)
                                if(offset >= aop->size) {
                                        emitpcode(POC_CLRF,popGet(aop,offset));
                                        break;
-                               } else
-                                       emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
+                               } 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) { // &&
+               if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
                        //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
                        /*
-                       if (*s == '@'           ||
+                       if (*s == '@'             ||
                        strcmp(s,"r0") == 0 ||
                        strcmp(s,"r1") == 0 ||
                        strcmp(s,"r2") == 0 ||
@@ -1555,7 +1732,7 @@ void aopPut (asmop *aop, char *s, int offset)
                aop->coff = offset;
                
                if (aop->paged) {
-                       MOVA(s);           
+                       MOVA(s);                         
                        pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
                        
                } else
@@ -1635,11 +1812,40 @@ void aopPut (asmop *aop, char *s, int offset)
        default :
                werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
                        "aopPut got unsupported aop->type");
-               exit(0);    
-       }    
+               exit(0);
+       }
        
 }
 
+/*-----------------------------------------------------------------*/
+/* mov2w_op - generate either a MOVLW or MOVFW based operand type  */
+/*-----------------------------------------------------------------*/
+static void mov2w_op (operand *op, int offset)
+{
+       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);
+       }
+}
+
+
 /*-----------------------------------------------------------------*/
 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
 /*-----------------------------------------------------------------*/
@@ -1651,15 +1857,55 @@ void mov2w (asmop *aop, int offset)
        
        DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
        
-       if ( aop->type == AOP_PCODE ||
-               aop->type == AOP_LIT ||
-               aop->type == AOP_IMMD )
-               emitpcode(POC_MOVLW,popGet(aop,offset));
+       if ( aop_isLitLike (aop) )
+               emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
        else
                emitpcode(POC_MOVFW,popGet(aop,offset));
        
 }
 
+static void movwf (asmop *op, int offset)
+{
+       emitpcode (POC_MOVWF, popGet(op, offset));
+}
+
+static pCodeOp *get_argument_pcop (int idx)
+{
+       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)
+{
+  /* library code might reside in different page... */
+  emitpcode (POC_PAGESEL, popGetWithString (name, 1));
+  /* call the library function */
+  emitpcode (POC_CALL, popGetExternal (name));
+  /* might return from different page... */
+  emitpcode (POC_PAGESEL, popGetWithString ("$", 0));
+}
+#if 0
 /*-----------------------------------------------------------------*/
 /* reAdjustPreg - points a register back to where it should        */
 /*-----------------------------------------------------------------*/
@@ -1677,7 +1923,7 @@ static void reAdjustPreg (asmop *aop)
        case AOP_R1 :
                while (size--)
                        pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
-               break;          
+               break;                  
        case AOP_DPTR :
        case AOP_DPTR2:
                if (aop->type == AOP_DPTR2)
@@ -1698,12 +1944,13 @@ static void reAdjustPreg (asmop *aop)
        }
        
 }
+#endif
 
 
 #if 0
 /*-----------------------------------------------------------------*/
-/* opIsGptr: returns non-zero if the passed operand is            */   
-/* a generic pointer type.                                        */
+/* opIsGptr: returns non-zero if the passed operand is             */
+/* a generic pointer type.                                         */
 /*-----------------------------------------------------------------*/ 
 static int opIsGptr(operand *op)
 {
@@ -1714,32 +1961,35 @@ static int opIsGptr(operand *op)
        {
                return 1;
        }
-       return 0;        
+       return 0;          
 }
 #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_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).
+                       /* generic pointer; arithmetic operations
+                       * should ignore the high byte (pointer type).
                        */
                        size--;
                        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -1750,7 +2000,7 @@ int pic14_getDataSize(operand *op)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_outAcc - output Acc                                             */
+/* pic14_outAcc - output Acc                                       */
 /*-----------------------------------------------------------------*/
 void pic14_outAcc(operand *result)
 {
@@ -1772,7 +2022,7 @@ void pic14_outAcc(operand *result)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_outBitC - output a bit C                                        */
+/* pic14_outBitC - output a bit C                                  */
 /*-----------------------------------------------------------------*/
 void pic14_outBitC(operand *result)
 {
@@ -1789,21 +2039,37 @@ 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)
 {
-       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));
+
+       assert (size > 0);
+
+       if (size == 1) {
+               /* MOVFW does not load the flags... */
+               if (AOP_TYPE(oper) == AOP_ACC) {
+                       emitpcode(POC_IORLW, popGetLit(0));
+                       offset = 1;
+               } else {
+                       emitpcode(POC_MOVLW, popGetLit(0));
+                       offset = 0;
+               }
+       } else {
+               if ( AOP_TYPE(oper) != AOP_ACC) {
+                       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
+                       offset = 1;
+               }
        }
-       while (size--) {
+       
+       while (offset < size) {
                emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
        }
+       /* Z is set iff (oper == 0) */
 }
 
 
@@ -1812,8 +2078,10 @@ void pic14_toBoolean(operand *oper)
 /*-----------------------------------------------------------------*/
 static void genNot (iCode *ic)
 {
-       symbol *tlbl;
+       //symbol *tlbl;
        int size;
+
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* assign asmOps to operand & result */
@@ -1835,20 +2103,26 @@ static void genNot (iCode *ic)
        }
        
        size = AOP_SIZE(IC_LEFT(ic));
-       if(size == 1) {
-               emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
-               emitpcode(POC_ANDLW,popGetLit(1));
-               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
-               goto release;
+       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));
        }
-       pic14_toBoolean(IC_LEFT(ic));
-       
-       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));
+       emitpcode(POC_MOVLW, popGetLit (0));
+       emitSKPNZ;
+       emitpcode(POC_MOVLW, popGetLit (1));
+       movwf(AOP(IC_RESULT(ic)), 0);
+
+       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);
@@ -1856,13 +2130,14 @@ release:
 
 
 /*-----------------------------------------------------------------*/
-/* genCpl - generate code for complement                           */
+/* genCpl - generate code for complement                                                  */
 /*-----------------------------------------------------------------*/
 static void genCpl (iCode *ic)
 {
        operand *left, *result;
        int size, offset=0;  
        
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        aopOp((left = IC_LEFT(ic)),ic,FALSE);
@@ -1880,6 +2155,7 @@ static void genCpl (iCode *ic)
        } 
        
        size = AOP_SIZE(result);
+       if (AOP_SIZE(left) < size) size = AOP_SIZE(left);
        while (size--) {
                
                if(AOP_TYPE(left) == AOP_ACC) 
@@ -1888,8 +2164,9 @@ static void genCpl (iCode *ic)
                        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:
@@ -1899,40 +2176,43 @@ release:
 }
 
 /*-----------------------------------------------------------------*/
-/* genUminusFloat - unary minus for floating points                */
+/* genUminusFloat - unary minus for floating points                       */
 /*-----------------------------------------------------------------*/
 static void genUminusFloat(operand *op,operand *result)
 {
        int size ,offset =0 ;
        char *l;
        
+       FENTRY;
+
        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);
        
-       MOVA(l);    
+       MOVA(l);          
        
        pic14_emitcode("cpl","acc.7");
-       aopPut(AOP(result),"a",3);    
+       aopPut(AOP(result),"a",3);      
        
        while(size--) {
                aopPut(AOP(result),
                        aopGet(AOP(op),offset,FALSE,FALSE),
                        offset);
                offset++;
-       }          
+       }                
 }
 
 /*-----------------------------------------------------------------*/
-/* genUminus - unary minus code generation                         */
+/* genUminus - unary minus code generation                                                */
 /*-----------------------------------------------------------------*/
 static void genUminus (iCode *ic)
 {
        int size, i;
        sym_link *optype, *rtype;
        
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* assign asmops */
@@ -1944,9 +2224,9 @@ static void genUminus (iCode *ic)
        if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
                AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
                
-               emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
+               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));
+               emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
                
                goto release; 
        } 
@@ -1981,11 +2261,11 @@ static void genUminus (iCode *ic)
 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     */
+/* saveRegisters - will look for a call and save the registers    */
 /*-----------------------------------------------------------------*/
 static void saveRegisters(iCode *lic) 
 {
@@ -1994,6 +2274,8 @@ static void saveRegisters(iCode *lic)
        bitVect *rsave;
        sym_link *dtype;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* look for call */
        for (ic = lic ; ic ; ic = ic->next) 
@@ -2032,10 +2314,10 @@ static void saveRegisters(iCode *lic)
                        }
                        pic14_emitcode("mov","%s,r0",spname);
                        if (bitVectBitValue(rsave,R0_IDX))
-                               pic14_emitcode("mov","r0,b");       
+                               pic14_emitcode("mov","r0,b");     
                }// else
                //for (i = 0 ; i < pic14_nRegs ; i++) {
-               //    if (bitVectBitValue(rsave,i))
+               //        if (bitVectBitValue(rsave,i))
                //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
                //}
                
@@ -2049,13 +2331,15 @@ static void saveRegisters(iCode *lic)
                
 }
 /*-----------------------------------------------------------------*/
-/* unsaveRegisters - pop the pushed registers                      */
+/* unsaveRegisters - pop the pushed registers                                     */
 /*-----------------------------------------------------------------*/
 static void unsaveRegisters (iCode *ic)
 {
        int i;
        bitVect *rsave;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* find the registers in use at this time 
        and push them away to safety */
@@ -2063,7 +2347,7 @@ static void unsaveRegisters (iCode *ic)
                ic->rUsed);
        
        if (options.useXstack) {
-               pic14_emitcode("mov","r0,%s",spname);   
+               pic14_emitcode("mov","r0,%s",spname); 
                for (i =  pic14_nRegs ; i >= 0 ; i--) {
                        if (bitVectBitValue(rsave,i)) {
                                pic14_emitcode("dec","r0");
@@ -2072,7 +2356,7 @@ static void unsaveRegisters (iCode *ic)
                                        pic14_emitcode("mov","b,a");
                                else
                                        pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
-                       }           
+                       }       
                        
                }
                pic14_emitcode("mov","%s,r0",spname);
@@ -2080,15 +2364,15 @@ static void unsaveRegisters (iCode *ic)
                        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);
+       //      if (bitVectBitValue(rsave,i))
+       //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
        //}
        
 }  
 
 
 /*-----------------------------------------------------------------*/
-/* pushSide -                                                     */
+/* pushSide -                           */
 /*-----------------------------------------------------------------*/
 static void pushSide(operand * oper, int size)
 {
@@ -2109,20 +2393,23 @@ static void pushSide(operand * oper, int size)
 }
 
 /*-----------------------------------------------------------------*/
-/* assignResultValue -                                            */
+/* assignResultValue -                          */
 /*-----------------------------------------------------------------*/
 static void assignResultValue(operand * oper)
 {
        int size = AOP_SIZE(oper);
+       int offset = 0;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
        
+       /* assign MSB first (passed via WREG) */
        while (size--) {
-               if (GpsuedoStkPtr++)
-                       emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
-               emitpcode(POC_MOVWF, popGet(AOP(oper),size));
+               get_returnvalue (oper, size, offset + GpsuedoStkPtr);
+               GpsuedoStkPtr++;
        }
 }
 
@@ -2132,6 +2419,7 @@ static void assignResultValue(operand * oper)
 /*-----------------------------------------------------------------*/
 static void genIpush (iCode *ic)
 {
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 #if 0
@@ -2158,7 +2446,7 @@ static void genIpush (iCode *ic)
                        }
                        pic14_emitcode("push","%s",l);
                }
-               return ;        
+               return ;                
        }
        
        /* this is a paramter push: in this case we call
@@ -2182,7 +2470,7 @@ static void genIpush (iCode *ic)
                        pic14_emitcode("push","acc");
                } else
                        pic14_emitcode("push","%s",l);
-       }       
+       }         
        
        freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
 #endif
@@ -2193,7 +2481,10 @@ 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 ;
        
@@ -2214,10 +2505,12 @@ static void genIpop (iCode *ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* unsaverbank - restores the resgister bank from stack            */
+/* unsaverbank - restores the resgister bank from stack                   */
 /*-----------------------------------------------------------------*/
 static void unsaverbank (int bank,iCode *ic,bool popPsw)
 {
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 #if 0
        int i;
@@ -2241,10 +2534,10 @@ static void unsaverbank (int bank,iCode *ic,bool popPsw)
        }
        
        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 
@@ -2262,10 +2555,12 @@ static void unsaverbank (int bank,iCode *ic,bool popPsw)
 }
 
 /*-----------------------------------------------------------------*/
-/* saverbank - saves an entire register bank on the stack          */
+/* saverbank - saves an entire register bank on the stack                 */
 /*-----------------------------------------------------------------*/
 static void saverbank (int bank, iCode *ic, bool pushPsw)
 {
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 #if 0
        int i;
@@ -2285,8 +2580,8 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
                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);           
+                       //               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);
@@ -2295,9 +2590,9 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
        if (pushPsw) {
                if (options.useXstack) {
                        pic14_emitcode("mov","a,psw");
-                       pic14_emitcode("movx","@%s,a",r->name); 
+                       pic14_emitcode("movx","@%s,a",r->name); 
                        pic14_emitcode("inc","%s",r->name);
-                       pic14_emitcode("mov","_spx,%s",r->name);       
+                       pic14_emitcode("mov","_spx,%s",r->name);                 
                        freeAsmop (NULL,aop,ic,TRUE);
                        
                } else
@@ -2310,15 +2605,17 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
 }
 
 /*-----------------------------------------------------------------*/
-/* genCall - generates a call statement                            */
+/* genCall - generates a call statement                                                   */
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
-       sym_link *dtype;   
+       sym_link *dtype;         
        symbol *sym;
-       unsigned char *name;
+       char *name;
        int isExtern;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        /* if caller saves & we have not saved then */
@@ -2370,16 +2667,16 @@ static void genCall (iCode *ic)
                                        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
+                                       /* 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 (AOP(IC_LEFT(sic)),  offset);
+                               mov2w_op (IC_LEFT(sic),  offset);
                                offset++;
                        }
                        freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
@@ -2395,7 +2692,7 @@ static void genCall (iCode *ic)
        }
        emitpcode(POC_CALL,popGetWithString(name,isExtern));
        if (isExtern) {
-               emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
+               emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
        }
        GpsuedoStkPtr=0;
        /* if we need assign a result value */
@@ -2416,20 +2713,6 @@ static void genCall (iCode *ic)
                freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
        }
        
-       /* 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);
-                       
-       }
-       
        /* if register bank was saved then pop them */
        if (ic->bankSaved)
                unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
@@ -2442,7 +2725,7 @@ static void genCall (iCode *ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* genPcall - generates a call by pointer statement                */
+/* genPcall - generates a call by pointer statement                       */
 /*-----------------------------------------------------------------*/
 static void genPcall (iCode *ic)
 {
@@ -2453,6 +2736,8 @@ static void genPcall (iCode *ic)
        pCodeOp *pcop;
        operand *left;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* if caller saves & we have not saved then */
        if (!ic->regsSaved)
@@ -2471,6 +2756,8 @@ static void genPcall (iCode *ic)
        aopOp(left,ic,FALSE);
        DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
        
+       poc = ( op_isLitLike (IC_LEFT(ic)) ? POC_MOVLW : POC_MOVFW );
+       
        pushSide(IC_LEFT(ic), FPTRSIZE);
        
        /* if send set is not empty, assign parameters */
@@ -2482,28 +2769,26 @@ static void genPcall (iCode *ic)
        /* 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(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);
-         }
+       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,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+       emitpcode(POC_PAGESEL,pcop); /* Must restore PCLATH before goto, without destroying W */
        emitpcode(POC_GOTO,pcop);
        emitpLabel(albl->key);
        
-       poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
-       
-       emitpcode(poc,popGet(AOP(left),1));
+       emitpcode(poc,popGetAddr(AOP(left),1,0));
        emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
-       emitpcode(poc,popGet(AOP(left),0));
+       emitpcode(poc,popGetAddr(AOP(left),0,0));
        emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
        
        emitpLabel(blbl->key);
@@ -2519,6 +2804,8 @@ static void genPcall (iCode *ic)
                _G.accInUse++;
                aopOp(IC_RESULT(ic),ic,FALSE);
                _G.accInUse--;
+
+               GpsuedoStkPtr = 0;
                
                assignResultValue(IC_RESULT(ic));
                
@@ -2538,11 +2825,13 @@ static void genPcall (iCode *ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* resultRemat - result  is rematerializable                       */
+/* resultRemat - result  is rematerializable                                      */
 /*-----------------------------------------------------------------*/
 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;
        
@@ -2585,13 +2874,15 @@ static bool inExcludeList(char *s)
 #endif
 
 /*-----------------------------------------------------------------*/
-/* genFunction - generated code for function entry                 */
+/* genFunction - generated code for function entry                                */
 /*-----------------------------------------------------------------*/
 static void genFunction (iCode *ic)
 {
        symbol *sym;
        sym_link *ftype;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
        
        labelOffset += (max_key+4);
@@ -2650,9 +2941,10 @@ static void genFunction (iCode *ic)
                emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
                
                pBlockConvert2ISR(pb);
+               pic14_hasInterrupt = 1;
 #if 0  
-               if (!inExcludeList("acc"))          
-                       pic14_emitcode ("push","acc");  
+               if (!inExcludeList("acc"))              
+                       pic14_emitcode ("push","acc");  
                if (!inExcludeList("b"))
                        pic14_emitcode ("push","b");
                if (!inExcludeList("dpl"))
@@ -2666,7 +2958,7 @@ static void genFunction (iCode *ic)
                        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");
@@ -2675,7 +2967,7 @@ static void genFunction (iCode *ic)
                }
                /* if this isr has no bank i.e. is going to
                run with bank 0 , then we need to save more
-registers :-) */
+               registers :-) */
                if (!FUNC_REGBANK(sym->type)) {
                        
                /* if this function does not call any other
@@ -2690,16 +2982,16 @@ registers :-) */
                                        for ( i = 0 ; i < sym->regsUsed->size ; i++) {
                                                if (bitVectBitValue(sym->regsUsed,i) ||
                                                        (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                                                       pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                           
+                                                       pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
                                        }
                                }
                                
                        } else {
-                       /* this function has  a function call cannot
+                       /* this function has    a function call cannot
                        determines register usage so we will have the
                                entire bank */
                                saverbank(0,ic,FALSE);
-                       }           
+                       }       
                }
 #endif
        } else {
@@ -2725,7 +3017,7 @@ registers :-) */
        /* set the register bank to the desired value */
        if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
                pic14_emitcode("push","psw");
-               pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
+               pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
        }
        
        if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
@@ -2739,7 +3031,7 @@ registers :-) */
                else
                {
                        /* set up the stack */
-                       pic14_emitcode ("push","_bp");     /* save the callers stack  */
+                       pic14_emitcode ("push","_bp");   /* save the callers stack      */
                }
                pic14_emitcode ("mov","_bp,%s",spname);
        }
@@ -2751,7 +3043,7 @@ registers :-) */
                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));
@@ -2768,17 +3060,19 @@ registers :-) */
                pic14_emitcode ("mov","a,_spx");
                pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
                pic14_emitcode ("mov","_spx,a");
-       }    
+       }
        
 }
 
 /*-----------------------------------------------------------------*/
-/* genEndFunction - generates epilogue for functions               */
+/* genEndFunction - generates epilogue for functions                      */
 /*-----------------------------------------------------------------*/
 static void genEndFunction (iCode *ic)
 {
        symbol *sym = OP_SYMBOL(IC_LEFT(ic));
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
@@ -2789,7 +3083,7 @@ 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");
@@ -2809,7 +3103,7 @@ static void genEndFunction (iCode *ic)
                }
        }
        
-       /* restore the register bank  */    
+       /* restore the register bank    */        
        if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
                pic14_emitcode ("pop","psw");
        
@@ -2838,11 +3132,11 @@ registers :-) */
                                }
                                
                        } else {
-                       /* this function has  a function call cannot
+                       /* this function has    a function call cannot
                        determines register usage so we will have the
                                entire bank */
                                unsaverbank(0,ic,FALSE);
-                       }           
+                       }       
                }
 #if 0
                if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
@@ -2852,7 +3146,7 @@ registers :-) */
                                pic14_emitcode ("pop", "dpx1");
                                pic14_emitcode ("pop", "dph1");
                                pic14_emitcode ("pop", "dpl1");
-                       }       
+                       } 
                        pic14_emitcode ("pop", "dps");
                        pic14_emitcode ("pop", "dpx");
                }
@@ -2870,17 +3164,9 @@ registers :-) */
 #endif
                
                /* if debug then send end of function */
-               /*      if (options.debug && currFunc) { */
+               /*      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;
+                       debugFile->writeEndFunction (currFunc, ic, 1);
                }
                
                pic14_emitcode ("reti","");
@@ -2915,15 +3201,7 @@ registers :-) */
                
                /* 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;
+                       debugFile->writeEndFunction (currFunc, ic, 1);
                }
                
                pic14_emitcode ("return","");
@@ -2936,79 +3214,50 @@ registers :-) */
 }
 
 /*-----------------------------------------------------------------*/
-/* genRet - generate code for return statement                     */
+/* genRet - generate code for return statement                                    */
 /*-----------------------------------------------------------------*/
 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;       
+               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_PCODE) && 
-                                       AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
-                                       ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
-                                       ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
-                                       emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
-                               }else {
-                                       emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
-                               }
-                               if(size) {
-                                       emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
-                               }
-                               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
+       /* 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);
        }
        
 }
 
 /*-----------------------------------------------------------------*/
-/* genLabel - generates a label                                    */
+/* genLabel - generates a label                                                                   */
 /*-----------------------------------------------------------------*/
 static void genLabel (iCode *ic)
 {
+       FENTRY;
+
        /* special case never generate */
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if (IC_LABEL(ic) == entryLabel)
@@ -3019,27 +3268,30 @@ static void genLabel (iCode *ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* genGoto - generates a goto                                      */
+/* genGoto - generates a goto                                                                     */
 /*-----------------------------------------------------------------*/
 //tsd
 static void genGoto (iCode *ic)
 {
+       FENTRY;
+
        emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
        pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
 }
 
 
 /*-----------------------------------------------------------------*/
-/* genMultbits :- multiplication of bits                           */
+/* genMultbits :- multiplication of bits                                                  */
 /*-----------------------------------------------------------------*/
 static void genMultbits (operand *left, 
                                                 operand *right, 
                                                 operand *result)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if(!pic14_sameRegs(AOP(result),AOP(right)))
-               emitpcode(POC_BSF,  popGet(AOP(result),0));
+               emitpcode(POC_BSF,      popGet(AOP(result),0));
        
        emitpcode(POC_BTFSC,popGet(AOP(right),0));
        emitpcode(POC_BTFSS,popGet(AOP(left),0));
@@ -3049,16 +3301,19 @@ static void genMultbits (operand *left,
 
 
 /*-----------------------------------------------------------------*/
-/* genMultOneByte : 8 bit multiplication & division                */
+/* genMultOneByte : 8 bit multiplication & division                       */
 /*-----------------------------------------------------------------*/
 static void genMultOneByte (operand *left,
                                                        operand *right,
                                                        operand *result)
 {
-       sym_link *opetype = operandType(result);
+       char *func[] = { NULL, "__mulchar", "__mulint", NULL, "__mullong" };
        
        // symbol *lbl ;
-       int size,offset;
+       int size,offset,i;
+       
+       
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        DEBUGpic14_AopType(__LINE__,left,right,result);
@@ -3071,98 +3326,54 @@ static void genMultOneByte (operand *left,
                right = left;
                left = t;
        }
+
+       assert (AOP_SIZE(left) == AOP_SIZE(right));
        
-       size = AOP_SIZE(result);
-       if(size == 1) {
-               
-               if (AOP_TYPE(right) == AOP_LIT){
-                       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
-                               aopGet(AOP(right),0,FALSE,FALSE), 
-                               aopGet(AOP(left),0,FALSE,FALSE), 
-                               aopGet(AOP(result),0,FALSE,FALSE));
-                       pic14_emitcode("call","genMultLit");
-               } else {
-                       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
-                               aopGet(AOP(right),0,FALSE,FALSE), 
-                               aopGet(AOP(left),0,FALSE,FALSE), 
-                               aopGet(AOP(result),0,FALSE,FALSE));
-                       pic14_emitcode("call","genMult8X8_8");
-                       
-               }
-               genMult8X8_8 (left, right,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);
-               
-       } else {  // (size > 1)
-               
-               pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
-                       aopGet(AOP(right),0,FALSE,FALSE), 
-                       aopGet(AOP(left),0,FALSE,FALSE), 
-                       aopGet(AOP(result),0,FALSE,FALSE));
-               
-               if (SPEC_USIGN(opetype)){
-                       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
-                       genUMult8X8_16 (left, right, result, NULL);
-                       
-                       if (size > 2) {
-                               /* for filling the MSBs */
-                               emitpcode(POC_CLRF,  popGet(AOP(result),2));
-                               emitpcode(POC_CLRF,  popGet(AOP(result),3));
-                       }
-               }
-               else{
-                       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
-                       
-                       pic14_emitcode("mov","a,b");
-                       
-                       /* adjust the MSB if left or right neg */
-                       
-                       /* if one literal */
-                       if (AOP_TYPE(right) == AOP_LIT){
-                               pic14_emitcode("multiply ","right is a 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{
-                               genSMult8X8_16 (left, right, result, NULL);
-                       }
-                       
-                       if(size > 2){
-                               pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
-                               /* get the sign */
-                               pic14_emitcode("rlc","a");
-                               pic14_emitcode("subb","a,acc");
-                       }
-               }
-               
-               size -= 2;   
-               offset = 2;
-               if (size > 0)
-                       while (size--)
-                               pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
-                       //aopPut(AOP(result),"a",offset++);
-       }
+       size = min(AOP_SIZE(result),AOP_SIZE(left));
+       offset = Gstack_base_addr - (2*size - 1);
+
+       /* pass right operand as argument */
+       for (i=0; i < size; i++)
+       {
+               mov2w (AOP(right), i);
+               emitpcode(POC_MOVWF, popRegFromIdx (++offset));
+       } // for
+       
+       /* 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)));
 }
 
 /*-----------------------------------------------------------------*/
-/* genMult - generates code for multiplication                     */
+/* genMult - generates code for multiplication                                    */
 /*-----------------------------------------------------------------*/
 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 */
        aopOp (left,ic,FALSE);
@@ -3186,10 +3397,8 @@ static void genMult (iCode *ic)
                goto release ;
        }
        
-       pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
-       
        /* should have been converted to function call */
-       //assert(0) ;
+       assert(0) ;
        
 release :
        freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
@@ -3198,7 +3407,7 @@ release :
 }
 
 /*-----------------------------------------------------------------*/
-/* genDivbits :- division of bits                                  */
+/* genDivbits :- division of bits                                                                 */
 /*-----------------------------------------------------------------*/
 static void genDivbits (operand *left, 
                                                operand *right, 
@@ -3207,12 +3416,14 @@ static void genDivbits (operand *left,
        
        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");
@@ -3220,98 +3431,101 @@ static void genDivbits (operand *left,
 }
 
 /*-----------------------------------------------------------------*/
-/* genDivOneByte : 8 bit division                                  */
+/* genDivOneByte : 8 bit division                                                                 */
 /*-----------------------------------------------------------------*/
 static void genDivOneByte (operand *left,
                                                   operand *right,
                                                   operand *result)
 {
-       sym_link *opetype = operandType(result);
-       char *l ;
-       symbol *lbl ;
-       int size,offset;
+       int size;
        
+       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 */
-       
-       /* 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 */
-       
-       /* 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);
-       
-       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));
-       
-       /* 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");   
+       assert (AOP_SIZE(result) == 1);
+       assert (AOP_SIZE(right) == 1);
+       assert (AOP_SIZE(left) == 1);
+
+       size = min(AOP_SIZE(result),AOP_SIZE(left));
+
+       if (AOP_TYPE(right) == AOP_LIT)
+       {
+               /* XXX: might add specialized code */
        }
-       while (size--)
-               aopPut(AOP(result),"a",offset++);
-       
+
+       if (SPEC_USIGN(operandType(left)) && SPEC_USIGN(operandType(right)))
+       {
+               /* 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
+                */
+
+               /* 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));
+       #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);
+       }
+
+       /* now performed the signed/unsigned division -- extend result */
+       addSign(result, 1, !SPEC_USIGN(operandType(result)));
 }
 
 /*-----------------------------------------------------------------*/
-/* 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);
@@ -3342,7 +3556,7 @@ release :
 }
 
 /*-----------------------------------------------------------------*/
-/* genModbits :- modulus of bits                                   */
+/* genModbits :- modulus of bits                                                                  */
 /*-----------------------------------------------------------------*/
 static void genModbits (operand *left, 
                                                operand *right, 
@@ -3351,11 +3565,12 @@ static void genModbits (operand *left,
        
        char *l;
        
-       /* the result must be bit */    
+       FENTRY;
+       /* 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("mov","a,b");
@@ -3364,81 +3579,93 @@ static void genModbits (operand *left,
 }
 
 /*-----------------------------------------------------------------*/
-/* genModOneByte : 8 bit modulus                                   */
+/* genModOneByte : 8 bit modulus                                                                  */
 /*-----------------------------------------------------------------*/
 static void genModOneByte (operand *left,
                                                   operand *right,
                                                   operand *result)
 {
-       sym_link *opetype = operandType(result);
-       char *l ;
-       symbol *lbl ;
+       int size;
        
+       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);
-       
-       pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
-       pic14_emitcode("push","acc"); /* save it on the stack */
-       
-       /* 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);
-       
-       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));
-       
-       /* 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));
-       
-       /* now we are done */
-       aopPut(AOP(result),"b",0);
        
+       assert (AOP_SIZE(result) == 1);
+       assert (AOP_SIZE(right) == 1);
+       assert (AOP_SIZE(left) == 1);
+
+       size = min(AOP_SIZE(result),AOP_SIZE(left));
+
+       if (AOP_TYPE(right) == AOP_LIT)
+       {
+               /* XXX: might add specialized code */
+       }
+
+       if (SPEC_USIGN(operandType(left)) && SPEC_USIGN(operandType(right)))
+       {
+               /* 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
+                */
+
+               /* XXX: This loops endlessly on DIVIDE BY ZERO */
+               /* We need 1..128 iterations of the loop body (`4 % 5' .. `255 % 2'). */
+               
+               if (!pic14_sameRegs(AOP(left), AOP(result)))
+               {
+                       mov2w(AOP(left),0);
+                       emitpcode(POC_MOVWF, popGet(AOP(result),0));
+               }
+               mov2w(AOP(right),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, !SPEC_USIGN(operandType(result)));
 }
 
 /*-----------------------------------------------------------------*/
-/* genMod - generates code for division                            */
+/* genMod - generates code for division                                                   */
 /*-----------------------------------------------------------------*/
 static void genMod (iCode *ic)
 {
@@ -3446,6 +3673,7 @@ static void genMod (iCode *ic)
        operand *right = IC_RIGHT(ic);
        operand *result= IC_RESULT(ic);  
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* assign the amsops */
        aopOp (left,ic,FALSE);
@@ -3477,7 +3705,7 @@ release :
 }
 
 /*-----------------------------------------------------------------*/
-/* genIfxJump :- will create a jump depending on the ifx           */
+/* genIfxJump :- will create a jump depending on the ifx                  */
 /*-----------------------------------------------------------------*/
 /*
 note: May need to add parameter to indicate when a variable is in bit space.
@@ -3485,6 +3713,7 @@ 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 */
@@ -3495,8 +3724,8 @@ static void genIfxJump (iCode *ic, char *jval)
                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));
+                       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));
@@ -3510,8 +3739,8 @@ static void genIfxJump (iCode *ic, char *jval)
                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));
+                       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));
@@ -3524,11 +3753,13 @@ static void genIfxJump (iCode *ic, char *jval)
        ic->generated = 1;
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
-/* genSkip                                                         */
+/* genSkip                                                                                                                */
 /*-----------------------------------------------------------------*/
 static void genSkip(iCode *ifx,int status_bit)
 {
+       FENTRY;
        if(!ifx)
                return;
        
@@ -3573,29 +3804,34 @@ static void genSkip(iCode *ifx,int status_bit)
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
-/* genSkipc                                                        */
+/* genSkipc                                                                                                       */
 /*-----------------------------------------------------------------*/
 static void genSkipc(resolvedIfx *rifx)
 {
+       FENTRY;
        if(!rifx)
                return;
        
        if(rifx->condition)
-               emitSKPC;
-       else
                emitSKPNC;
+       else
+               emitSKPC;
        
        emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+       emitpComment ("%s:%u: created from rifx:%p", __FUNCTION__, __LINE__, rifx);
        rifx->generated = 1;
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
-/* genSkipz2                                                       */
+/* genSkipz2                                                                                                      */
 /*-----------------------------------------------------------------*/
 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
 {
+       FENTRY;
        if(!rifx)
                return;
        
@@ -3607,14 +3843,16 @@ static void genSkipz2(resolvedIfx *rifx, int invert_condition)
        emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
        rifx->generated = 1;
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genSkipz                                                        */
 /*-----------------------------------------------------------------*/
 static void genSkipz(iCode *ifx, int condition)
 {
-       if(!ifx)
-               return;
+       FENTRY;
+       assert (ifx != NULL);
        
        if(condition)
                emitSKPNZ;
@@ -3632,11 +3870,15 @@ static void genSkipz(iCode *ifx, int condition)
                pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
        
 }
+#endif
+
+#if 0
 /*-----------------------------------------------------------------*/
 /* genSkipCond                                                     */
 /*-----------------------------------------------------------------*/
 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
 {
+       FENTRY;
        if(!rifx)
                return;
        
@@ -3649,6 +3891,7 @@ static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
        emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
        rifx->generated = 1;
 }
+#endif
 
 #if 0
 /*-----------------------------------------------------------------*/
@@ -3679,6 +3922,241 @@ static int genChkZeroes(operand *op, int lit,  int size)
 }
 #endif
 
+
+#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
+
+/*-----------------------------------------------------------------*/
+/* 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)                              */
+/*-----------------------------------------------------------------*/
+void pic14_mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) {
+  if (aop->type == AOP_LIT) {
+    emitpcode (POC_MOVLW, popGetLit((lit >> (offset*8)) & 0x00FF));
+  } else {
+    emitpcode (POC_MOVFW, popGet (aop, offset));
+  }
+}
+
+/* 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)
+{
+  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
+
+  /*************************************************
+   * 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 = (unsigned long)floatFromVal(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 = (unsigned long)floatFromVal(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;
+      }
+    } 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;
+      }
+    } // 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 {
+    // 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
+}
+
+
+#if 0
+/* OLD VERSION -- BUGGY, DO NOT USE */
+
 /*-----------------------------------------------------------------*/
 /* genCmp :- greater or less than comparison                       */
 /*-----------------------------------------------------------------*/
@@ -3690,6 +4168,8 @@ static void genCmp (operand *left,operand *right,
        resolvedIfx rFalseIfx;
        //  resolvedIfx rTrueIfx;
        symbol *truelbl;
+
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /*
        if(ifx) {
@@ -3735,8 +4215,6 @@ static void genCmp (operand *left,operand *right,
        end the carry flag is set then we know that
                left is greater than right */
                
-               //    {
-               
                symbol *lbl  = newiTempLabel(NULL);
                
 #ifndef _swapp
@@ -3780,7 +4258,7 @@ static void genCmp (operand *left,operand *right,
                                        } else {
                                                emitpcode(POC_ADDLW, popGetLit(0x80));
                                                emitpcode(POC_ADDLW, popGetLit(i^0x80));
-                                               genSkipc(&rFalseIfx);
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                        }
                                        
                                } else {
@@ -3788,7 +4266,7 @@ static void genCmp (operand *left,operand *right,
                                                genSkipz2(&rFalseIfx,1);
                                        } else {
                                                emitpcode(POC_ADDLW, popGetLit(i));
-                                               genSkipc(&rFalseIfx);
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                        }
                                }
                                
@@ -3839,7 +4317,7 @@ static void genCmp (operand *left,operand *right,
                                                emitSKPNZ;
                                        }
                                        
-                                       genSkipc(&rFalseIfx);
+                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                        emitpLabel(truelbl->key);
                                        if(ifx) ifx->generated = 1;
                                        return;
@@ -3855,7 +4333,7 @@ static void genCmp (operand *left,operand *right,
                                                emitpcode(POC_MOVFW, popGet(AOP(left),size));
                                                emitpcode(POC_ADDLW, popGetLit( 0x80));
                                                emitpcode(POC_ADDLW, popGetLit(0x100-i));
-                                               genSkipc(&rFalseIfx);
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                                
                                                
                                                if(ifx) ifx->generated = 1;
@@ -3871,7 +4349,7 @@ static void genCmp (operand *left,operand *right,
                                                emitpcode(POC_MOVFW, popGet(AOP(left),size));
                                                emitpcode(POC_ADDLW, popGetLit( 0x80));
                                                emitpcode(POC_ADDLW, popGetLit(0x100-i));
-                                               genSkipc(&rFalseIfx);
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                                
                                                
                                                if(ifx) ifx->generated = 1;
@@ -3919,7 +4397,7 @@ static void genCmp (operand *left,operand *right,
                                        emitpcode(POC_SUBFW, popGet(AOP(left),size));
                                }
                                //rFalseIfx.condition ^= 1;
-                               genSkipc(&rFalseIfx);
+                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                
                                emitpLabel(truelbl->key);
                                
@@ -3927,419 +4405,420 @@ static void genCmp (operand *left,operand *right,
                                return;
                                
                                
-         }
-         
-         
-         /* sign is out of the way. So now do an unsigned compare */
-         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
-         
-         
-         /* General case - compare to an unsigned literal on the right.*/
-         
-         i = (lit >> (size*8)) & 0xff;
-         emitpcode(POC_MOVLW, popGetLit(i));
-         emitpcode(POC_SUBFW, popGet(AOP(left),size));
-         while(size--) {
-                 i = (lit >> (size*8)) & 0xff;
-                 
-                 if(i) {
-                         emitpcode(POC_MOVLW, popGetLit(i));
-                         emitSKPNZ;
-                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
-                 } else {
-                 /* this byte of the lit is zero, 
-                         *if it's not the last then OR in the variable */
-                         if(size)
-                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
-                 }
-         }
-         
-         
-         emitpLabel(lbl->key);
-         //if(emitFinalCheck)
-         genSkipc(&rFalseIfx);
-         if(sign)
-                 emitpLabel(truelbl->key);
-         
-         if(ifx) ifx->generated = 1;
-         return;
-         
-         
-       }
-#endif  // _swapp
-       
-       if(AOP_TYPE(left) == AOP_LIT) {
-               //symbol *lbl = newiTempLabel(NULL);
-               
-               //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
-               
-               
-               DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
-               
-               /* Special cases */
-               if((lit == 0) && (sign == 0)){
-                       
-                       size--;
-                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
-                       while(size) 
-                               emitpcode(POC_IORFW, popGet(AOP(right),--size));
-                       
-                       genSkipz2(&rFalseIfx,0);
-                       if(ifx) ifx->generated = 1;
-                       return;
-               }
-               
-               if(size==1) {
-                       /* Special cases */
-                       lit &= 0xff;
-                       if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
-                               /* degenerate compare can never be true */
-                               if(rFalseIfx.condition == 0)
-                                       emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
-                               
-                               if(ifx) ifx->generated = 1;
-                               return;
                        }
-                       
-                       if(sign) {
-                               /* signed comparisons to a literal byte */
-                               
-                               int lp1 = (lit+1) & 0xff;
-                               
-                               DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
-                               switch (lp1) {
-                               case 0:
-                                       rFalseIfx.condition ^= 1;
-                                       genSkipCond(&rFalseIfx,right,0,7);
-                                       break;
-                               case 0x7f:
-                                       emitpcode(POC_MOVFW, popGet(AOP(right),0));
-                                       emitpcode(POC_XORLW, popGetLit(0x7f));
-                                       genSkipz2(&rFalseIfx,1);
-                                       break;
-                               default:
-                                       emitpcode(POC_MOVFW, popGet(AOP(right),0));
-                                       emitpcode(POC_ADDLW, popGetLit(0x80));
-                                       emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
-                                       rFalseIfx.condition ^= 1;
-                                       genSkipc(&rFalseIfx);
-                                       break;
-                               }
-                               if(ifx) ifx->generated = 1;
-                       } else {
-                               /* unsigned comparisons to a literal byte */
+
+
+                       /* sign is out of the way. So now do an unsigned compare */
+                       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
+
+
+                       /* General case - compare to an unsigned literal on the right.*/
+
+                       i = (lit >> (size*8)) & 0xff;
+                       emitpcode(POC_MOVLW, popGetLit(i));
+                       emitpcode(POC_SUBFW, popGet(AOP(left),size));
+                       while(size--) {
+                               i = (lit >> (size*8)) & 0xff;
                                
-                               switch(lit & 0xff ) {
-                               case 0:
-                                       emitpcode(POC_MOVFW, popGet(AOP(right),0));
-                                       genSkipz2(&rFalseIfx,0);
-                                       if(ifx) ifx->generated = 1;
-                                       break;
-                               case 0x7f:
-                                       genSkipCond(&rFalseIfx,right,0,7);
-                                       if(ifx) ifx->generated = 1;
-                                       break;
-                                       
-                               default:
-                                       emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
-                                       emitpcode(POC_SUBFW, popGet(AOP(right),0));
-                                       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-                                       rFalseIfx.condition ^= 1;
-                                       if (AOP_TYPE(result) == AOP_CRY) {
-                                               genSkipc(&rFalseIfx);
-                                               if(ifx) ifx->generated = 1;
-                                       } else {
-                                               DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
-                                               emitpcode(POC_CLRF, popGet(AOP(result),0));
-                                               emitpcode(POC_RLF, popGet(AOP(result),0));
-                                               emitpcode(POC_MOVLW, popGetLit(0x01));
-                                               emitpcode(POC_XORWF, popGet(AOP(result),0));
-                                       }             
-                                       break;
+                               if(i) {
+                                       emitpcode(POC_MOVLW, popGetLit(i));
+                                       emitSKPNZ;
+                                       emitpcode(POC_SUBFW, popGet(AOP(left),size));
+                               } else {
+                               /* this byte of the lit is zero, 
+                                       *if it's not the last then OR in the variable */
+                                       if(size)
+                                               emitpcode(POC_IORFW, popGet(AOP(left),size));
                                }
                        }
+
+
+               emitpLabel(lbl->key);
+               //if(emitFinalCheck)
+               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+               if(sign)
+                       emitpLabel(truelbl->key);
+
+               if(ifx) ifx->generated = 1;
+               return;
+
+
+               }
+#endif  // _swapp
+
+               if(AOP_TYPE(left) == AOP_LIT) {
+                       //symbol *lbl = newiTempLabel(NULL);
                        
-                       //goto check_carry;
-                       return;
+                       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
                        
-               } else {
                        
-                       /* Size is greater than 1 */
+                       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
                        
-                       if(sign) {
-                               int lp1 = lit+1;
+                       /* Special cases */
+                       if((lit == 0) && (sign == 0)){
                                
                                size--;
+                               emitpcode(POC_MOVFW, popGet(AOP(right),size));
+                               while(size) 
+                                       emitpcode(POC_IORFW, popGet(AOP(right),--size));
                                
-                               if(lp1 == 0) {
-                                       /* this means lit = 0xffffffff, or -1 */
-                                       
+                               genSkipz2(&rFalseIfx,0);
+                               if(ifx) ifx->generated = 1;
+                               return;
+                       }
+                       
+                       if(size==1) {
+                               /* Special cases */
+                               lit &= 0xff;
+                               if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
+                                       /* degenerate compare can never be true */
+                                       if(rFalseIfx.condition == 0)
+                                               emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
                                        
-                                       DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
-                                       rFalseIfx.condition ^= 1;
-                                       genSkipCond(&rFalseIfx,right,size,7);
                                        if(ifx) ifx->generated = 1;
                                        return;
                                }
                                
-                               if(lit == 0) {
-                                       int s = size;
-                                       
-                                       if(rFalseIfx.condition) {
-                                               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
-                                               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
-                                       }
-                                       
-                                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
-                                       while(size--)
-                                               emitpcode(POC_IORFW, popGet(AOP(right),size));
+                               if(sign) {
+                                       /* signed comparisons to a literal byte */
                                        
+                                       int lp1 = (lit+1) & 0xff;
                                        
-                                       emitSKPZ;
-                                       if(rFalseIfx.condition) {
-                                               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
-                                               emitpLabel(truelbl->key);
-                                       }else {
+                                       DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
+                                       switch (lp1) {
+                                       case 0:
+                                               rFalseIfx.condition ^= 1;
+                                               genSkipCond(&rFalseIfx,right,0,7);
+                                               break;
+                                       case 0x7f:
+                                               emitpcode(POC_MOVFW, popGet(AOP(right),0));
+                                               emitpcode(POC_XORLW, popGetLit(0x7f));
+                                               genSkipz2(&rFalseIfx,1);
+                                               break;
+                                       default:
+                                               emitpcode(POC_MOVFW, popGet(AOP(right),0));
+                                               emitpcode(POC_ADDLW, popGetLit(0x80));
+                                               emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
                                                rFalseIfx.condition ^= 1;
-                                               genSkipCond(&rFalseIfx,right,s,7);
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+                                               break;
                                        }
-                                       
                                        if(ifx) ifx->generated = 1;
-                                       return;
+                               } else {
+                                       /* unsigned comparisons to a literal byte */
+                                       
+                                       switch(lit & 0xff ) {
+                                       case 0:
+                                               emitpcode(POC_MOVFW, popGet(AOP(right),0));
+                                               genSkipz2(&rFalseIfx,0);
+                                               if(ifx) ifx->generated = 1;
+                                               break;
+                                       case 0x7f:
+                                               genSkipCond(&rFalseIfx,right,0,7);
+                                               if(ifx) ifx->generated = 1;
+                                               break;
+                                               
+                                       default:
+                                               emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
+                                               emitpcode(POC_SUBFW, popGet(AOP(right),0));
+                                               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+                                               rFalseIfx.condition ^= 1;
+                                               if (AOP_TYPE(result) == AOP_CRY) {
+                                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+                                                       if(ifx) ifx->generated = 1;
+                                               } else {
+                                                       DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
+                                                       emitpcode(POC_CLRF, popGet(AOP(result),0));
+                                                       emitpcode(POC_RLF, popGet(AOP(result),0));
+                                                       emitpcode(POC_MOVLW, popGetLit(0x01));
+                                                       emitpcode(POC_XORWF, popGet(AOP(result),0));
+                                               }       
+                                               break;
+                                       }
                                }
                                
-                               if((size == 1) &&  (0 == (lp1&0xff))) {
-                                       /* lower byte of signed word is zero */
-                                       DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
-                                       i = ((lp1 >> 8) & 0xff) ^0x80;
-                                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
-                                       emitpcode(POC_ADDLW, popGetLit( 0x80));
-                                       emitpcode(POC_ADDLW, popGetLit(0x100-i));
-                                       rFalseIfx.condition ^= 1;
-                                       genSkipc(&rFalseIfx);
+                               //goto check_carry;
+                               return;
+                               
+                       } else {
+                               
+                               /* Size is greater than 1 */
+                               
+                               if(sign) {
+                                       int lp1 = lit+1;
                                        
+                                       size--;
                                        
-                                       if(ifx) ifx->generated = 1;
-                                       return;
-                               }
-                               
-                               if(lit & (0x80 << (size*8))) {
-                                       /* Lit is less than zero */
-                                       DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
-                                       //rFalseIfx.condition ^= 1;
-                                       //genSkipCond(&rFalseIfx,left,size,7);
-                                       //rFalseIfx.condition ^= 1;
-                                       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
-                                       //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+                                       if(lp1 == 0) {
+                                               /* this means lit = 0xffffffff, or -1 */
+                                               
+                                               
+                                               DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
+                                               rFalseIfx.condition ^= 1;
+                                               genSkipCond(&rFalseIfx,right,size,7);
+                                               if(ifx) ifx->generated = 1;
+                                               return;
+                                       }
                                        
-                                       if(rFalseIfx.condition)
-                                               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
-                                       else
-                                               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+                                       if(lit == 0) {
+                                               int s = size;
+                                               
+                                               if(rFalseIfx.condition) {
+                                                       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+                                                       emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+                                               }
+                                               
+                                               emitpcode(POC_MOVFW, popGet(AOP(right),size));
+                                               while(size--)
+                                                       emitpcode(POC_IORFW, popGet(AOP(right),size));
+                                               
+                                               
+                                               emitSKPZ;
+                                               if(rFalseIfx.condition) {
+                                                       emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
+                                                       emitpLabel(truelbl->key);
+                                               }else {
+                                                       rFalseIfx.condition ^= 1;
+                                                       genSkipCond(&rFalseIfx,right,s,7);
+                                               }
+                                               
+                                               if(ifx) ifx->generated = 1;
+                                               return;
+                                       }
                                        
+                                       if((size == 1) &&  (0 == (lp1&0xff))) {
+                                               /* lower byte of signed word is zero */
+                                               DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
+                                               i = ((lp1 >> 8) & 0xff) ^0x80;
+                                               emitpcode(POC_MOVFW, popGet(AOP(right),size));
+                                               emitpcode(POC_ADDLW, popGetLit( 0x80));
+                                               emitpcode(POC_ADDLW, popGetLit(0x100-i));
+                                               rFalseIfx.condition ^= 1;
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+                                               
+                                               
+                                               if(ifx) ifx->generated = 1;
+                                               return;
+                                       }
+                                       
+                                       if(lit & (0x80 << (size*8))) {
+                                               /* Lit is less than zero */
+                                               DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
+                                               //rFalseIfx.condition ^= 1;
+                                               //genSkipCond(&rFalseIfx,left,size,7);
+                                               //rFalseIfx.condition ^= 1;
+                                               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+                                               //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+                                               
+                                               if(rFalseIfx.condition)
+                                                       emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
+                                               else
+                                                       emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+                                               
+                                               
+                                       } else {
+                                               /* Lit is greater than or equal to zero */
+                                               DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
+                                               //rFalseIfx.condition ^= 1;
+                                               //genSkipCond(&rFalseIfx,right,size,7);
+                                               //rFalseIfx.condition ^= 1;
+                                               
+                                               //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+                                               //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
+                                               
+                                               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+                                               if(rFalseIfx.condition)
+                                                       emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+                                               else
+                                                       emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
+                                               
+                                       }
+                                       
+                                       
+                                       emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
+                                       emitpcode(POC_SUBFW, popGet(AOP(right),size));
+                                       
+                                       while(size--) {
+                                               
+                                               emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
+                                               emitSKPNZ;
+                                               emitpcode(POC_SUBFW, popGet(AOP(right),size));
+                                       }
+                                       rFalseIfx.condition ^= 1;
+                                       //rFalseIfx.condition = 1;
+                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+                                       
+                                       emitpLabel(truelbl->key);
                                        
+                                       if(ifx) ifx->generated = 1;
+                                       return;
+                                       // end of if (sign)
                                } else {
-                                       /* Lit is greater than or equal to zero */
-                                       DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
-                                       //rFalseIfx.condition ^= 1;
-                                       //genSkipCond(&rFalseIfx,right,size,7);
-                                       //rFalseIfx.condition ^= 1;
                                        
-                                       //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
-                                       //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
+                                       /* compare word or long to an unsigned literal on the right.*/
                                        
-                                       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
-                                       if(rFalseIfx.condition)
-                                               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
-                                       else
-                                               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
                                        
-                               }
-                               
-                               
-                               emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
-                               emitpcode(POC_SUBFW, popGet(AOP(right),size));
-                               
-                               while(size--) {
+                                       size--;
+                                       if(lit < 0xff) {
+                                               DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
+                                               switch (lit) {
+                                               case 0:
+                                                       break; /* handled above */
+                                               /*
+                                               case 0xff:
+                                                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
+                                                       while(size--)
+                                                               emitpcode(POC_IORFW, popGet(AOP(right),size));
+                                                       genSkipz2(&rFalseIfx,0);
+                                                       break;
+                                               */
+                                               default:
+                                                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
+                                                       while(--size)
+                                                               emitpcode(POC_IORFW, popGet(AOP(right),size));
+                                                       
+                                                       emitSKPZ;
+                                                       if(rFalseIfx.condition)
+                                                               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
+                                                       else
+                                                               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+                                                       
+                                                       
+                                                       emitpcode(POC_MOVLW, popGetLit(lit+1));
+                                                       emitpcode(POC_SUBFW, popGet(AOP(right),0));
+                                                       
+                                                       rFalseIfx.condition ^= 1;
+                                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+                                               }
+                                               
+                                               emitpLabel(truelbl->key);
+                                               
+                                               if(ifx) ifx->generated = 1;
+                                               return;
+                                       }
                                        
-                                       emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
-                                       emitSKPNZ;
+                                       
+                                       lit++;
+                                       DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
+                                       i = (lit >> (size*8)) & 0xff;
+                                       
+                                       emitpcode(POC_MOVLW, popGetLit(i));
                                        emitpcode(POC_SUBFW, popGet(AOP(right),size));
+                                       
+                                       while(size--) {
+                                               i = (lit >> (size*8)) & 0xff;
+                                               
+                                               if(i) {
+                                                       emitpcode(POC_MOVLW, popGetLit(i));
+                                                       emitSKPNZ;
+                                                       emitpcode(POC_SUBFW, popGet(AOP(right),size));
+                                               } else {
+                                               /* this byte of the lit is zero, 
+                                                       *if it's not the last then OR in the variable */
+                                                       if(size)
+                                                               emitpcode(POC_IORFW, popGet(AOP(right),size));
+                                               }
+                                       }
+                                       
+                                       
+                                       emitpLabel(lbl->key);
+                                       
+                                       rFalseIfx.condition ^= 1;
+                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                }
-                               rFalseIfx.condition ^= 1;
-                               //rFalseIfx.condition = 1;
-                               genSkipc(&rFalseIfx);
-                               
-                               emitpLabel(truelbl->key);
                                
+                               if(sign)
+                                       emitpLabel(truelbl->key);
                                if(ifx) ifx->generated = 1;
                                return;
-                               // end of if (sign)
-       } else {
-               
-               /* compare word or long to an unsigned literal on the right.*/
+                       }
+               }
+               /* Compare two variables */
                
+               DEBUGpic14_emitcode(";sign","%d",sign);
                
                size--;
-               if(lit < 0xff) {
-                       DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
-                       switch (lit) {
-                       case 0:
-                               break; /* handled above */
-                       /*
-                       case 0xff:
-                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
-                       while(size--)
-                       emitpcode(POC_IORFW, popGet(AOP(right),size));
-                       genSkipz2(&rFalseIfx,0);
-                       break;
-                       */
-                       default:
-                               emitpcode(POC_MOVFW, popGet(AOP(right),size));
-                               while(--size)
-                                       emitpcode(POC_IORFW, popGet(AOP(right),size));
-                               
-                               emitSKPZ;
-                               if(rFalseIfx.condition)
-                                       emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
-                               else
-                                       emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
-                               
+               if(sign) {
+                       /* Sigh. thus sucks... */
+                       if(size) {
+                               emitpcode(POC_MOVFW, popGet(AOP(left),size));
+                               emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+                               emitpcode(POC_MOVLW, popGetLit(0x80));
+                               emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
+                               emitpcode(POC_XORFW, popGet(AOP(right),size));
+                               emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
+                       } else {
+                               /* Signed char comparison */
+                               /* Special thanks to Nikolai Golovchenko for this snippet */
+                               emitpcode(POC_MOVFW, popGet(AOP(right),0));
+                               emitpcode(POC_SUBFW, popGet(AOP(left),0));
+                               emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
+                               emitpcode(POC_XORFW, popGet(AOP(left),0));
+                               emitpcode(POC_XORFW, popGet(AOP(right),0));
+                               emitpcode(POC_ADDLW, popGetLit(0x80));
                                
-                               emitpcode(POC_MOVLW, popGetLit(lit+1));
-                               emitpcode(POC_SUBFW, popGet(AOP(right),0));
+                               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                
-                               rFalseIfx.condition ^= 1;
-                               genSkipc(&rFalseIfx);
+                               if(ifx) ifx->generated = 1;
+                               return;
                        }
                        
-                       emitpLabel(truelbl->key);
+               } else {
                        
-                       if(ifx) ifx->generated = 1;
-                       return;
+                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
+                       emitpcode(POC_SUBFW, popGet(AOP(left),size));
                }
                
                
-               lit++;
-               DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
-               i = (lit >> (size*8)) & 0xff;
-               
-               emitpcode(POC_MOVLW, popGetLit(i));
-               emitpcode(POC_SUBFW, popGet(AOP(right),size));
-               
-               while(size--) {
-                       i = (lit >> (size*8)) & 0xff;
+               /* The rest of the bytes of a multi-byte compare */
+               while (size) {
                        
-                       if(i) {
-                               emitpcode(POC_MOVLW, popGetLit(i));
-                               emitSKPNZ;
-                               emitpcode(POC_SUBFW, popGet(AOP(right),size));
-                       } else {
-                       /* this byte of the lit is zero, 
-                               *if it's not the last then OR in the variable */
-                               if(size)
-                                       emitpcode(POC_IORFW, popGet(AOP(right),size));
-                       }
-               }
-               
-               
-               emitpLabel(lbl->key);
-               
-               rFalseIfx.condition ^= 1;
-               genSkipc(&rFalseIfx);
-       }
-       
-       if(sign)
-               emitpLabel(truelbl->key);
-       if(ifx) ifx->generated = 1;
-       return;
-         }
-       }
-       /* Compare two variables */
-       
-       DEBUGpic14_emitcode(";sign","%d",sign);
-       
-       size--;
-       if(sign) {
-               /* Sigh. thus sucks... */
-               if(size) {
-                       emitpcode(POC_MOVFW, popGet(AOP(left),size));
-                       emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
-                       emitpcode(POC_MOVLW, popGetLit(0x80));
-                       emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
-                       emitpcode(POC_XORFW, popGet(AOP(right),size));
-                       emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
-               } else {
-                       /* Signed char comparison */
-                       /* Special thanks to Nikolai Golovchenko for this snippet */
-                       emitpcode(POC_MOVFW, popGet(AOP(right),0));
-                       emitpcode(POC_SUBFW, popGet(AOP(left),0));
-                       emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
-                       emitpcode(POC_XORFW, popGet(AOP(left),0));
-                       emitpcode(POC_XORFW, popGet(AOP(right),0));
-                       emitpcode(POC_ADDLW, popGetLit(0x80));
+                       emitSKPZ;
+                       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
+                       size--;
+                       
+                       emitpcode(POC_MOVFW, popGet(AOP(right),size));
+                       emitpcode(POC_SUBFW, popGet(AOP(left),size));
                        
-                       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-                       genSkipc(&rFalseIfx);
                        
-                       if(ifx) ifx->generated = 1;
-                       return;
                }
                
-       } else {
-               
-               emitpcode(POC_MOVFW, popGet(AOP(right),size));
-               emitpcode(POC_SUBFW, popGet(AOP(left),size));
-       }
-       
-       
-       /* The rest of the bytes of a multi-byte compare */
-       while (size) {
-               
-               emitSKPZ;
-               emitpcode(POC_GOTO,  popGetLabel(lbl->key));
-               size--;
+               emitpLabel(lbl->key);
                
-               emitpcode(POC_MOVFW, popGet(AOP(right),size));
-               emitpcode(POC_SUBFW, popGet(AOP(left),size));
+               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+               if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
+                       (AOP_TYPE(result) == AOP_REG)) {
+                       emitpcode(POC_CLRF, popGet(AOP(result),0));
+                       emitpcode(POC_RLF, popGet(AOP(result),0));
+               } else {
+                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+               }       
+               //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+               if(ifx) ifx->generated = 1;
                
+               return;
                
        }
        
-       emitpLabel(lbl->key);
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
-               (AOP_TYPE(result) == AOP_REG)) {
-               emitpcode(POC_CLRF, popGet(AOP(result),0));
-               emitpcode(POC_RLF, popGet(AOP(result),0));
+       // check_carry:
+       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
+               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+               pic14_outBitC(result);
        } else {
-               genSkipc(&rFalseIfx);
-       }             
-       //genSkipc(&rFalseIfx);
-       if(ifx) ifx->generated = 1;
-       
-       return;
+               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+               /* if the result is used in the next
+               ifx conditional branch then generate
+               code a little differently */
+               if (ifx )
+                       genIfxJump (ifx,"c");
+               else
+                       pic14_outBitC(result);
+               /* leave the result in acc */
+       }
        
-  }
-  
-  // check_carry:
-  if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-         pic14_outBitC(result);
-  } else {
-         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-         /* if the result is used in the next
-         ifx conditional branch then generate
-         code a little differently */
-         if (ifx )
-                 genIfxJump (ifx,"c");
-         else
-                 pic14_outBitC(result);
-         /* leave the result in acc */
-  }
-  
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genCmpGt :- greater than comparison                             */
@@ -4350,6 +4829,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);
@@ -4379,6 +4859,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);
@@ -4400,6 +4881,7 @@ static void genCmpLt (iCode *ic, iCode *ifx)
        freeAsmop(result,NULL,ic,TRUE); 
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genc16bit2lit - compare a 16 bit value to a literal             */
 /*-----------------------------------------------------------------*/
@@ -4407,6 +4889,7 @@ static void genc16bit2lit(operand *op, int lit, int offset)
 {
        int i;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
        if( (lit&0xff) == 0) 
                i=1;
@@ -4450,26 +4933,69 @@ static void genc16bit2lit(operand *op, int lit, int offset)
        }
        
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* gencjneshort - compare and jump if not equal                    */
 /*-----------------------------------------------------------------*/
 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
 {
-       int size = max(AOP_SIZE(left),AOP_SIZE(right));
+       int size = min(AOP_SIZE(left),AOP_SIZE(right));
        int offset = 0;
-       int res_offset = 0;  /* the result may be a different size then left or right */
-       int res_size = AOP_SIZE(result);
-       resolvedIfx rIfx;
+       //resolvedIfx rIfx;
        symbol *lbl;
        
-       unsigned long lit = 0L;
+       //unsigned long lit = 0L;
+       FENTRY;
+       if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
+         emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
+         return;
+       }
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        DEBUGpic14_AopType(__LINE__,left,right,result);
+       
+       assert (!pic14_sameRegs (AOP(left), AOP(result)));
+       assert (!pic14_sameRegs (AOP(right), AOP(result)));
+       if (AOP_SIZE(result)) {
+         for (offset = 0; offset < AOP_SIZE(result); offset++)
+           emitpcode (POC_CLRF, popGet (AOP(result), offset));
+       }
+       
+       assert (AOP_SIZE(left) == AOP_SIZE(right));
+       //resolveIfx(&rIfx,ifx);
+       lbl = newiTempLabel (NULL);
+       while (size--)
+       {
+         mov2w (AOP(right),size);
+         emitpcode (POC_XORFW, popGet (AOP(left), size));
+         if (size)
+         {
+           emitSKPZ;
+           emitpcode (POC_GOTO, popGetLabel (lbl->key));
+         }
+       } // while
+       emitpLabel (lbl->key);
+       if (AOP_SIZE(result)) {
+         emitSKPNZ;
+         emitpcode (POC_INCF, popGet (AOP(result), 0));
+       } else {
+         assert (ifx);
+         genSkipz (ifx, NULL != IC_TRUE(ifx));
+         ifx->generated = 1;
+       }
+       return;
+#if 0  
        if(result)
+       {
                DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
-       resolveIfx(&rIfx,ifx);
-       lbl =  newiTempLabel(NULL);
+               assert (!pic14_sameRegs (AOP(result), AOP(left)));
+               assert (!pic14_sameRegs (AOP(result), AOP(right)));
+               for (offset=0; offset < AOP_SIZE(result); offset++)
+               {
+                       emitpcode (POC_CLRF, popGet (AOP(result), offset));
+               } // for offset
+       }
        
        
        /* if the left side is a literal or 
@@ -4494,6 +5020,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                        emitpcode(POC_GOTO,popGetLabel(lbl->key));
                        break;
                default:
+                       offset = 0;
                        while (size--) {
                                if(lit & 0xff) {
                                        emitpcode(POC_MOVFW,popGet(AOP(left),offset));
@@ -4505,8 +5032,6 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                emitSKPNZ;
                                emitpcode(POC_GOTO,popGetLabel(lbl->key));
                                offset++;
-                               if(res_offset < res_size-1)
-                                       res_offset++;
                                lit >>= 8;
                        }
                        break;
@@ -4522,10 +5047,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
                int lbl_key = lbl->key;
                
-               if(result) {
-                       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
-                       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
-               }else {
+               if(!result) {
                        DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
                        fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
                                __FUNCTION__,__LINE__);
@@ -4539,6 +5061,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
                /*       break; */
                /*     default: */
+               offset = 0;
                while (size--) {
                        int emit_skip=1;
                        if((AOP_TYPE(left) == AOP_DIR) && 
@@ -4555,8 +5078,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                        break;
                                case 1:
                                        emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
-                                       emitpcode(POC_INCF,popGet(AOP(result),res_offset));
-                                       //emitpcode(POC_GOTO,popGetLabel(lbl->key));
+                                       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+                                       emitpcode(POC_GOTO,popGetLabel(lbl->key));
                                        emit_skip=0;
                                        break;
                                case 0xff:
@@ -4591,377 +5114,199 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                        else
                                                emitSKPNZ;
                                        emitpcode(POC_GOTO,popGetLabel(lbl_key));
-                                       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
-                               }
-                               if(ifx)
-                                       ifx->generated=1;
-                       }
-                       emit_skip++;
-                       offset++;
-                       if(res_offset < res_size-1)
-                               res_offset++;
-               }
-               /*       break; */
-               /*     } */
-       } else if(AOP_TYPE(right) == AOP_REG &&
-               AOP_TYPE(left) != AOP_DIR){
-               
-               while(size--) {
-                       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-                       emitpcode(POC_XORFW,popGet(AOP(right),offset));
-                       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
-                       if(rIfx.condition)
-                               emitSKPNZ;
-                       else
-                               emitSKPZ;
-                       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
-                       offset++;
-                       if(res_offset < res_size-1)
-                               res_offset++;
-               }
-               
-       }else{
-               /* right is a pointer reg need both a & b */
-               while(size--) {
-                       char *l = 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++;
-               }
-       }
-       
-       emitpcode(POC_INCF,popGet(AOP(result),res_offset));
-       if(!rIfx.condition)
-               emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
-       
-       emitpLabel(lbl->key);
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       
-       if(ifx)
-               ifx->generated = 1;
-}
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* gencjne - compare and jump if not equal                         */
-/*-----------------------------------------------------------------*/
-static void gencjne(operand *left, operand *right, iCode *ifx)
-{
-       symbol *tlbl  = newiTempLabel(NULL);
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       gencjneshort(left, right, lbl);
-       
-       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);
-       
-       emitpLabel(lbl->key);
-       emitpLabel(tlbl->key);
-       
-}
-#endif
-
-/*-----------------------------------------------------------------*/
-/* 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;
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       
-       if(ifx)
-               DEBUGpic14_emitcode ("; ifx is non-null","");
-       else
-               DEBUGpic14_emitcode ("; ifx is null","");
-       
-       aopOp((left=IC_LEFT(ic)),ic,FALSE);
-       aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-       aopOp((result=IC_RESULT(ic)),ic,TRUE);
-       
-       size = max(AOP_SIZE(left),AOP_SIZE(right));
-       
-       DEBUGpic14_AopType(__LINE__,left,right,result);
-       
-       /* 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 *tmp = right ;
-               right = left;
-               left = tmp;
-       }
-       
-       
-       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(right)->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);
-                       
-                       {
-                               /* left and right are both bit variables, result is carry */
-                               resolvedIfx rIfx;
-                               
-                               resolveIfx(&rIfx,ifx);
-                               
-                               emitpcode(POC_MOVLW,popGet(AOP(left),0));
-                               emitpcode(POC_ANDFW,popGet(AOP(left),0));
-                               emitpcode(POC_BTFSC,popGet(AOP(right),0));
-                               emitpcode(POC_ANDLW,popGet(AOP(left),0));
-                               genSkipz2(&rIfx,0);
-                       }
-               } else {
-                       
-                       /* They're not both bit variables. Is the right a literal? */
-                       if(AOP_TYPE(right) == AOP_LIT) {
-                               lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-                               
-                               switch(size) {
-                                       
-                               case 1:
-                                       switch(lit & 0xff) {
-                                       case 1:
-                                               if ( IC_TRUE(ifx) ) {
-                                                       emitpcode(POC_DECFW,popGet(AOP(left),offset));
-                                                       emitSKPNZ;
-                                                       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-                                               } else {
-                                                       emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
-                                                       emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-                                               }
-                                               break;
-                                       case 0xff:
-                                               if ( IC_TRUE(ifx) ) {
-                                                       emitpcode(POC_INCFW,popGet(AOP(left),offset));
-                                                       emitSKPNZ;
-                                                       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-                                               } else {
-                                                       emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
-                                                       emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-                                               }
-                                               break;
-                                       default:
-                                               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-                                               if(lit)
-                                                       emitpcode(POC_XORLW,popGetLit(lit & 0xff));
-                                               genSkip(ifx,'z');
-                                       }
-                                       
-                                       
-                                       /* end of size == 1 */
-                                       break;
-                                       
-                                       case 2:
-                                               genc16bit2lit(left,lit,offset);
-                                               genSkip(ifx,'z');
-                                               break;
-                                               /* end of size == 2 */
-                                               
-                                       default:
-                                               /* size is 4 */
-                                               if(lit==0) {
-                                                       emitpcode(POC_MOVFW,popGet(AOP(left),0));
-                                                       emitpcode(POC_IORFW,popGet(AOP(left),1));
-                                                       emitpcode(POC_IORFW,popGet(AOP(left),2));
-                                                       emitpcode(POC_IORFW,popGet(AOP(left),3));
-                                                       
-                                               } else {
-                                                       
-                                                       /* search for patterns that can be optimized */
-                                                       
-                                                       genc16bit2lit(left,lit,0);
-                                                       lit >>= 16;
-                                                       if(lit) {
-                                                               genSkipz(ifx,IC_TRUE(ifx) == NULL);
-                                                               //genSkip(ifx,'z');
-                                                               genc16bit2lit(left,lit,2);
-                                                       } else {
-                                                               emitpcode(POC_IORFW,popGet(AOP(left),2));
-                                                               emitpcode(POC_IORFW,popGet(AOP(left),3));
-                                                               
-                                                       }
-                                                       
-                                               }
-                                               
-                                               genSkip(ifx,'z');
-                               }
-                               
-                               ifx->generated = 1;
-                               goto release ;
-                               
-                               
-                       } else if(AOP_TYPE(right) == AOP_CRY ) {
-                               /* we know the left is not a bit, but that the right is */
-                               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-                               emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
-                                       popGet(AOP(right),offset));
-                               emitpcode(POC_XORLW,popGetLit(1));
-                               
-                               /* if the two are equal, then W will be 0 and the Z bit is set
-                               * we could test Z now, or go ahead and check the high order bytes if
-                               * the variable we're comparing is larger than a byte. */
-                               
-                               while(--size)
-                                       emitpcode(POC_IORFW,popGet(AOP(left),offset));
-                               
-                               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));
-                                       emitpcode(POC_XORFW,popGet(AOP(right),offset));
-                                       
-                                       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);
-                                       pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
                                }
-                       }
-               }
-               /* mark the icode as generated */
-               ifx->generated = 1;
-               goto release ;
-       }
-       
-       /* 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(right)->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 {
-               
-               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               gencjne(left,right,result,ifx);
-               /*
-               if(ifx) 
-               gencjne(left,right,newiTempLabel(NULL));
-               else {
-               if(IC_TRUE(ifx)->key)
-               gencjne(left,right,IC_TRUE(ifx)->key);
-               else
-               gencjne(left,right,IC_FALSE(ifx)->key);
-               ifx->generated = 1;
-               goto release ;
+                               if(ifx)
+                                       ifx->generated=1;
+                       }
+                       emit_skip++;
+                       offset++;
                }
-               if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-               aopPut(AOP(result),"a",0);
-               goto release ;
+               /*       break; */
+               /*     } */
+       } else if(AOP_TYPE(right) == AOP_REG &&
+               AOP_TYPE(left) != AOP_DIR){
+
+               offset = 0;
+               while(size--) {
+                       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+                       emitpcode(POC_XORFW,popGet(AOP(right),offset));
+                       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
+                       if(rIfx.condition)
+                               emitSKPNZ;
+                       else
+                               emitSKPZ;
+                       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+                       offset++;
                }
                
-                 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 */
+       }else{
+               /* right is a pointer reg need both a & b */
+               offset = 0;
+               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++;
+               }
        }
        
-release:
-       freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-       freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-       freeAsmop(result,NULL,ic,TRUE);
+       emitpcode(POC_INCF,popGet(AOP(result),0));
+       if(!rIfx.condition)
+               emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+       
+       emitpLabel(lbl->key);
+       
+       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       
+       if(ifx)
+               ifx->generated = 1;
+#endif
+}
+#endif
+
+#if 0
+/*-----------------------------------------------------------------*/
+/* gencjne - compare and jump if not equal                         */
+/*-----------------------------------------------------------------*/
+static void gencjne(operand *left, operand *right, iCode *ifx)
+{
+       symbol *tlbl  = newiTempLabel(NULL);
+       
+       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       gencjneshort(left, right, lbl);
+       
+       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);
+       
+       emitpLabel(lbl->key);
+       emitpLabel(tlbl->key);
+       
+}
+#endif
+
+/*-----------------------------------------------------------------*/
+/* genCmpEq - generates code for equal to                          */
+/*-----------------------------------------------------------------*/
+static void genCmpEq (iCode *ic, iCode *ifx)
+{
+  operand *left, *right, *result;
+  int size;
+  symbol *false_label;
+
+  FENTRY;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  if(ifx)
+    DEBUGpic14_emitcode ("; ifx is non-null","");
+  else
+    DEBUGpic14_emitcode ("; ifx is null","");
+
+  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 literal, move literal to right */ 
+  if (op_isLitLike (IC_LEFT(ic))) {
+    operand *tmp = right ;
+    right = left;
+    left = tmp;
+  }
+
+  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)));
+
+  /* assume left != right */
+  {
+    int i;
+    for (i=0; i < AOP_SIZE(result); i++)
+    {
+      emitpcode(POC_CLRF, popGet(AOP(result),i));
+    }
+  }
+
+  if (AOP_TYPE(right) == AOP_LIT)
+  {
+    unsigned long lit = (unsigned long) floatFromVal (AOP(right)->aopu.aop_lit);
+    int i;
+    size = AOP_SIZE(left);
+    assert(!op_isLitLike(left));
+
+    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;
+
+      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;
+
+    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 we reach here, left == right */
+
+  if (AOP_SIZE(result) > 0)
+  {
+    emitpcode(POC_INCF, popGet(AOP(result),0));
+  }
+
+  if (ifx && IC_TRUE(ifx))
+  {
+    emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
+  }
+
+  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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4969,13 +5314,14 @@ 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))
                return NULL ;
        
-               /* if this has register type condition and
-               the next instruction is ifx with the same operand
+       /* if this has register type condition and
+       the next instruction is ifx with the same operand
        and live to of the operand is upto the ifx only then */
        if (ic->next &&
                ic->next->op == IFX &&
@@ -5015,6 +5361,7 @@ static void genAndOp (iCode *ic)
        operand *left,*right, *result;
        /*     symbol *tlbl; */
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* note here that && operations that are in an
        if statement are taken away by backPatchLabels
@@ -5062,39 +5409,33 @@ 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);
        
        DEBUGpic14_AopType(__LINE__,left,right,result);
-       
-       /* 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","");
-               
-       } 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);
-               
-               pic14_outBitAcc(result);
-       }
+
+       for (i=0; i < AOP_SIZE(result); i++)
+       {
+               emitpcode(POC_CLRF, popGet(AOP(result), i));
+       } // for i
+
+       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));
@@ -5115,6 +5456,7 @@ static int isLiteralBit(unsigned long lit)
                0x10000000L,0x20000000L,0x40000000L,0x80000000L};
        int idx;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        for(idx = 0; idx < 32; idx++)
                if(lit == pw[idx])
@@ -5127,6 +5469,7 @@ 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);
@@ -5138,6 +5481,7 @@ static void continueIfTrue (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void jumpIfTrue (iCode *ic)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(!IC_TRUE(ic))
                pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
@@ -5149,6 +5493,7 @@ 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)){
@@ -5176,7 +5521,7 @@ static void genAnd (iCode *ic, iCode *ifx)
        int bytelit = 0;
        resolvedIfx rIfx;
        
-       
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        aopOp((left = IC_LEFT(ic)),ic,FALSE);
        aopOp((right= IC_RIGHT(ic)),ic,FALSE);
@@ -5331,7 +5676,6 @@ static void genAnd (iCode *ic, iCode *ifx)
                                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));
                                        break;
                                case 0xff:
@@ -5343,12 +5687,9 @@ static void genAnd (iCode *ic, iCode *ifx)
                                                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,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
                                                        
                                                } else {
-                                                       pic14_emitcode("movlw","0x%x", (lit & 0xff));
-                                                       pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
                                                        if(know_W != (int)(lit&0xff))
                                                                emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
                                                        know_W = lit &0xff;
@@ -5359,7 +5700,7 @@ static void genAnd (iCode *ic, iCode *ifx)
                        } else {
                                if (AOP_TYPE(left) == AOP_ACC) {
                                        emitpcode(POC_ANDFW,popGet(AOP(right),offset));
-                               } else {                    
+                               } else {        
                                        emitpcode(POC_MOVFW,popGet(AOP(right),offset));
                                        emitpcode(POC_ANDWF,popGet(AOP(left),offset));
                                        
@@ -5398,16 +5739,10 @@ static void genAnd (iCode *ic, iCode *ifx)
                                        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));
                                                break;
                                        case 0xff:
                                                if(AOP_TYPE(left) != AOP_ACC) {
-                                                       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));
                                                }
                                                emitpcode(POC_MOVWF,popGet(AOP(result),offset));
@@ -5416,12 +5751,6 @@ static void genAnd (iCode *ic, iCode *ifx)
                                                if(AOP_TYPE(left) == AOP_ACC) {
                                                        emitpcode(POC_ANDLW, popGetLit(t));
                                                } else {
-                                                       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));
                                                }
@@ -5431,16 +5760,11 @@ static void genAnd (iCode *ic, iCode *ifx)
                                }
                                
                                if (AOP_TYPE(left) == AOP_ACC) {
-                                       pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
                                        emitpcode(POC_ANDFW,popGet(AOP(right),offset));
                                } 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));
                                        emitpcode(POC_ANDFW,popGet(AOP(left),offset));
                                }
-                               pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
                                emitpcode(POC_MOVWF,popGet(AOP(result),offset));
                        }
                }
@@ -5461,6 +5785,7 @@ 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);
@@ -5510,8 +5835,8 @@ static void genOr (iCode *ic, iCode *ifx)
                                        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);
+                                       //   AOP(result)->aopu.aop_dir,
+                                       //   AOP(result)->aopu.aop_dir);
                                        else if(ifx)
                                                continueIfTrue(ifx);
                                        goto release;
@@ -5607,12 +5932,12 @@ static void genOr (iCode *ic, iCode *ifx)
                        genIfxJump(ifx, "c");           
                goto release ;
        }
-       
+
        // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
        // bit = val | 0xZZ     - size = 1, ifx = FALSE -
        if((AOP_TYPE(right) == AOP_LIT) &&
-               (AOP_TYPE(result) == AOP_CRY) &&
-               (AOP_TYPE(left) != AOP_CRY)){
+         (AOP_TYPE(result) == AOP_CRY) &&
+         (AOP_TYPE(left) != AOP_CRY)){
                if(lit){
                        pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
                        // result = 1
@@ -5640,7 +5965,7 @@ static void genOr (iCode *ic, iCode *ifx)
                pic14_outBitC(result);
                goto release ;
        }
-       
+
        /* if left is same as result */
        if(pic14_sameRegs(AOP(result),AOP(left))){
                int know_W = -1;
@@ -5667,7 +5992,7 @@ static void genOr (iCode *ic, iCode *ifx)
                                if (AOP_TYPE(left) == AOP_ACC) {
                                        emitpcode(POC_IORFW,  popGet(AOP(right),offset));
                                        pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-                               } else {                    
+                               } else {        
                                        emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
                                        emitpcode(POC_IORWF,  popGet(AOP(left),offset));
                                        
@@ -5705,7 +6030,7 @@ static void genOr (iCode *ic, iCode *ifx)
                                jmpTrueOrFalse(ifx, tlbl);
                } else for(;(size--);offset++){
                        // normal case
-                       // result = left & right
+                       // result = left | right
                        if(AOP_TYPE(right) == AOP_LIT){
                                int t = (lit >> (offset*8)) & 0x0FFL;
                                switch(t) { 
@@ -5723,7 +6048,7 @@ static void genOr (iCode *ic, iCode *ifx)
                                                emitpcode(POC_MOVLW,  popGetLit(t));
                                                emitpcode(POC_IORFW,  popGet(AOP(left),offset));
                                        }
-                                       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));            
+                                       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
                                }
                                continue;
                        }
@@ -5731,21 +6056,15 @@ static void genOr (iCode *ic, iCode *ifx)
                        // 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));
-                               pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+                               emitpcode(POC_IORFW,popGet(AOP(right),offset));
                        } else {
-                               emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
-                               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
-                               
-                               pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-                               pic14_emitcode("iorwf","%s,w",
-                                       aopGet(AOP(left),offset,FALSE,FALSE));
+                               emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+                               emitpcode(POC_IORFW,popGet(AOP(left),offset));
                        }
                        emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
-                       pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
                }
        }
-       
+
 release :
        freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
        freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
@@ -5761,6 +6080,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);
@@ -5826,6 +6146,7 @@ static void genXor (iCode *ic, iCode *ifx)
                                                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");
                                        }
@@ -5979,16 +6300,12 @@ static void genXor (iCode *ic, iCode *ifx)
                        // and better if result is SFR
                        if (AOP_TYPE(left) == AOP_ACC) {
                                emitpcode(POC_XORFW,popGet(AOP(right),offset));
-                               pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
                        } else {
                                emitpcode(POC_MOVFW,popGet(AOP(right),offset));
                                emitpcode(POC_XORFW,popGet(AOP(left),offset));
-                               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));
-                               pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
                        }
                }
        }
@@ -6004,40 +6321,45 @@ release :
 /*-----------------------------------------------------------------*/
 static void genInline (iCode *ic)
 {
-       char *buffer, *bp, *bp1;
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       
-       _G.inLine += (!options.asmpeep);
-       
-       buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
-       strcpy(buffer,IC_INLINE(ic));
-       
-       /* emit each line as a code */
-       while (*bp) {
-               if (*bp == '\n') {
-                       *bp++ = '\0';
-                       
-                       if(*bp1)
-                               addpCode2pBlock(pb,AssembleLine(bp1));
-                       bp1 = bp;
-               } else {
-                       if (*bp == ':') {
-                               bp++;
-                               *bp = '\0';
-                               bp++;
-                               pic14_emitcode(bp1,"");
-                               bp1 = bp;
-                       } else
-                               bp++;
-               }
-       }
-       if ((bp1 != bp) && *bp1)
-               addpCode2pBlock(pb,AssembleLine(bp1));
-       
-       Safe_free(buffer);
-       
-       _G.inLine -= (!options.asmpeep);
+  char *buffer, *bp, *bp1;
+
+  FENTRY;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  _G.inLine += (!options.asmpeep);
+
+  buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
+  strcpy(buffer,IC_INLINE(ic));
+
+  /* emit each line as a code */
+  while (*bp) {
+    if (*bp == '\n') {
+      *bp++ = '\0';
+      
+      if(*bp1)
+        addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+      bp1 = bp;
+    } else {
+      if (*bp == ':') {
+        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++;
+    }
+  }
+  if ((bp1 != bp) && *bp1)
+    addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+
+  Safe_free(buffer);
+
+  _G.inLine -= (!options.asmpeep);
 }
 
 /*-----------------------------------------------------------------*/
@@ -6048,6 +6370,7 @@ static void genRRC (iCode *ic)
        operand *left , *result ;
        int size, offset = 0, same;
        
+       FENTRY;
        /* rotate right with carry */
        left = IC_LEFT(ic);
        result=IC_RESULT(ic);
@@ -6090,6 +6413,7 @@ static void genRLC (iCode *ic)
        int size, offset = 0;
        int same;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* rotate right with carry */
        left = IC_LEFT(ic);
@@ -6137,6 +6461,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));
@@ -6156,81 +6481,141 @@ 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 :
+               return;
                break;
        case 1 :
-               pic14_emitcode("rl","a");
+               emitCLRC;
+               emitpcode(POC_RLF,pcop);
+               return;
                break;
        case 2 :
-               pic14_emitcode("rl","a");
-               pic14_emitcode("rl","a");
+               emitpcode(POC_RLF,pcop);
+               emitpcode(POC_RLF,pcop);
                break;
        case 3 :
-               pic14_emitcode("swap","a");
-               pic14_emitcode("rr","a");
+               emitpcode(POC_RLF,pcop);
+               emitpcode(POC_RLF,pcop);
+               emitpcode(POC_RLF,pcop);
                break;
        case 4 :
-               pic14_emitcode("swap","a");
+               emitpcode(POC_SWAPF,pcop);
                break;
        case 5 :
-               pic14_emitcode("swap","a");
-               pic14_emitcode("rl","a");
+               emitpcode(POC_SWAPF,pcop);
+               emitpcode(POC_RLF,pcop);
                break;
        case 6 :
-               pic14_emitcode("rr","a");
-               pic14_emitcode("rr","a");
+               emitpcode(POC_SWAPF,pcop);
+               emitpcode(POC_RLF,pcop);
+               emitpcode(POC_RLF,pcop);
                break;
        case 7 :
-               pic14_emitcode("rr","a");
+               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);
 }
 
 /*-----------------------------------------------------------------*/
-/* AccLsh - left shift accumulator by known count                  */
-/*-----------------------------------------------------------------*/
-static void AccLsh (int shCount)
-{
-       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");
-                       } else {
-                               /* rotate left accumulator */
-                               AccRol(shCount);
-                               /* and kill the lower order bits */
-                               pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
-                       }
-       }
-}
-
-/*-----------------------------------------------------------------*/
-/* AccRsh - right shift accumulator by known count                 */
+/* 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 (int shCount)
+static void AccRsh (pCodeOp *pcop,int shCount, int mask_mode)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       if(shCount != 0){
-               if(shCount == 1){
-                       CLRC;
-                       pic14_emitcode("rrc","a");
+       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 right accumulator */
-                       AccRol(8 - shCount);
-                       /* and kill the higher order bits */
-                       pic14_emitcode("anl","a,#0x%02x", SRMask[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);
        }
 }
 
@@ -6264,7 +6649,7 @@ static void AccSRsh (int shCount)
                }
        }
 }
-#endif
+
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
 /*-----------------------------------------------------------------*/
@@ -6274,6 +6659,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl,
 {
        int same;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
@@ -6385,6 +6771,7 @@ static void shiftR1Left2Result (operand *left, int offl,
 {
        int same;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
@@ -6478,6 +6865,7 @@ static void shiftL1Left2Result (operand *left, int offl,
        int same;
        
        //    char *l;
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
@@ -6541,35 +6929,225 @@ static void shiftL1Left2Result (operand *left, int offl,
        }
        
 }
+#endif
+
+/*-----------------------------------------------------------------*/
+/* movLeft2Result - move byte from left to result                  */
+/*-----------------------------------------------------------------*/
+static void movLeft2Result (operand *left, int offl,
+                                                       operand *result, int offr)
+{
+       char *l;
+       FENTRY;
+       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 {
+                       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
+                       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+               }
+       }
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftLeft_Left2ResultLit - shift left by known count            */
+/*-----------------------------------------------------------------*/
+
+static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
+{
+       int size, same, offr, i;
+
+       size = AOP_SIZE(left);
+       if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+       
+       same = pic14_sameRegs (AOP(left), AOP(result));
+       
+       offr = shCount / 8;
+       shCount = shCount & 0x07;
+
+       size -= offr;
+
+       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
+}
 
 /*-----------------------------------------------------------------*/
-/* movLeft2Result - move byte from left to result                  */
+/* shiftRight_Left2ResultLit - shift right by known count          */
 /*-----------------------------------------------------------------*/
-static void movLeft2Result (operand *left, int offl,
-                                                       operand *result, int offr)
+
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, 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);
+       int size, same, offr, i;
+
+       size = AOP_SIZE(left);
+       if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+       
+       same = pic14_sameRegs (AOP(left), AOP(result));
+       
+       offr = shCount / 8;
+       shCount = shCount & 0x07;
+
+       size -= offr;
+
+       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;
+                       
+               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;
+                       
+               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));
+
+                       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;
+                       
+               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;
                
-               if (*l == '@' && (IS_AOP_PREG(result))) {
-                       pic14_emitcode("mov","a,%s",l);
-                       aopPut(AOP(result),"a",offr);
-               } else {
-                       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
-                       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
-               }
-       }
+               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
+
+       addSign (result, size, sign);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* shiftL2Left2Result - shift left two bytes from left to result   */
 /*-----------------------------------------------------------------*/
 static void shiftL2Left2Result (operand *left, int offl,
                                                                operand *result, int offr, int shCount)
 {
-       
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
@@ -6690,6 +7268,7 @@ static void shiftL2Left2Result (operand *left, int offl,
        }
        
 }
+
 /*-----------------------------------------------------------------*/
 /* shiftR2Left2Result - shift right two bytes from left to result  */
 /*-----------------------------------------------------------------*/
@@ -6699,6 +7278,7 @@ static void shiftR2Left2Result (operand *left, int offl,
 {
        int same=0;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        same = pic14_sameRegs(AOP(result), AOP(left));
        
@@ -6727,7 +7307,7 @@ static void shiftR2Left2Result (operand *left, int offl,
        case 2:
        case 3:
                if(sign)
-                       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
+                       emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
                else
                        emitCLRC;
                
@@ -6841,21 +7421,20 @@ static void shiftR2Left2Result (operand *left, int offl,
   }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
 /*-----------------------------------------------------------------*/
 static void shiftLLeftOrResult (operand *left, int offl,
                                                                operand *result, int offr, int shCount)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+       
        /* shift left accumulator */
-       AccLsh(shCount);
+       AccLsh(left,offl,shCount);
        /* or with result */
-       pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-       /* back to result */
-       aopPut(AOP(result),"a",offr);
+       emitpcode (POC_IORWF, popGet (AOP(result), offr));
+       assert ( !"broken (modifies left, fails for left==result))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -6864,14 +7443,14 @@ static void shiftLLeftOrResult (operand *left, int offl,
 static void shiftRLeftOrResult (operand *left, int offl,
                                                                operand *result, int offr, int shCount)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+       
        /* shift right accumulator */
-       AccRsh(shCount);
+       AccRsh(left,offl,shCount);
        /* or with result */
-       pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-       /* back to result */
-       aopPut(AOP(result),"a",offr);
+       emitpcode (POC_IORWF, popGet (AOP(result), offr));
+       assert ( !"broken (modifies left, fails for left==result))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -6879,6 +7458,7 @@ static void shiftRLeftOrResult (operand *left, int offl,
 /*-----------------------------------------------------------------*/
 static void genlshOne (operand *result, operand *left, int shCount)
 {       
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        shiftL1Left2Result(left, LSB, result, LSB, shCount);
 }
@@ -6890,6 +7470,7 @@ static void genlshTwo (operand *result,operand *left, int shCount)
 {
        int size;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        size = pic14_getDataSize(result);
        
@@ -6924,6 +7505,7 @@ static void shiftLLong (operand *left, operand *result, int offr )
        char *l;
        int size = AOP_SIZE(result);
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(size >= LSB+offr){
                l = aopGet(AOP(left),LSB,FALSE,FALSE);
@@ -6933,7 +7515,7 @@ static void shiftLLong (operand *left, operand *result, int offr )
                        size >= MSB16+offr && offr != LSB )
                        pic14_emitcode("xch","a,%s",
                        aopGet(AOP(left),LSB+offr,FALSE,FALSE));
-               else        
+               else      
                        aopPut(AOP(result),"a",LSB+offr);
        }
        
@@ -6947,7 +7529,7 @@ static void shiftLLong (operand *left, operand *result, int offr )
                        size >= MSB24+offr && offr != LSB)
                        pic14_emitcode("xch","a,%s",
                        aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
-               else        
+               else      
                        aopPut(AOP(result),"a",MSB16+offr);
        }
        
@@ -6961,14 +7543,14 @@ static void shiftLLong (operand *left, operand *result, int offr )
                        size >= MSB32+offr && offr != LSB )
                        pic14_emitcode("xch","a,%s",
                        aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
-               else        
+               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);        
+                       MOVA(l);  
                }
                pic14_emitcode("rlc","a");
                aopPut(AOP(result),"a",MSB32+offr);
@@ -6984,6 +7566,7 @@ static void genlshFour (operand *result, operand *left, int shCount)
 {
        int size;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        size = AOP_SIZE(result);
        
@@ -7059,7 +7642,9 @@ static void genlshFour (operand *result, operand *left, int shCount)
                shiftL2Left2Result(left, LSB, result, LSB, shCount);
        }
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genLeftShiftLiteral - left shifting by known count              */
 /*-----------------------------------------------------------------*/
@@ -7069,14 +7654,15 @@ static void genLeftShiftLiteral (operand *left,
                                                                 iCode *ic)
 {    
        int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
-       int size;
+       //int size;
        
+       FENTRY;
        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
@@ -7113,6 +7699,7 @@ static void genLeftShiftLiteral (operand *left,
                freeAsmop(left,NULL,ic,TRUE);
                freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*
 * genMultiAsm - repeat assembly instruction for size of register.
@@ -7124,6 +7711,7 @@ static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
        
        int offset = 0;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if(!reg)
@@ -7142,6 +7730,8 @@ static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
        }
        
 }
+
+#if 0
 /*-----------------------------------------------------------------*/
 /* genLeftShift - generates code for left shifting                 */
 /*-----------------------------------------------------------------*/
@@ -7149,10 +7739,12 @@ static void genLeftShift (iCode *ic)
 {
        operand *left,*right, *result;
        int size, offset;
+       unsigned long lit = 0L;
        char *l;
        symbol *tlbl , *tlbl1;
        pCodeOp *pctemp;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        right = IC_RIGHT(ic);
@@ -7160,11 +7752,14 @@ static void genLeftShift (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 
        as efficiently as possible */
        if (AOP_TYPE(right) == AOP_LIT) {
-               genLeftShiftLiteral (left,right,result,ic);
+               shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit));
                return ;
        }
        
@@ -7174,9 +7769,8 @@ static void genLeftShift (iCode *ic)
        more that 32 bits make no sense anyway, ( the
        largest size of an object can be only 32 bits ) */  
        
-       
-       aopOp(left,ic,FALSE);
-       aopOp(result,ic,FALSE);
+       /* this code fails for RIGHT == RESULT */
+       assert (!pic14_sameRegs (AOP(right), AOP(result)));
        
        /* now move the left to the result if they are not the
        same */
@@ -7200,11 +7794,14 @@ static void genLeftShift (iCode *ic)
                }
        }
        
+       if(AOP_TYPE(left) == AOP_LIT)
+               lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
+
        size = AOP_SIZE(result);
        
        /* if it is only one byte then */
        if (size == 1) {
-               if(optimized_for_speed) {
+               if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
                        emitpcode(POC_SWAPFW, popGet(AOP(left),0));
                        emitpcode(POC_ANDLW,  popGetLit(0xf0));
                        emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
@@ -7221,7 +7818,7 @@ static void genLeftShift (iCode *ic)
                        
                        tlbl = newiTempLabel(NULL);
                        if (!pic14_sameRegs(AOP(left),AOP(result))) {
-                               emitpcode(POC_MOVFW,  popGet(AOP(left),0));
+                               mov2w (AOP(left), 0);
                                emitpcode(POC_MOVWF,  popGet(AOP(result),0));
                        }
                        
@@ -7310,13 +7907,16 @@ release:
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genrshOne - right shift a one byte quantity by known count      */
 /*-----------------------------------------------------------------*/
 static void genrshOne (operand *result, operand *left,
                                           int shCount, int sign)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
 }
@@ -7327,6 +7927,7 @@ static void genrshOne (operand *result, operand *left,
 static void genrshTwo (operand *result,operand *left,
                                           int shCount, int sign)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* if shCount >= 8 */
        if (shCount >= 8) {
@@ -7357,31 +7958,35 @@ static void genrshTwo (operand *result,operand *left,
 static void shiftRLong (operand *left, int offl,
                                                operand *result, int sign)
 {
-       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);
+       int size, same;
        
-       MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB24-offl);
+       FENTRY;
+       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
-       MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB16-offl);
+       size = AOP_SIZE(left);
+       if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
        
-       if(offl == LSB){
-               MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
-               pic14_emitcode("rrc","a");
-               aopPut(AOP(result),"a",LSB);
-       }
+       if (sign)
+               emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1));
+       else
+               emitCLRC;
+
+       assert (offl >= 0 && offl < size);
+
+       same = pic14_sameRegs (AOP(left), AOP(result));
+
+       /* perform the shift */
+       while (size--)
+       {
+               if (same && !offl) {
+                       emitpcode (POC_RRF, popGet (AOP(result), size));
+               } else {
+                       emitpcode (POC_RRFW, popGet (AOP(left), size));
+                       emitpcode (POC_MOVWF, popGet (AOP(result), size-offl));
+               }
+       } // while
+
+       addSign (result, AOP_SIZE(left) - offl, sign);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7390,6 +7995,7 @@ static void shiftRLong (operand *left, int offl,
 static void genrshFour (operand *result, operand *left,
                                                int shCount, int sign)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* if shifting more that 3 bytes */
        if(shCount >= 24 ) {
@@ -7455,6 +8061,7 @@ static void genRightShiftLiteral (operand *left,
        int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
        int lsize,res_size;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        freeAsmop(right,NULL,ic,TRUE);
        
@@ -7473,7 +8080,7 @@ static void genRightShiftLiteral (operand *left,
        /* I suppose that the left size >= result size */
        if(shCount == 0){
                while(res_size--)
-                       movLeft2Result(left, lsize, result, res_size);
+                       movLeft2Result(left, res_size, result, res_size);
        }
        
        else if(shCount >= (lsize * 8)){
@@ -7518,11 +8125,13 @@ static void genRightShiftLiteral (operand *left,
                }
                
        }
-       
+
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genSignedRightShift - right shift of signed number              */
 /*-----------------------------------------------------------------*/
@@ -7538,6 +8147,7 @@ static void genSignedRightShift (iCode *ic)
        
        /* we do it the hard way put the shift count in b
        and loop thru preserving the sign */
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        right = IC_RIGHT(ic);
@@ -7550,7 +8160,8 @@ static void genSignedRightShift (iCode *ic)
        
        
        if ( AOP_TYPE(right) == AOP_LIT) {
-               genRightShiftLiteral (left,right,result,ic,1);
+               shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1);
+               //genRightShiftLiteral (left,right,result,ic,1);
                return ;
        }
        /* shift count is unknown then we have to form 
@@ -7573,14 +8184,13 @@ static void genSignedRightShift (iCode *ic)
                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);
+                       /*
+                       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);
                        */
                        emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
                        emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
@@ -7663,28 +8273,38 @@ release:
        freeAsmop(result,NULL,ic,TRUE);
        freeAsmop(right,NULL,ic,TRUE);
 }
+#endif
+
+/*-----------------------------------------------------------------*/
+/* loadSignToC - load the operand's sign bit into CARRY            */
+/*-----------------------------------------------------------------*/
+
+static void loadSignToC (operand *op)
+{
+       FENTRY;
+       assert (op && AOP(op) && AOP_SIZE(op));
+
+       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
@@ -7697,11 +8317,24 @@ 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 
        as efficiently as possible */
        if (AOP_TYPE(right) == AOP_LIT) {
-               genRightShiftLiteral (left,right,result,ic, 0);
+               int lit = (int)floatFromVal (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 ;
        }
        
@@ -7710,194 +8343,324 @@ static void genRightShift (iCode *ic)
        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");
-       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) {
+
+       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));
+
+       if (!SPEC_USIGN(operandType(right)))
+       {
+               symbol *inv_loop = newiTempLabel(NULL);
+
+               shiftRight = !shiftRight;       /* invert shift direction */
                
-               tlbl = newiTempLabel(NULL);
-               if (!pic14_sameRegs(AOP(left),AOP(result))) {
-                       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
-                       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
-               }
+               /* we came here from the code above -- we are done */
+               emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
                
-               emitpcode(POC_COMFW,  popGet(AOP(right),0));
-               emitpcode(POC_RLF,    popGet(AOP(result),0));
-               emitpLabel(tlbl->key);
-               emitpcode(POC_RRF,    popGet(AOP(result),0));
-               emitpcode(POC_ADDLW,  popGetLit(1));
+               /* 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(tlbl->key));
-               
-               goto release ;
-       }
-       
-       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));
+               emitpcode(POC_GOTO, popGetLabel(inv_loop->key));
+       } // if
        
-       pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
-       pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
+       emitpLabel(tlbl1->key);
        
-release:
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop (right,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
 
+static void genRightShift (iCode *ic)
+{
+       genGenericShift(ic, 1);
+}
+
+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 ;
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       etype = getSpec(operandType(result));
-       
-       /* read the first byte  */
-       switch (ptype) {
-               
-       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;
-               
-       case CPOINTER:
-               pic14_emitcode("clr","a");
-               pic14_emitcode("movc","a","@a+dptr");
-               break;
-               
-       case GPOINTER:
-               pic14_emitcode("lcall","__gptrget");
-               break;
-       }
-       
-       /* if we have bitdisplacement then it fits   */
-       /* into this byte completely or if length is */
-       /* less than a byte                          */
-       if ((shCnt = SPEC_BSTR(etype)) || 
-               (SPEC_BLEN(etype) <= 8))  {
-               
-               /* shift right acc */
-               AccRsh(shCnt);
-               
-               pic14_emitcode("anl","a,#0x%02x",
-                       ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
-               aopPut(AOP(result),"a",offset);
-               return ;
-       }
-       
-       /* 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;
+void SetIrp(operand *result) {
+       FENTRY;
+       if (AOP_TYPE(result) == AOP_LIT) {
+               unsigned lit = (unsigned)operandLitValue(result);
+               if (lit&0x100)
+                       emitSETIRP;
+               else
+                       emitCLRIRP;
+       } else {
+               if (PCOP(AOP(result))->type == PO_LITERAL) {
+                       int addrs = PCOL(AOP(result))->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;
+                       }
                }
-               
-               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 ;
 }
 
-#if 0
+static void
+setup_fsr (operand *ptr)
+{
+  mov2w_op(ptr, 0);
+  emitpcode(POC_MOVWF, popCopyReg (&pc_fsr));
+
+  /* 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 FPOINTER:
+      if (!alreadyAddressed) setup_fsr (src);
+      emitpcode(POC_MOVFW, popCopyReg (&pc_fsr));
+      break;
+    
+    case CPOINTER:
+      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:
+      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;
+    
+    case CPOINTER:
+      assert( !"trying to assign to __code pointer" );
+      break;
+    
+    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;
+
+    default:
+      assert( !"unhandled pointer type" );
+      break;
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* genUnpackBits - generates code for unpacking bits               */
+/*-----------------------------------------------------------------*/
+static void genUnpackBits (operand *result, operand *left, int ptype, iCode *ifx)
+{    
+  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));
+
+    switch (ptype)
+    {
+    case -1:
+      mov2w(AOP(left), 0);
+      break;
+      
+    case POINTER:
+    case FPOINTER:
+    case GPOINTER:
+    case CPOINTER:
+      emitPtrByteGet (left, ptype, FALSE);
+      break;
+      
+    default:
+      assert( !"unhandled pointer type" );
+    } // switch
+
+    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 */
+
+    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;
+  }
+
+  assert( !"bitfields larger than 8 bits or crossing byte boundaries are not yet supported" );
+}
+
+#if 1
 /*-----------------------------------------------------------------*/
 /* genDataPointerGet - generates code when ptr offset is known     */
 /*-----------------------------------------------------------------*/
 static void genDataPointerGet (operand *left, 
-                                                          operand *result, 
-                                                          iCode *ic)
+       operand *result, 
+       iCode *ic)
 {
        int size , offset = 0;
-       
-       
+               
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        
@@ -7905,16 +8668,21 @@ static void genDataPointerGet (operand *left,
        * address, but different types. for the pic code, we could omit
        * the following
        */
-       
        aopOp(result,ic,TRUE);
        
+       if (pic14_sameRegs (AOP(left), AOP(result)))
+               return;
+       
        DEBUGpic14_AopType(__LINE__,left,NULL,result);
        
-       emitpcode(POC_MOVFW, popGet(AOP(left),0));
+       //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++;
        }
@@ -7923,24 +8691,23 @@ static void genDataPointerGet (operand *left,
        freeAsmop(result,NULL,ic,TRUE);
 }
 #endif
+
 /*-----------------------------------------------------------------*/
-/* genNearPointerGet - pic14_emitcode for near pointer fetch             */
+/* genNearPointerGet - pic14_emitcode for near pointer fetch       */
 /*-----------------------------------------------------------------*/
 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);    
-       //char buffer[80];
-       
+       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);
        
@@ -7950,65 +8717,55 @@ static void genNearPointerGet (operand *left,
        lower 128 bytes of space */
        if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
                !IS_BITVAR(retype)         &&
-               DCL_TYPE(ltype) == POINTER) {
-               //genDataPointerGet (left,result,ic);
+               PIC_IS_DATA_PTR(ltype)) {
+               genDataPointerGet (left,result,ic);
                return ;
        }
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       aopOp (result,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 */
-               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 ;
-               */
-               rname ="BAD";
-       } else
-               rname = aopGet(AOP(left),0,FALSE,FALSE);
+       /* Check if can access directly instead of via a pointer */
+       if ((PCOP(AOP(left))->type == PO_LITERAL || PCOP(AOP(left))->type == PO_IMMEDIATE)
+               && AOP_SIZE(result) == 1)
+       {
+               direct = 1;
+       }
+
+       if (IS_BITFIELD(getSpec(operandType(result)))) 
+       {
+               genUnpackBits (result,left,direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
+               goto release;
+       }
        
-       aopOp (result,ic,FALSE);
+       /* 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);
        
+//     sym_link *etype;
        /* 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 ;        
+               int offset = 0 ;  
                
                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
                
-               emitpcode(POC_MOVFW,popGet(AOP(left),0));
-               emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
                while(size--) {
-                       emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
-                       emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
-                       if(size)
-                               emitpcode(POC_INCF,popCopyReg(&pc_fsr));
-               }
-               /*
-               while (size--) {
-               if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
-
-                       pic14_emitcode("mov","a,@%s",rname);
-                       aopPut(AOP(result),"a",offset);
+                       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 {
-                       sprintf(buffer,"@%s",rname);
-                       aopPut(AOP(result),buffer,offset);
+                               emitpcode(POC_MOVWF,popGet(AOP(result),offset));
                        }
-                       offset++ ;
-                       if (size)
-                       pic14_emitcode("inc","%s",rname);
+                       if (size && !direct)
+                               emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+                       offset++;
                }
-               */
        }
        
        /* now some housekeeping stuff */
@@ -8017,10 +8774,10 @@ static void genNearPointerGet (operand *left,
                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 
+               /* 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 &&
@@ -8029,16 +8786,18 @@ static void genNearPointerGet (operand *left,
                        ic->depth )) {
                        int size = AOP_SIZE(result) - 1;
                        while (size--)
-                               pic14_emitcode("dec","%s",rname);
+                               emitpcode(POC_DECF, popCopyReg(&pc_fsr));
                }
        }
        
+release:
        /* done */
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
-       
+
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
 /*-----------------------------------------------------------------*/
@@ -8051,6 +8810,7 @@ static void genPagedPointerGet (operand *left,
        char *rname ;
        sym_link *rtype, *retype;    
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        rtype = operandType(result);
@@ -8075,12 +8835,12 @@ static void genPagedPointerGet (operand *left,
        aopOp (result,ic,FALSE);
        
        /* if bitfield then unpack the bits */
-       if (IS_BITVAR(retype)) 
-               genUnpackBits (result,rname,PPOINTER);
+       if (IS_BITFIELD(retype)) 
+               genUnpackBits (result,left,rname,PPOINTER,0);
        else {
                /* we have can just get the values */
                int size = AOP_SIZE(result);
-               int offset = 0 ;        
+               int offset = 0 ;  
                
                while (size--) {
                        
@@ -8100,9 +8860,9 @@ static void genPagedPointerGet (operand *left,
                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 
+       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 &&
@@ -8129,6 +8889,7 @@ static void genFarPointerGet (operand *left,
        int size, offset ;
        sym_link *retype = getSpec(operandType(result));
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        aopOp(left,ic,FALSE);
@@ -8153,8 +8914,8 @@ static void genFarPointerGet (operand *left,
        aopOp(result,ic,FALSE);
        
        /* if bit then unpack */
-       if (IS_BITVAR(retype)) 
-               genUnpackBits(result,"dptr",FPOINTER);
+       if (IS_BITFIELD(retype)) 
+               genUnpackBits(result,left,"dptr",FPOINTER,0);
        else {
                size = AOP_SIZE(result);
                offset = 0 ;
@@ -8169,6 +8930,8 @@ static void genFarPointerGet (operand *left,
        
        freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* genCodePointerGet - get value from code space                  */
@@ -8203,8 +8966,8 @@ static void genCodePointerGet (operand *left,
        aopOp(result,ic,FALSE);
        
        /* if bit then unpack */
-       if (IS_BITVAR(retype)) 
-               genUnpackBits(result,"dptr",CPOINTER);
+       if (IS_BITFIELD(retype)) 
+               genUnpackBits(result,left,"dptr",CPOINTER,0);
        else {
                size = AOP_SIZE(result);
                offset = 0 ;
@@ -8227,48 +8990,45 @@ static void genCodePointerGet (operand *left,
 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);
        aopOp(result,ic,FALSE);
        
        
        DEBUGpic14_AopType(__LINE__,left,NULL,result);
-       
-       /* 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));
+
+       if (IS_BITFIELD(getSpec(operandType(result))))
+       {
+         genUnpackBits (result, left, GPOINTER, ifxForOp (IC_RESULT(ic), ic));
+         return;
        }
-       else { /* we need to get it byte by byte */
-               
-               emitpcode(POC_MOVFW,popGet(AOP(left),0));
-               emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
-               
-               size = AOP_SIZE(result);
-               offset = 0 ;
-               
-               while(size--) {
-                       emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
-                       emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
-                       if(size)
-                               emitpcode(POC_INCF,popCopyReg(&pc_fsr));
-               }
-               goto release;
+
+       {
+         /* 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
        }
-       //}
-       /* so dptr know contains the address */
        
-       /* if bit then unpack */
-       //if (IS_BITVAR(retype)) 
-       //  genUnpackBits(result,"dptr",GPOINTER);
-       
-release:
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
        
@@ -8281,38 +9041,54 @@ static void genConstPointerGet (operand *left,
                                                                operand *result, iCode *ic)
 {
        //sym_link *retype = getSpec(operandType(result));
-       symbol *albl = newiTempLabel(NULL);
-       symbol *blbl = newiTempLabel(NULL);
-       PIC_OPCODE poc;
+       #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);
        
+       size = AOP_SIZE(result);
        
        DEBUGpic14_AopType(__LINE__,left,NULL,result);
        
        DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
+
+       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
+       }
        
-       emitpcode(POC_CALL,popGetLabel(albl->key));
-       pcop = popGetLabel(blbl->key);
-       emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
-       emitpcode(POC_GOTO,pcop);
-       emitpLabel(albl->key);
-       
-       poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
-       
-       emitpcode(poc,popGet(AOP(left),1));
-       emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
-       emitpcode(poc,popGet(AOP(left),0));
-       emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
-       
-       emitpLabel(blbl->key);
-       
-       emitpcode(POC_MOVWF,popGet(AOP(result),0));
-       
-       
+release:
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
        
@@ -8324,8 +9100,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);
@@ -8350,7 +9127,7 @@ static void genPointerGet (iCode *ic)
                
                if (SPEC_OCLS(etype)->codesp ) {
                        DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
-                       //p_type = CPOINTER ;   
+                       //p_type = CPOINTER ; 
                }
                else
                        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
@@ -8359,25 +9136,26 @@ static void genPointerGet (iCode *ic)
                        else
                                if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
                                        DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
-                               /*                  p_type = PPOINTER; */
+                               /*        p_type = PPOINTER; */
                                else
                                        if (SPEC_OCLS(etype) == idata )
                                                DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
-                                       /*                      p_type = IPOINTER; */
+                                       /*      p_type = IPOINTER; */
                                        else
                                                DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
-                                       /*                      p_type = POINTER ; */
+                                       /*      p_type = POINTER ; */
        }
        
        /* now that we have the pointer type we assign
        the pointer values */
        switch (p_type) {
                
-       case POINTER:   
-       case IPOINTER:
+       case POINTER: 
+       case FPOINTER:
+       //case IPOINTER:
                genNearPointerGet (left,result,ic);
                break;
-               
+/*
        case PPOINTER:
                genPagedPointerGet(left,result,ic);
                break;
@@ -8385,18 +9163,17 @@ static void genPointerGet (iCode *ic)
        case FPOINTER:
                genFarPointerGet (left,result,ic);
                break;
-               
+*/             
        case CPOINTER:
                genConstPointerGet (left,result,ic);
-               //pic14_emitcodePointerGet (left,result,ic);
                break;
                
        case GPOINTER:
-               if (IS_PTR_CONST(type))
-                       genConstPointerGet (left,result,ic);
-               else
-                       genGenPointerGet (left,result,ic);
+               genGenPointerGet (left,result,ic);
                break;
+       default:
+               assert ( !"unhandled pointer type" );
+               break;
        }
        
 }
@@ -8404,175 +9181,245 @@ 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 ;
+  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 */
+
+  FENTRY;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
+
+  /* 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)));
+
+    if (AOP_TYPE (right) == AOP_LIT)
+    {
+      /* Case with a bitfield length <8 and literal source */
+      int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+      if (blen == 1) {
+        pCodeOp *pcop;
        
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       blen = SPEC_BLEN(etype);
-       bstr = SPEC_BSTR(etype);
+       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;
        
-       l = aopGet(AOP(right),offset++,FALSE,FALSE);
-       MOVA(l);   
+       case POINTER:
+       case FPOINTER:
+         setup_fsr (result);
+         emitpcode(lit?POC_BSF:POC_BCF,newpCodeOpBit(PCOP(&pc_indf)->name,bstr,0));
+         break;
        
-       /* 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 */
-                       
-                       
-                       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;
-                       }
-                       
-                       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");
-               }
-       }
+       case CPOINTER:
+         assert( !"trying to assign to bitfield via pointer to __code space" );
+         break;
+       
+       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;
+       
+       default:
+         assert( !"unhandled pointer type" );
+         break;
+       } // switch (p_type)
+      } else {
+        /* blen > 1 */
+       litval = lit << bstr;
+       litval &= (~mask) & 0x00ff;
+       
+       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:
-               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);
+         if ((litval|mask) != 0x00ff)
+           emitpcode(POC_ANDLW, popGetLit (mask));
+         if (litval != 0x00)
+           emitpcode(POC_IORLW, popGetLit (litval));
+         emitPtrByteSet(result, p_type, TRUE);
+         break;
        
-       /* if we r done */
-       if ( SPEC_BLEN(etype) <= 8 )
-               return ;
+       case CPOINTER:
+         assert( !"trying to assign to bitfield via pointer to __code space" );
+         break;
        
-       pic14_emitcode("inc","%s",rname);
-       rLen = SPEC_BLEN(etype) ;     
+       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;
        
-       /* now generate for lengths greater than one byte */
-       while (1) {
-               
-               l = aopGet(AOP(right),offset++,FALSE,TRUE);
-               
-               rLen -= 8 ;
-               if (rLen <= 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 FPOINTER:
-                       MOVA(l);
-                       pic14_emitcode("movx","@dptr,a");
-                       break;
-                       
-               case GPOINTER:
-                       MOVA(l);
-                       DEBUGpic14_emitcode(";lcall","__gptrput");
-                       break;  
-               }   
-               pic14_emitcode ("inc","%s",rname);
-       }
+       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;
        
-       MOVA(l);
+       case CPOINTER:
+         assert( !"trying to assign to bitfield via pointer to __code space" );
+         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;
-               }
-               
-               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 ();
+
+       mov2w (AOP(right), 0);
+       if (blen < 8) {
+         emitpcode (POC_ANDLW, popGetLit ((1UL << blen)-1));
+       }
+       emitpcode(POC_MOVWF, temp);
+       if (bstr) {
+         AccLsh (temp, bstr);
        }
        
-       if (p_type == GPOINTER)
-               pic14_emitcode("pop","b");
+       switch (p_type)
+       {
+       case -1:
+         mov2w (AOP(result), 0);
+         emitpcode(POC_ANDLW, popGetLit (mask));
+         emitpcode(POC_IORFW, temp);
+         movwf (AOP(result), 0);
+         break;
        
-       switch (p_type) {
-               
        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" );
+}
+
+unsigned long
+bitpatternFromVal (value *val)
+{
+  union {
+    float d;
+    uint32_t l;
+  } float_long;
+
+  assert (sizeof (float) == sizeof (uint32_t));
+
+  //fprintf (stderr, "%s:%u(%s): val=%lf, type: %d, etype: %d\n", __FILE__, __LINE__, __FUNCTION__, floatFromVal(val), SPEC_NOUN(val->type), SPEC_NOUN(val->etype));
+
+  switch (SPEC_NOUN(val->type))
+  {
+  case V_INT:
+  case V_CHAR:
+    return (unsigned long)floatFromVal (val);
+    
+  case V_FLOAT:
+  case V_DOUBLE:
+    float_long.d = floatFromVal (val);
+    return float_long.l;
+    
+  default:
+    assert( !"unhandled value type" );
+    break;
+  }
+
+  float_long.d = floatFromVal (val);
+  return float_long.l;
 }
+
 /*-----------------------------------------------------------------*/
 /* 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);
+       aopOp(result,ic,FALSE);
+       
+       assert (IS_SYMOP(result));
+       assert (IS_PTR(OP_SYM_TYPE(result)));
        
-       l = aopGet(AOP(result),0,FALSE,TRUE);
        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);
+       
+       //assert( !"what's going on here?" );
+
        /*
        if ( AOP_TYPE(result) == AOP_PCODE) {
        fprintf(stderr,"genDataPointerSet   %s, %d\n",
@@ -8583,36 +9430,23 @@ static void genDataPointerSet(operand *right,
        
        // tsd, was l+1 - the underline `_' prefix was being stripped
        while (size--) {
-               if (offset) {
-                       sprintf(buffer,"(%s + %d)",l,offset);
-                       fprintf(stderr,"oops  %s\n",buffer);
-               } else
-                       sprintf(buffer,"%s",l);
+               emitpComment ("%s:%u: size=%d/%d, offset=%i", __FILE__,__LINE__, size, ressize, offset);
                
                if (AOP_TYPE(right) == AOP_LIT) {
-                       unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
+                       /* XXX: might be float... */
+                       unsigned int lit = bitpatternFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
                        lit = lit >> (8*offset);
+                       //fprintf (stderr, "%s:%u: lit %d 0x%x\n", __FUNCTION__,__LINE__, lit, lit);
                        if(lit&0xff) {
-                               pic14_emitcode("movlw","%d",lit);
-                               pic14_emitcode("movwf","%s",buffer);
-                               
                                emitpcode(POC_MOVLW, popGetLit(lit&0xff));
-                               //emitpcode(POC_MOVWF, popRegFromString(buffer));
-                               emitpcode(POC_MOVWF, popGet(AOP(result),0));
-                               
+                               emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                        } else {
-                               pic14_emitcode("clrf","%s",buffer);
-                               //emitpcode(POC_CLRF, popRegFromString(buffer));
-                               emitpcode(POC_CLRF, popGet(AOP(result),0));
+                               emitpcode(POC_CLRF, popGet(AOP(result),offset));
                        }
-               }else {
-                       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-                       pic14_emitcode("movwf","%s",buffer);
-                       
+               } else {
+                       //fprintf (stderr, "%s:%u: no lit\n", __FUNCTION__,__LINE__);
                        emitpcode(POC_MOVFW, popGet(AOP(right),offset));
-                       //emitpcode(POC_MOVWF, popRegFromString(buffer));
-                       emitpcode(POC_MOVWF, popGet(AOP(result),0));
-                       
+                       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                }
                
                offset++;
@@ -8623,98 +9457,81 @@ 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, 
                                                           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;
        
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       retype= getSpec(operandType(right));
-       
        aopOp(result,ic,FALSE);
        
-       
+#if 1
        /* if the result is rematerializable &
        in data space & not a bit variable */
        //if (AOP_TYPE(result) == AOP_IMMD &&
-       if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
-               DCL_TYPE(ptype) == POINTER   &&
-               !IS_BITVAR(retype)) {
+       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");
-               emitpcode(POC_MOVFW, popGet(AOP(result),0));
-               emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
-               emitpcode(POC_MOVFW, popGet(AOP(right),0));
-               emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
-               goto release;
-               
-       }// else
-       //   rname = aopGet(AOP(result),0,FALSE,FALSE);
-       
+       /* Check if can access directly instead of via a pointer */
+       if (PCOP(AOP(result))->type == PO_LITERAL && 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 ;    
                
                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");
+                                       emitpcode(POC_MOVLW,popGet(AOP(right),offset));
+                               } else {
+                                       emitpcode(POC_MOVFW,popGet(AOP(right),offset));
                                }
-                               //pic14_emitcode("mov","@%s,%s",rname,l);
+                               if (direct)
+                                       emitpcode(POC_MOVWF,popGet(AOP(result),0));
+                               else
+                                       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
                        }
-                       if (size)
-                               pic14_emitcode("incf","fsr,f ;3");
-                       //pic14_emitcode("inc","%s",rname);
+                       if (size && !direct)
+                               emitpcode(POC_INCF,popCopyReg(&pc_fsr));
                        offset++;
                }
        }
@@ -8725,10 +9542,10 @@ static void genNearPointerSet (operand *right,
                /* 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 
+               /* 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(right) > 1 &&
@@ -8737,18 +9554,18 @@ static void genNearPointerSet (operand *right,
                        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 */
-release:
+
        freeAsmop(right,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
 /*-----------------------------------------------------------------*/
@@ -8761,6 +9578,7 @@ static void genPagedPointerSet (operand *right,
        char *rname , *l;
        sym_link *retype;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        retype= getSpec(operandType(right));
@@ -8784,12 +9602,12 @@ static void genPagedPointerSet (operand *right,
        aopOp (right,ic,FALSE);
        
        /* if bitfield then unpack the bits */
-       if (IS_BITVAR(retype)) 
-               genPackBits (retype,right,rname,PPOINTER);
+       if (IS_BITFIELD(retype)) 
+               genPackBits (retype,result,right,rname,PPOINTER);
        else {
                /* we have can just get the values */
                int size = AOP_SIZE(right);
-               int offset = 0 ;        
+               int offset = 0 ;  
                
                while (size--) {
                        l = aopGet(AOP(right),offset,FALSE,TRUE);
@@ -8810,9 +9628,9 @@ static void genPagedPointerSet (operand *right,
                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 
+       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 &&
@@ -8839,6 +9657,7 @@ static void genFarPointerSet (operand *right,
        int size, offset ;
        sym_link *retype = getSpec(operandType(right));
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        aopOp(result,ic,FALSE);
        
@@ -8862,8 +9681,8 @@ static void genFarPointerSet (operand *right,
        aopOp(right,ic,FALSE);
        
        /* if bit then unpack */
-       if (IS_BITVAR(retype)) 
-               genPackBits(retype,right,"dptr",FPOINTER);
+       if (IS_BITFIELD(retype)) 
+               genPackBits(retype,result,right,"dptr",FPOINTER);
        else {
                size = AOP_SIZE(right);
                offset = 0 ;
@@ -8879,110 +9698,60 @@ static void genFarPointerSet (operand *right,
        
        freeAsmop(right,NULL,ic,TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* 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(result,ic,FALSE);
        aopOp(right,ic,FALSE);
-       size = AOP_SIZE(right);
-       
-       DEBUGpic14_AopType(__LINE__,NULL,right,result);
+       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);
-                       size = AOP_SIZE(right);
-                       offset = 0 ;
-                       
-                       /* hack hack! see if this the FSR. If so don't load W */
-                       if(AOP_TYPE(right) != AOP_ACC) {
-                               
-                               
-                               emitpcode(POC_MOVFW,popGet(AOP(result),0));
-                               emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
-                               
-                               if(AOP_SIZE(result) > 1) {
-                                       emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
-                                       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
-                                       emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
-                                       
-                               }
-                               
-                               //if(size==2)
-                               //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
-                               //if(size==4) {
-                               //  emitpcode(POC_MOVLW,popGetLit(0xfd));
-                               //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
-                               //}
-                               
-                               while(size--) {
-                                       emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
-                                       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
-                                       
-                                       if(size)
-                                               emitpcode(POC_INCF,popCopyReg(&pc_fsr));
-                               }
-                               
-                               
-                               goto release;
-                       } 
-                       
-                       if(aopIdx(AOP(result),0) != 4) {
-                               
-                               emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
-                               goto release;
-                       }
-                       
-                       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
-                       goto release;
-                       
-               }
+       DEBUGpic14_AopType(__LINE__,right,NULL,result);
+
+       if (IS_BITFIELD(retype))
+       {
+         genPackBits (retype, result, right, GPOINTER);
+         return;
        }
-       /* so dptr know contains the address */
-       
-       
-       /* if bit then unpack */
-       if (IS_BITVAR(retype)) 
-               genPackBits(retype,right,"dptr",GPOINTER);
-       else {
-               size = AOP_SIZE(right);
-               offset = 0 ;
-               
-               DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
-               
-               while (size--) {
-                       
-                       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
-                       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
-                       
-                       if (AOP_TYPE(right) == AOP_LIT) 
-                               emitpcode(POC_MOVLW, popGet(AOP(right),offset));
-                       else
-                               emitpcode(POC_MOVFW, popGet(AOP(right),offset));
-                       
-                       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
-                       
-                       offset++;
-               }
+
+       {
+         /* emit call to __gptrput */
+         char *func[] = {NULL, "__gptrput1", "__gptrput2", "__gptrput3", "__gptrput4"};
+         int size = AOP_SIZE(right);
+         int idx = 0;
+
+         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]);
        }
        
-release:
        freeAsmop(right,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
@@ -8996,6 +9765,7 @@ static void genPointerSet (iCode *ic)
        sym_link *type, *etype;
        int p_type;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        right = IC_RIGHT(ic);
@@ -9013,20 +9783,20 @@ static void genPointerSet (iCode *ic)
                /* 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 ; */
+               /*  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
@@ -9034,10 +9804,11 @@ static void genPointerSet (iCode *ic)
        switch (p_type) {
                
        case POINTER:
-       case IPOINTER:
+       case FPOINTER:
+       //case IPOINTER:
                genNearPointerSet (right,result,ic);
                break;
-               
+/*
        case PPOINTER:
                genPagedPointerSet (right,result,ic);
                break;
@@ -9045,7 +9816,7 @@ static void genPointerSet (iCode *ic)
        case FPOINTER:
                genFarPointerSet (right,result,ic);
                break;
-               
+*/
        case GPOINTER:
                genGenPointerSet (right,result,ic);
                break;
@@ -9064,6 +9835,7 @@ 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);
@@ -9073,27 +9845,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))
-                       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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -9104,6 +9903,7 @@ static void genAddrOf (iCode *ic)
        operand *right, *result, *left;
        int size, offset ;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        
@@ -9114,8 +9914,33 @@ static void genAddrOf (iCode *ic)
        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_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_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);
+       }
        
        size = AOP_SIZE(IC_RESULT(ic));
+       if (IS_GENPTR(OP_SYM_TYPE(result))) {
+               /* strip tag */
+               if (size > GPTRSIZE-1) size = GPTRSIZE-1;
+       }
        offset = 0;
        
        while (size--) {
@@ -9129,6 +9954,14 @@ static void genAddrOf (iCode *ic)
 #endif
                offset++;
        }
+
+       if (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(left,NULL,ic,FALSE);
        freeAsmop(result,NULL,ic,TRUE);
@@ -9176,6 +10009,7 @@ static void genAssign (iCode *ic)
        result = IC_RESULT(ic);
        right  = IC_RIGHT(ic) ;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        /* if they are the same */
@@ -9190,7 +10024,27 @@ static void genAssign (iCode *ic)
        /* 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) {
                
@@ -9278,7 +10132,7 @@ static void genAssign (iCode *ic)
                                emitpcode(POC_INCF, popGet(AOP(result),0));
                        }
                } else {
-                       mov2w (AOP(right), offset);
+                       mov2w_op (right, offset);
                        emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                }
                
@@ -9299,6 +10153,7 @@ static void genJumpTab (iCode *ic)
        symbol *jtab;
        char *l;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        aopOp(IC_JTCOND(ic),ic,FALSE);
@@ -9348,6 +10203,7 @@ iCode tree, I'm going to not be using this routine :(.
 */
 static int genMixedOperation (iCode *ic)
 {
+       FENTRY;
 #if 0
        operand *result = IC_RESULT(ic);
        sym_link *ctype = operandType(IC_LEFT(ic));
@@ -9472,11 +10328,12 @@ release:
 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)))
@@ -9489,49 +10346,7 @@ static void genCast (iCode *ic)
        
        /* 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 */
-               DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
-               if (AOP_TYPE(right) == AOP_LIT) {
-                       
-                       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);
-                       
-                       goto release;
-               }
-               
-               /* the right is also a bit variable */
-               if (AOP_TYPE(right) == AOP_CRY) {
-                       
-                       emitCLRC;
-                       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
-                       
-                       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 ;
-               }
-               
-               /* we need to or */
-               if (AOP_TYPE(right) == AOP_REG) {
-                       emitpcode(POC_BCF,    popGet(AOP(result),0));
-                       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
-                       emitpcode(POC_BSF,    popGet(AOP(result),0));
-               }
-               pic14_toBoolean(right);
-               aopPut(AOP(result),"a",0);
-               goto release ;
+               assert(!"assigning to bit variables is not supported");
        }
        
        if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
@@ -9550,6 +10365,82 @@ static void genCast (iCode *ic)
                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;
+           }
+
+           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 */
        if (AOP_SIZE(result) <= AOP_SIZE(right)) {
                
@@ -9564,9 +10455,9 @@ static void genCast (iCode *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, popGet(AOP(right),0));
+                       emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
                        emitpcode(POC_MOVWF, popGet(AOP(result),0));
-                       emitpcode(POC_MOVLW, popGet(AOP(right),1));
+                       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__);
@@ -9590,112 +10481,15 @@ static void genCast (iCode *ic)
                goto release;
        }
        
-       
-       /* if the result is of type pointer */
-       if (IS_PTR(ctype)) {
-               
-               int p_type;
-               sym_link *type = operandType(right);
-               sym_link *etype = getSpec(type);
-               DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
-               
-               /* pointer to generic pointer */
-               if (IS_GENPTR(ctype)) {
-                       char *l = zero;
-                       
-                       if (IS_PTR(type)) 
-                               p_type = DCL_TYPE(type);
-                       else {
-                               /* we have to go by the storage class */
-                               p_type = PTR_TYPE(SPEC_OCLS(etype));
-                               
-                               /*              if (SPEC_OCLS(etype)->codesp )  */
-                               /*                  p_type = CPOINTER ;  */
-                               /*              else */
-                               /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-                               /*                      p_type = FPOINTER ; */
-                               /*                  else */
-                               /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-                               /*                          p_type = PPOINTER; */
-                               /*                      else */
-                               /*                          if (SPEC_OCLS(etype) == idata ) */
-                               /*                              p_type = IPOINTER ; */
-                               /*                          else */
-                               /*                              p_type = POINTER ; */
-                       }
-                       
-                       /* the first two bytes are known */
-                       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
-                       size = GPTRSIZE - 1; 
-                       offset = 0 ;
-                       while (size--) {
-                               if(offset < AOP_SIZE(right)) {
-                                       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
-                                       if ((AOP_TYPE(right) == AOP_PCODE) && 
-                                               AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
-                                               emitpcode(POC_MOVLW, popGet(AOP(right),offset));
-                                               emitpcode(POC_MOVWF, popGet(AOP(result),offset));
-                                       } else { 
-                                               aopPut(AOP(result),
-                                                       aopGet(AOP(right),offset,FALSE,FALSE),
-                                                       offset);
-                                       }
-                               } else 
-                                       emitpcode(POC_CLRF,popGet(AOP(result),offset));
-                               offset++;
-                       }
-                       /* the last byte depending on type */
-                       switch (p_type) {
-                       case IPOINTER:
-                       case POINTER:
-                               emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
-                               break;
-                       case FPOINTER:
-                               pic14_emitcode(";BUG!? ","%d",__LINE__);
-                               l = one;
-                               break;
-                       case CPOINTER:
-                               pic14_emitcode(";BUG!? ","%d",__LINE__);
-                               l = "#0x02";
-                               break;                          
-                       case PPOINTER:
-                               pic14_emitcode(";BUG!? ","%d",__LINE__);
-                               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 ;
-       }
-       
-       
-       
        /* 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))
+       if(0 && genMixedOperation(ic)) {
+               /* XXX: cannot optimize: must copy regs! */
                goto release;
-       
-       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+       }
        
        /* we move to result for the size of source */
        size = AOP_SIZE(right);
@@ -9705,36 +10499,9 @@ static void genCast (iCode *ic)
                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(rtype) || !IS_SPEC(rtype)) {
-               while (size--)
-                       emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
-       } else {
-               /* we need to extend the sign :{ */
-               
-               if(size == 1) {
-                       /* Save one instruction of casting char to int */
-                       emitpcode(POC_CLRF,   popGet(AOP(result),offset));
-                       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
-                       emitpcode(POC_DECF,   popGet(AOP(result),offset));
-               } else {
-                       emitpcodeNULLop(POC_CLRW);
-                       
-                       if(offset)
-                               emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
-                       else
-                               emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
-                       
-                       emitpcode(POC_MOVLW,   popGetLit(0xff));
-                       
-                       while (size--)
-                               emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
-               }
-       }
-       
+
+       addSign (result, AOP_SIZE(right), !SPEC_USIGN(rtype));
+
 release:
        freeAsmop(right,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
@@ -9747,6 +10514,7 @@ release:
 static int genDjnz (iCode *ic, iCode *ifx)
 {
        symbol *lbl, *lbl1;
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if (!ifx)
@@ -9782,7 +10550,7 @@ static int genDjnz (iCode *ic, iCode *ifx)
                        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 {        
+       } else {  
                
                
                emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
@@ -9808,6 +10576,7 @@ static int genDjnz (iCode *ic, iCode *ifx)
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode *ic)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if (isOperandInFarSpace(IC_RESULT(ic)) &&
@@ -9845,6 +10614,7 @@ static void genReceive (iCode *ic)
 static void
 genDummyRead (iCode * ic)
 {
+       FENTRY;
        pic14_emitcode ("; genDummyRead","");
        pic14_emitcode ("; not implemented","");
        
@@ -9867,7 +10637,9 @@ void genpic14Code (iCode *lic)
 {
        iCode *ic;
        int cln = 0;
+       const char *cline;
        
+       FENTRY;
        lineHead = lineCurr = NULL;
        
        pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
@@ -9876,48 +10648,30 @@ void genpic14Code (iCode *lic)
        /* if debug information required */
        if (options.debug && currFunc) { 
                if (currFunc) {
-                       debugFile->writeFunction(currFunc);
-                       _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;
+                       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("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
-                       pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
-                       printCLine(ic->filename, ic->lineno));
-                       */
-                       if (!options.noCcodeInAsm) {
-                               addpCode2pBlock(pb,
-                                       newpCodeCSource(ic->lineno, 
-                                       ic->filename, 
-                                       printCLine(ic->filename, ic->lineno)));
-                       }
-                       
-                       cln = ic->lineno ;
-               }
+               //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 you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
+               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) {
+                 emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
+               }
                /* if the result is marked as
                spilt and rematerializable or code for
                this has already been generated then
@@ -9944,11 +10698,11 @@ void genpic14Code (iCode *lic)
                        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
+                       /* 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 &&
@@ -10008,7 +10762,7 @@ void genpic14Code (iCode *lic)
                        break;
                        
                case '>' :
-                       genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                     
+                       genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
                        break;
                        
                case '<' :
@@ -10019,15 +10773,15 @@ void genpic14Code (iCode *lic)
                case GE_OP:
                case NE_OP:
                        
-               /* note these two are xlated by algebraic equivalence
+                       /* 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;  
+                       break;  
                        
                case EQ_OP:
                        genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
-                       break;      
+                       break;      
                        
                case AND_OP:
                        genAndOp (ic);
@@ -10113,10 +10867,12 @@ void genpic14Code (iCode *lic)
                        break;
                        
                default :
+                       fprintf(stderr, "UNHANDLED iCode: "); piCode(ic, stderr);
                        ic = ic;
+                       break;
                }
        }
-       
+
        
        /* now we are ready to call the
        peep hole optimizer */
@@ -10133,3 +10889,32 @@ void genpic14Code (iCode *lic)
        
        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. */
+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_FUNC(OP_SYM_TYPE(op))) return 1;
+  if (IS_PTR(OP_SYM_TYPE(op)) && AOP_TYPE(op) == AOP_PCODE && AOP(op)->aopu.pcop->type == PO_IMMEDIATE) return 1;
+  return 0;
+}