* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / src / pic / gen.c
index ea77e889b3c6f68757e64e0a32d3871752c3f4af..ac092203ff2f3a87528a1a7ca874d2f6fb4f7d78 100644 (file)
 #include "pcode.h"
 #include "gen.h"
 
-
 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;
@@ -63,9 +61,8 @@ static int GpsuedoStkPtr=0;
 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
 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 +74,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;
 
@@ -99,10 +95,10 @@ static struct {
 about an iCode ifx that makes it easier to generate code.
 */
 typedef struct resolvedIfx {
-       symbol *lbl;       /* pointer to a label */
+       symbol *lbl;     /* pointer to a label */
        int condition;   /* true or false ifx */
-                                        int generated;   /* set true when the code associated with the ifx
-                                        * is generated */
+       int generated;   /* set true when the code associated with the ifx
+                         * is generated */
 } resolvedIfx;
 
 extern int pic14_ptrRegReq ;
@@ -178,9 +174,9 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
 {
        va_list ap;
        char lb[INITIAL_INLINEASM];  
-       char *lbp = lb;
+       unsigned char *lbp = lb;
        
-       if(!debug_verbose)
+       if(!debug_verbose && !options.debug)
                return;
        
        va_start(ap,fmt);   
@@ -208,13 +204,52 @@ 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));
+  }
+  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));
@@ -237,7 +272,7 @@ void pic14_emitcode (char *inst,char *fmt, ...)
 {
        va_list ap;
        char lb[INITIAL_INLINEASM];  
-       char *lbp = lb;
+       unsigned char *lbp = lb;
        
        va_start(ap,fmt);   
        
@@ -402,7 +437,7 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
        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);
@@ -486,8 +521,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__);
@@ -720,7 +755,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 )
 {
@@ -745,7 +780,7 @@ bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
 }
 
 /*-----------------------------------------------------------------*/
-/* aopOp - allocates an asmop for an operand  :                                   */
+/* aopOp - allocates an asmop for an operand  :                    */
 /*-----------------------------------------------------------------*/
 void aopOp (operand *op, iCode *ic, bool result)
 {
@@ -756,7 +791,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);
@@ -822,6 +856,10 @@ void aopOp (operand *op, iCode *ic, bool result)
                        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);
@@ -831,6 +869,7 @@ 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 
@@ -864,23 +903,27 @@ 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);
-               
-               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);
+               if (sym->usl.spillLoc)
+               {
+                       if (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);
+               
+                       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);
                
-               return;
+                       return;
+               }
        }
        
        {
@@ -1140,9 +1183,13 @@ 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);
                        
@@ -1177,7 +1224,7 @@ pCodeOp *popGetTempReg(void)
 }
 
 /*-----------------------------------------------------------------*/
-/* popGetTempReg - create a new temporary pCodeOp                                 */
+/* popReleaseTempReg - create a new temporary pCodeOp                             */
 /*-----------------------------------------------------------------*/
 void popReleaseTempReg(pCodeOp *pcop)
 {
@@ -1212,7 +1259,7 @@ pCodeOp *popGetHighLabel(unsigned int key)
 }
 
 /*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion                     */
+/* popGetLit - asm operator to pcode operator conversion                          */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetLit(unsigned int lit)
 {
@@ -1231,7 +1278,7 @@ pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
 
 
 /*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion                     */
+/* popGetWithString - asm operator to pcode operator conversion                           */
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetWithString(char *str, int isExtern)
 {
@@ -1316,7 +1363,14 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* offset is greater than
        size then zero */
+
+       if (!(offset >= 0 && ((offset < aop->size) || (aop->size == 0))))
+       {
+         fprintf (stderr, "%s:%u: offset=%d, aop-type:%s, size:%d\n", __FILE__, __LINE__, offset, AopType (aop->type), aop->size);
+       }
+       assert (offset >= 0 && ((offset < aop->size) || (aop->size == 0)));
        
+       /* XXX: still needed for BIT operands (AOP_CRY) */
        if (offset > (aop->size - 1) &&
                aop->type != AOP_LIT)
                return NULL;  //zero;
@@ -1398,11 +1452,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;
        }
        
@@ -1410,6 +1481,27 @@ 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 poGet)  */
+/*-----------------------------------------------------------------*/
+pCodeOp *popGetAddr (asmop *aop, int offset, int index)
+{
+  if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
+  {
+    pCodeOp *pcop = aop->aopu.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;
+    return pcop;
+  } else {
+    return popGet (aop, offset + index);
+  }
+}
+
 /*-----------------------------------------------------------------*/
 /* aopPut - puts a string for a aop                                                       */
 /*-----------------------------------------------------------------*/
@@ -1652,10 +1744,8 @@ 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));
        
@@ -1739,8 +1829,8 @@ int pic14_getDataSize(operand *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__);
@@ -1813,8 +1903,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,19 +1927,20 @@ static void genNot (iCode *ic)
                goto release;
        }
        
+       assert (!pic14_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(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;
+       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
+       mov2w (AOP(IC_LEFT(ic)),0);
+       while (--size > 0)
+       {
+         if (aop_isLitLike (AOP(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));
+       emitSKPNZ;
+       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
+       goto release;
        
 release:       
        /* release the aops */
@@ -1864,6 +1957,7 @@ 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);
@@ -1907,6 +2001,8 @@ 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 */
@@ -1934,6 +2030,7 @@ static void genUminus (iCode *ic)
        int size, i;
        sym_link *optype, *rtype;
        
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* assign asmops */
@@ -1995,6 +2092,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) 
@@ -2057,6 +2156,8 @@ 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 */
@@ -2116,6 +2217,8 @@ static void assignResultValue(operand * oper)
 {
        int size = AOP_SIZE(oper);
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
@@ -2133,6 +2236,7 @@ static void assignResultValue(operand * oper)
 /*-----------------------------------------------------------------*/
 static void genIpush (iCode *ic)
 {
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 #if 0
@@ -2194,6 +2298,8 @@ static void genIpush (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genIpop (iCode *ic)
 {
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 #if 0
        int size,offset ;
@@ -2219,6 +2325,8 @@ static void genIpop (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void unsaverbank (int bank,iCode *ic,bool popPsw)
 {
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 #if 0
        int i;
@@ -2267,6 +2375,8 @@ static void unsaverbank (int bank,iCode *ic,bool popPsw)
 /*-----------------------------------------------------------------*/
 static void saverbank (int bank, iCode *ic, bool pushPsw)
 {
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 #if 0
        int i;
@@ -2320,6 +2430,8 @@ static void genCall (iCode *ic)
        unsigned char *name;
        int isExtern;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        /* if caller saves & we have not saved then */
@@ -2371,9 +2483,9 @@ 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));
                                        
@@ -2396,7 +2508,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 */
@@ -2454,6 +2566,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)
@@ -2500,11 +2614,11 @@ static void genPcall (iCode *ic)
        emitpcode(POC_GOTO,pcop);
        emitpLabel(albl->key);
        
-       poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
+       poc = ( aop_isLitLike (AOP(left)) ? 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);
@@ -2544,6 +2658,8 @@ static void genPcall (iCode *ic)
 static int resultRemat (iCode *ic)
 {
        //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       FENTRY;
+
        if (SKIP_IC(ic) || ic->op == IFX)
                return 0;
        
@@ -2593,6 +2709,8 @@ 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);
@@ -2676,7 +2794,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
@@ -2780,6 +2898,8 @@ 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)
@@ -2925,15 +3045,17 @@ registers :-) */
 /*-----------------------------------------------------------------*/
 static void genRet (iCode *ic)
 {
-       int size, pushed = 0;
+       int size,offset = 0 , pushed = 0;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* if we have no return value then
        just generate the "ret" */
        if (!IC_LEFT(ic)) 
                goto jumpret;           
        
-       /* we have something to return then
+               /* we have something to return then
        move the return value into place */
        aopOp(IC_LEFT(ic),ic,FALSE);
        size = AOP_SIZE(IC_LEFT(ic));
@@ -2942,23 +3064,26 @@ static void genRet (iCode *ic)
                char *l ;
                if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
                        /* #NOCHANGE */
-                       l = aopGet(AOP(IC_LEFT(ic)),size,FALSE,TRUE);
+                       l = aopGet(AOP(IC_LEFT(ic)),offset++,
+                               FALSE,TRUE);
                        pic14_emitcode("push","%s",l);
                        pushed++;
                } else {
-                       l = aopGet(AOP(IC_LEFT(ic)),size,FALSE,FALSE);
-                       if (strcmp(fReturn[size],l)) {
+                       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)),size));
+                                       emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                }else {
-                                       emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),size));
+                                       emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
                                }
                                if(size) {
                                        emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
                                }
+                               offset++;
                        }
                }
        }
@@ -2991,6 +3116,8 @@ jumpret:
 /*-----------------------------------------------------------------*/
 static void genLabel (iCode *ic)
 {
+       FENTRY;
+
        /* special case never generate */
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if (IC_LABEL(ic) == entryLabel)
@@ -3006,6 +3133,8 @@ static void genLabel (iCode *ic)
 //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);
 }
@@ -3018,6 +3147,7 @@ static void genMultbits (operand *left,
                                                 operand *right, 
                                                 operand *result)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if(!pic14_sameRegs(AOP(result),AOP(right)))
@@ -3042,6 +3172,8 @@ static void genMultOneByte (operand *left,
        // symbol *lbl ;
        int size,offset;
        
+       FENTRY;
+       
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        DEBUGpic14_AopType(__LINE__,left,right,result);
        DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
@@ -3145,6 +3277,8 @@ static void genMult (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);
@@ -3189,6 +3323,8 @@ static void genDivbits (operand *left,
        
        char *l;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* the result must be bit */      
        pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
@@ -3213,6 +3349,7 @@ static void genDivOneByte (operand *left,
        symbol *lbl ;
        int size,offset;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        size = AOP_SIZE(result) - 1;
        offset = 1;
@@ -3294,6 +3431,7 @@ static void genDiv (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);
@@ -3333,6 +3471,7 @@ static void genModbits (operand *left,
        
        char *l;
        
+       FENTRY;
        /* the result must be bit */      
        pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
        l = aopGet(AOP(left),0,FALSE,FALSE);
@@ -3356,6 +3495,7 @@ static void genModOneByte (operand *left,
        char *l ;
        symbol *lbl ;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* signed or unsigned */
        if (SPEC_USIGN(opetype)) {
@@ -3428,6 +3568,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);
@@ -3467,6 +3608,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 */
@@ -3511,6 +3653,7 @@ static void genIfxJump (iCode *ic, char *jval)
 /*-----------------------------------------------------------------*/
 static void genSkip(iCode *ifx,int status_bit)
 {
+       FENTRY;
        if(!ifx)
                return;
        
@@ -3561,15 +3704,17 @@ static void genSkip(iCode *ifx,int status_bit)
 /*-----------------------------------------------------------------*/
 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;
 }
 
@@ -3578,6 +3723,7 @@ static void genSkipc(resolvedIfx *rifx)
 /*-----------------------------------------------------------------*/
 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
 {
+       FENTRY;
        if(!rifx)
                return;
        
@@ -3595,6 +3741,7 @@ static void genSkipz2(resolvedIfx *rifx, int invert_condition)
 /*-----------------------------------------------------------------*/
 static void genSkipz(iCode *ifx, int condition)
 {
+       FENTRY;
        if(!ifx)
                return;
        
@@ -3614,11 +3761,14 @@ static void genSkipz(iCode *ifx, int condition)
                pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
        
 }
+
+#if 0
 /*-----------------------------------------------------------------*/
 /* genSkipCond                                                     */
 /*-----------------------------------------------------------------*/
 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
 {
+       FENTRY;
        if(!rifx)
                return;
        
@@ -3631,6 +3781,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
 /*-----------------------------------------------------------------*/
@@ -3661,6 +3812,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                       */
 /*-----------------------------------------------------------------*/
@@ -3672,6 +4058,8 @@ static void genCmp (operand *left,operand *right,
        resolvedIfx rFalseIfx;
        //  resolvedIfx rTrueIfx;
        symbol *truelbl;
+
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /*
        if(ifx) {
@@ -3760,7 +4148,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 {
@@ -3768,7 +4156,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" );
                                        }
                                }
                                
@@ -3819,7 +4207,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;
@@ -3835,7 +4223,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;
@@ -3851,7 +4239,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;
@@ -3899,7 +4287,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);
                                
@@ -3937,7 +4325,7 @@ static void genCmp (operand *left,operand *right,
 
                emitpLabel(lbl->key);
                //if(emitFinalCheck)
-               genSkipc(&rFalseIfx);
+               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                if(sign)
                        emitpLabel(truelbl->key);
 
@@ -4002,7 +4390,7 @@ static void genCmp (operand *left,operand *right,
                                                emitpcode(POC_ADDLW, popGetLit(0x80));
                                                emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
                                                rFalseIfx.condition ^= 1;
-                                               genSkipc(&rFalseIfx);
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                                break;
                                        }
                                        if(ifx) ifx->generated = 1;
@@ -4026,7 +4414,7 @@ static void genCmp (operand *left,operand *right,
                                                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
                                                rFalseIfx.condition ^= 1;
                                                if (AOP_TYPE(result) == AOP_CRY) {
-                                                       genSkipc(&rFalseIfx);
+                                                       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);
@@ -4096,7 +4484,7 @@ static void genCmp (operand *left,operand *right,
                                                emitpcode(POC_ADDLW, popGetLit( 0x80));
                                                emitpcode(POC_ADDLW, popGetLit(0x100-i));
                                                rFalseIfx.condition ^= 1;
-                                               genSkipc(&rFalseIfx);
+                                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                                
                                                
                                                if(ifx) ifx->generated = 1;
@@ -4148,7 +4536,7 @@ static void genCmp (operand *left,operand *right,
                                        }
                                        rFalseIfx.condition ^= 1;
                                        //rFalseIfx.condition = 1;
-                                       genSkipc(&rFalseIfx);
+                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                        
                                        emitpLabel(truelbl->key);
                                        
@@ -4190,7 +4578,7 @@ static void genCmp (operand *left,operand *right,
                                                        emitpcode(POC_SUBFW, popGet(AOP(right),0));
                                                        
                                                        rFalseIfx.condition ^= 1;
-                                                       genSkipc(&rFalseIfx);
+                                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                                }
                                                
                                                emitpLabel(truelbl->key);
@@ -4226,7 +4614,7 @@ static void genCmp (operand *left,operand *right,
                                        emitpLabel(lbl->key);
                                        
                                        rFalseIfx.condition ^= 1;
-                                       genSkipc(&rFalseIfx);
+                                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                }
                                
                                if(sign)
@@ -4260,7 +4648,7 @@ static void genCmp (operand *left,operand *right,
                                emitpcode(POC_ADDLW, popGetLit(0x80));
                                
                                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-                               genSkipc(&rFalseIfx);
+                               genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                                
                                if(ifx) ifx->generated = 1;
                                return;
@@ -4294,9 +4682,9 @@ static void genCmp (operand *left,operand *right,
                        emitpcode(POC_CLRF, popGet(AOP(result),0));
                        emitpcode(POC_RLF, popGet(AOP(result),0));
                } else {
-                       genSkipc(&rFalseIfx);
+                       genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                }       
-               //genSkipc(&rFalseIfx);
+               //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
                if(ifx) ifx->generated = 1;
                
                return;
@@ -4320,6 +4708,7 @@ static void genCmp (operand *left,operand *right,
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genCmpGt :- greater than comparison                             */
@@ -4330,6 +4719,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);
@@ -4359,6 +4749,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);
@@ -4387,6 +4778,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;
@@ -4436,20 +4828,61 @@ static void genc16bit2lit(operand *op, int lit, int offset)
 /*-----------------------------------------------------------------*/
 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 
@@ -4474,6 +4907,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));
@@ -4485,8 +4919,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;
@@ -4502,10 +4934,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__);
@@ -4519,6 +4948,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) && 
@@ -4535,8 +4965,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:
@@ -4571,21 +5001,19 @@ 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){
-               
+
+               offset = 0;
                while(size--) {
                        emitpcode(POC_MOVFW,popGet(AOP(left),offset));
                        emitpcode(POC_XORFW,popGet(AOP(right),offset));
@@ -4596,12 +5024,11 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                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 */
+               offset = 0;
                while(size--) {
                        char *l = aopGet(AOP(left),offset,FALSE,FALSE);
                        if(strcmp(l,"b"))
@@ -4612,7 +5039,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                }
        }
        
-       emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+       emitpcode(POC_INCF,popGet(AOP(result),0));
        if(!rIfx.condition)
                emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
        
@@ -4622,6 +5049,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        
        if(ifx)
                ifx->generated = 1;
+#endif
 }
 
 #if 0
@@ -4656,6 +5084,7 @@ static void genCmpEq (iCode *ic, iCode *ifx)
        unsigned long lit = 0L;
        int size,offset=0;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if(ifx)
@@ -4674,8 +5103,8 @@ static void genCmpEq (iCode *ic, iCode *ifx)
        /* if literal, literal on the right or 
        if the right is in a pointer register and left 
        is not */
-       if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
-               (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+       if (aop_isLitLike (AOP(IC_LEFT(ic)))
+                       || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
                operand *tmp = right ;
                right = left;
                left = tmp;
@@ -4840,8 +5269,8 @@ static void genCmpEq (iCode *ic, iCode *ifx)
                                tlbl = newiTempLabel(NULL);
                                
                                while(size--) {
-                                       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-                                       emitpcode(POC_XORFW,popGet(AOP(right),offset));
+                                       mov2w (AOP(right),offset); /* right might be litLike() */
+                                       emitpcode(POC_XORFW,popGet(AOP(left),offset));
                                        
                                        if ( IC_TRUE(ifx) ) {
                                                if(size) {
@@ -4949,13 +5378,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 &&
@@ -4995,6 +5425,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
@@ -5046,6 +5477,7 @@ static void genOrOp (iCode *ic)
        /* 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);
@@ -5095,6 +5527,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])
@@ -5107,6 +5540,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);
@@ -5118,6 +5552,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);
@@ -5129,6 +5564,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)){
@@ -5156,7 +5592,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);
@@ -5311,7 +5747,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:
@@ -5323,12 +5758,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;
@@ -5378,16 +5810,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));
@@ -5396,12 +5822,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));
                                                }
@@ -5411,16 +5831,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));
                        }
                }
@@ -5441,6 +5856,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);
@@ -5586,150 +6002,144 @@ static void genOr (iCode *ic, iCode *ifx)
                else if((AOP_TYPE(result) == AOP_CRY) && ifx)
                        genIfxJump(ifx, "c");           
                goto release ;
-  }
-  
-  // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
-  // bit = val | 0xZZ     - size = 1, ifx = FALSE -
-  if((AOP_TYPE(right) == AOP_LIT) &&
+       }
+
+       // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
+       // bit = val | 0xZZ     - size = 1, ifx = FALSE -
+       if((AOP_TYPE(right) == AOP_LIT) &&
          (AOP_TYPE(result) == AOP_CRY) &&
          (AOP_TYPE(left) != AOP_CRY)){
-         if(lit){
-                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-                 // result = 1
-                 if(size)
-                         pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
-                 else 
-                         continueIfTrue(ifx);
-                 goto release;
-         } else {
-                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-                 // lit = 0, result = boolean(left)
-                 if(size)
-                         pic14_emitcode(";XXX setb","c");
-                 pic14_toBoolean(right);
-                 if(size){
-                         symbol *tlbl = newiTempLabel(NULL);
-                         pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
-                         CLRC;
-                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-                 } else {
-                         genIfxJump (ifx,"a");
-                         goto release;
-                 }
-         }
-         pic14_outBitC(result);
-         goto release ;
-  }
-  
-  /* if left is same as result */
-  if(pic14_sameRegs(AOP(result),AOP(left))){
-         int know_W = -1;
-         for(;size--; offset++,lit>>=8) {
-                 if(AOP_TYPE(right) == AOP_LIT){
-                         if((lit & 0xff) == 0)
-                                 /*  or'ing with 0 has no effect */
-                                 continue;
-                         else {
-                                 int p = my_powof2(lit & 0xff);
-                                 if(p>=0) {
-                                         /* only one bit is set in the literal, so use a bsf instruction */
-                                         emitpcode(POC_BSF,
-                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
-                                 } else {
-                                         if(know_W != (int)(lit & 0xff))
-                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-                                         know_W = lit & 0xff;
-                                         emitpcode(POC_IORWF, popGet(AOP(left),offset));
-                                 }
-                                 
-                         }
-                 } else {
-                         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 {        
-                                 emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
-                                 emitpcode(POC_IORWF,  popGet(AOP(left),offset));
-                                 
-                                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-                                 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-                                 
-                         }
-                 }
-         }
-  } else {
-         // left & result in different registers
-         if(AOP_TYPE(result) == AOP_CRY){
-                 // result = bit
-                 // if(size), result in bit
-                 // if(!size && ifx), conditional oper: if(left | right)
-                 symbol *tlbl = newiTempLabel(NULL);
-                 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
-                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-                 
-                 
-                 if(size)
-                         pic14_emitcode(";XXX setb","c");
-                 while(sizer--){
-                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                         pic14_emitcode(";XXX orl","a,%s",
-                                 aopGet(AOP(left),offset,FALSE,FALSE));
-                         pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
-                         offset++;
-                 }
-                 if(size){
-                         CLRC;
-                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-                         pic14_outBitC(result);
-                 } else if(ifx)
-                         jmpTrueOrFalse(ifx, tlbl);
-         } else for(;(size--);offset++){
-                 // normal case
-                 // result = left & right
-                 if(AOP_TYPE(right) == AOP_LIT){
-                         int t = (lit >> (offset*8)) & 0x0FFL;
-                         switch(t) { 
-                         case 0x00:
-                                 if (AOP_TYPE(left) != AOP_ACC) {
-                                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
-                                 }
-                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
-                                 
-                                 break;
-                         default:
-                                 if (AOP_TYPE(left) == AOP_ACC) {
-                                         emitpcode(POC_IORLW,  popGetLit(t));
-                                 } else {
-                                         emitpcode(POC_MOVLW,  popGetLit(t));
-                                         emitpcode(POC_IORFW,  popGet(AOP(left),offset));
-                                 }
-                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
-                         }
-                         continue;
-                 }
-                 
-                 // faster than result <- left, anl result,right
-                 // and better if result is SFR
-                 if (AOP_TYPE(left) == AOP_ACC) {
-                         emitpcode(POC_IORWF,  popGet(AOP(right),offset));
-                         pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-                 } 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_MOVWF,  popGet(AOP(result),offset));
-                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-         }
-  }
-  
+               if(lit){
+                       pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+                       // result = 1
+                       if(size)
+                               pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
+                       else 
+                               continueIfTrue(ifx);
+                       goto release;
+               } else {
+                       pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+                       // lit = 0, result = boolean(left)
+                       if(size)
+                               pic14_emitcode(";XXX setb","c");
+                       pic14_toBoolean(right);
+                       if(size){
+                               symbol *tlbl = newiTempLabel(NULL);
+                               pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+                               CLRC;
+                               pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+                       } else {
+                               genIfxJump (ifx,"a");
+                               goto release;
+                       }
+               }
+               pic14_outBitC(result);
+               goto release ;
+       }
+
+       /* if left is same as result */
+       if(pic14_sameRegs(AOP(result),AOP(left))){
+               int know_W = -1;
+               for(;size--; offset++,lit>>=8) {
+                       if(AOP_TYPE(right) == AOP_LIT){
+                               if((lit & 0xff) == 0)
+                                       /*  or'ing with 0 has no effect */
+                                       continue;
+                               else {
+                                       int p = my_powof2(lit & 0xff);
+                                       if(p>=0) {
+                                               /* only one bit is set in the literal, so use a bsf instruction */
+                                               emitpcode(POC_BSF,
+                                                       newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+                                       } else {
+                                               if(know_W != (int)(lit & 0xff))
+                                                       emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+                                               know_W = lit & 0xff;
+                                               emitpcode(POC_IORWF, popGet(AOP(left),offset));
+                                       }
+                                       
+                               }
+                       } else {
+                               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 {        
+                                       emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
+                                       emitpcode(POC_IORWF,  popGet(AOP(left),offset));
+                                       
+                                       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+                                       pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+                                       
+                               }
+                       }
+               }
+       } else {
+               // left & result in different registers
+               if(AOP_TYPE(result) == AOP_CRY){
+                       // result = bit
+                       // if(size), result in bit
+                       // if(!size && ifx), conditional oper: if(left | right)
+                       symbol *tlbl = newiTempLabel(NULL);
+                       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
+                       pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+                       
+                       
+                       if(size)
+                               pic14_emitcode(";XXX setb","c");
+                       while(sizer--){
+                               MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+                               pic14_emitcode(";XXX orl","a,%s",
+                                       aopGet(AOP(left),offset,FALSE,FALSE));
+                               pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+                               offset++;
+                       }
+                       if(size){
+                               CLRC;
+                               pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+                               pic14_outBitC(result);
+                       } else if(ifx)
+                               jmpTrueOrFalse(ifx, tlbl);
+               } else for(;(size--);offset++){
+                       // normal case
+                       // result = left | right
+                       if(AOP_TYPE(right) == AOP_LIT){
+                               int t = (lit >> (offset*8)) & 0x0FFL;
+                               switch(t) { 
+                               case 0x00:
+                                       if (AOP_TYPE(left) != AOP_ACC) {
+                                               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
+                                       }
+                                       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
+                                       
+                                       break;
+                               default:
+                                       if (AOP_TYPE(left) == AOP_ACC) {
+                                               emitpcode(POC_IORLW,  popGetLit(t));
+                                       } else {
+                                               emitpcode(POC_MOVLW,  popGetLit(t));
+                                               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
+                                       }
+                                       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
+                               }
+                               continue;
+                       }
+                       
+                       // faster than result <- left, anl result,right
+                       // and better if result is SFR
+                       if (AOP_TYPE(left) == AOP_ACC) {
+                               emitpcode(POC_IORFW,popGet(AOP(right),offset));
+                       } else {
+                               emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+                               emitpcode(POC_IORFW,popGet(AOP(left),offset));
+                       }
+                       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
+               }
+       }
+
 release :
-  freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-  freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-  freeAsmop(result,NULL,ic,TRUE);     
+       freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+       freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+       freeAsmop(result,NULL,ic,TRUE);     
 }
 
 /*-----------------------------------------------------------------*/
@@ -5741,6 +6151,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);
@@ -5806,6 +6217,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");
                                        }
@@ -5959,16 +6371,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));
                        }
                }
        }
@@ -5984,40 +6392,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -6028,6 +6441,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);
@@ -6070,6 +6484,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);
@@ -6117,6 +6532,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));
@@ -6138,8 +6554,9 @@ static void genGetHbit (iCode *ic)
 /*-----------------------------------------------------------------*/
 /* AccRol - rotate left accumulator by known count                 */
 /*-----------------------------------------------------------------*/
-static void AccRol (int shCount)
+static void AccRol (operand *op,int offset,int shCount)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        shCount &= 0x0007;              // shCount : 0..7
        switch(shCount){
@@ -6147,28 +6564,39 @@ static void AccRol (int shCount)
                break;
        case 1 :
                pic14_emitcode("rl","a");
+               emitpcode(POC_RLF,popGet(AOP(op),offset));
                break;
        case 2 :
                pic14_emitcode("rl","a");
                pic14_emitcode("rl","a");
+               emitpcode(POC_RLF,popGet(AOP(op),offset));
+               emitpcode(POC_RLF,popGet(AOP(op),offset));
                break;
        case 3 :
                pic14_emitcode("swap","a");
                pic14_emitcode("rr","a");
+               emitpcode(POC_SWAPF,popGet(AOP(op),offset));
+               emitpcode(POC_RRF,popGet(AOP(op),offset));
                break;
        case 4 :
                pic14_emitcode("swap","a");
+               emitpcode(POC_SWAPF,popGet(AOP(op),offset));
                break;
        case 5 :
                pic14_emitcode("swap","a");
                pic14_emitcode("rl","a");
+               emitpcode(POC_SWAPF,popGet(AOP(op),offset));
+               emitpcode(POC_RLF,popGet(AOP(op),offset));
                break;
        case 6 :
                pic14_emitcode("rr","a");
                pic14_emitcode("rr","a");
+               emitpcode(POC_RRF,popGet(AOP(op),offset));
+               emitpcode(POC_RRF,popGet(AOP(op),offset));
                break;
        case 7 :
                pic14_emitcode("rr","a");
+               emitpcode(POC_RRF,popGet(AOP(op),offset));
                break;
        }
 }
@@ -6176,40 +6604,42 @@ static void AccRol (int shCount)
 /*-----------------------------------------------------------------*/
 /* AccLsh - left shift accumulator by known count                  */
 /*-----------------------------------------------------------------*/
-static void AccLsh (int shCount)
+static void AccLsh (operand *op,int offset,int shCount)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       if(shCount != 0){
-               if(shCount == 1)
-                       pic14_emitcode("add","a,acc");
-               else 
-                       if(shCount == 2) {
-                               pic14_emitcode("add","a,acc");
-                               pic14_emitcode("add","a,acc");
-                       } else {
-                               /* rotate left accumulator */
-                               AccRol(shCount);
-                               /* and kill the lower order bits */
-                               pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
-                       }
+       if(shCount != 0) {
+               if (shCount == 1)
+               {
+                       emitCLRC;
+                       emitpcode (POC_RLF, popGet (AOP(op), 0));
+               } else {
+                       /* rotate left accumulator */
+                       AccRol(op,offset,shCount);
+                       /* and kill the lower order bits */
+                       emitpcode(POC_MOVLW,popGetLit(SLMask[shCount]));
+                       emitpcode (POC_ANDWF, popGet (AOP(op),0));
+               }
        }
 }
 
 /*-----------------------------------------------------------------*/
 /* AccRsh - right shift accumulator by known count                 */
 /*-----------------------------------------------------------------*/
-static void AccRsh (int shCount)
+static void AccRsh (operand *op,int offset,int shCount)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(shCount != 0){
                if(shCount == 1){
-                       CLRC;
-                       pic14_emitcode("rrc","a");
+                       emitCLRC;
+                       emitpcode (POC_RRF, popGet (AOP(op), 0));
                } else {
                        /* rotate right accumulator */
-                       AccRol(8 - shCount);
+                       AccRol(op,offset,8 - shCount);
                        /* and kill the higher order bits */
-                       pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
+                       emitpcode (POC_MOVLW, popGetLit (SRMask[shCount]));
+                       emitpcode (POC_ANDWF, popGet (AOP(op),0));
                }
        }
 }
@@ -6244,7 +6674,7 @@ static void AccSRsh (int shCount)
                }
        }
 }
-#endif
+
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
 /*-----------------------------------------------------------------*/
@@ -6254,6 +6684,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);
@@ -6365,6 +6796,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);
@@ -6458,6 +6890,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);
@@ -6521,6 +6954,7 @@ static void shiftL1Left2Result (operand *left, int offl,
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* movLeft2Result - move byte from left to result                  */
@@ -6529,6 +6963,7 @@ 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);
@@ -6543,13 +6978,201 @@ static void movLeft2Result (operand *left, int offl,
        }
 }
 
+/*-----------------------------------------------------------------*/
+/* 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
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRight_Left2ResultLit - shift right by known count          */
+/*-----------------------------------------------------------------*/
+
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
+{
+       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;
+               
+               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__);
        
@@ -6670,6 +7293,7 @@ static void shiftL2Left2Result (operand *left, int offl,
        }
        
 }
+
 /*-----------------------------------------------------------------*/
 /* shiftR2Left2Result - shift right two bytes from left to result  */
 /*-----------------------------------------------------------------*/
@@ -6679,6 +7303,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));
        
@@ -6707,7 +7332,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;
                
@@ -6821,21 +7446,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))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -6844,14 +7468,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))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -6859,6 +7483,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);
 }
@@ -6870,6 +7495,7 @@ static void genlshTwo (operand *result,operand *left, int shCount)
 {
        int size;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        size = pic14_getDataSize(result);
        
@@ -6904,6 +7530,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);
@@ -6964,6 +7591,7 @@ static void genlshFour (operand *result, operand *left, int shCount)
 {
        int size;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        size = AOP_SIZE(result);
        
@@ -7039,7 +7667,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              */
 /*-----------------------------------------------------------------*/
@@ -7049,14 +7679,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
@@ -7093,6 +7724,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.
@@ -7104,6 +7736,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)
@@ -7129,10 +7762,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);
@@ -7140,11 +7775,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 ;
        }
        
@@ -7154,9 +7792,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 */
@@ -7180,11 +7817,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));
@@ -7201,7 +7841,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));
                        }
                        
@@ -7291,12 +7931,14 @@ release:
        freeAsmop(result,NULL,ic,TRUE);
 }
 
+#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);
 }
@@ -7307,6 +7949,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) {
@@ -7337,31 +7980,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7370,6 +8017,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 ) {
@@ -7435,6 +8083,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);
        
@@ -7453,7 +8102,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)){
@@ -7498,10 +8147,11 @@ static void genRightShiftLiteral (operand *left,
                }
                
        }
-       
+
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genSignedRightShift - right shift of signed number              */
@@ -7518,6 +8168,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);
@@ -7530,7 +8181,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 
@@ -7553,14 +8205,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));
@@ -7655,6 +8306,7 @@ static void genRightShift (iCode *ic)
        char *l;
        symbol *tlbl, *tlbl1 ;
        
+       FENTRY;
        /* if signed then we do it the hard way preserve the
        sign bit moving it inwards */
        retype = getSpec(operandType(IC_RESULT(ic)));
@@ -7677,11 +8329,14 @@ 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);
+               shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 0);
+               //genRightShiftLiteral (left,right,result,ic, 0);
                return ;
        }
        
@@ -7693,8 +8348,6 @@ static void genRightShift (iCode *ic)
        
        pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
        pic14_emitcode("inc","b");
-       aopOp(left,ic,FALSE);
-       aopOp(result,ic,FALSE);
        
        /* now move the left to the result if they are not the
        same */
@@ -7764,22 +8417,68 @@ release:
 /*-----------------------------------------------------------------*/
 /* genUnpackBits - generates code for unpacking bits               */
 /*-----------------------------------------------------------------*/
-static void genUnpackBits (operand *result, char *rname, int ptype)
+static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
 {    
-       int shCnt ;
-       int rlen = 0 ;
-       sym_link *etype;
-       int offset = 0 ;
-       
+       int shCnt;
+       int offset = 0;       /* result byte offset */
+       int rsize;            /* result size */
+       int rlen = 0;         /* remaining bitfield length */
+       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 {
+                       pCodeOp *pcop;
+                       int i;
+                       assert (!pic14_sameRegs (AOP(result), AOP(left)));
+                       for (i=0; i < AOP_SIZE(result); i++)
+                               emitpcode (POC_CLRF, popGet (AOP(result), i));
+                       if (ptype == -1) /* direct */
+                               pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
+                       else
+                               pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
+                       emitpcode(POC_BTFSC,pcop);
+                       emitpcode(POC_BSF,newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),0,0));
+               }
+               return;
+       }
+
+       {
+         static int has_warned=0;
+         if (!has_warned)
+         {
+           fprintf (stderr, "%s: bitfields with more than 1 bit are probably broken...", __FUNCTION__);
+           has_warned=1;
+         }
+       }
+
        /* read the first byte  */
        switch (ptype) {
                
        case POINTER:
        case IPOINTER:
-               pic14_emitcode("mov","a,@%s",rname);
+//             pic14_emitcode("mov","a,@%s",rname);
+               emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
                break;
                
        case PPOINTER:
@@ -7799,15 +8498,14 @@ static void genUnpackBits (operand *result, char *rname, int ptype)
                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))  {
+       if ((shCnt = SPEC_BSTR(etype)) || blen <= 8)  {
                
                /* shift right acc */
-               AccRsh(shCnt);
+               AccRsh(left,0,shCnt);
                
                pic14_emitcode("anl","a,#0x%02x",
                        ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
@@ -7867,17 +8565,17 @@ static void genUnpackBits (operand *result, char *rname, int ptype)
        return ;
 }
 
-#if 0
+#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__);
        
        
@@ -7885,16 +8583,20 @@ 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 > AOP_SIZE(left)) size = AOP_SIZE(left);
        
        while (size--) {
+               emitpcode(POC_MOVFW, popGet(AOP(left),offset));
                emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                offset++;
        }
@@ -7904,23 +8606,21 @@ static void genDataPointerGet (operand *left,
 }
 #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);
        
@@ -7931,34 +8631,34 @@ static void genNearPointerGet (operand *left,
        if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
                !IS_BITVAR(retype)         &&
                DCL_TYPE(ltype) == POINTER) {
-               //genDataPointerGet (left,result,ic);
+               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))) {
+       /* Check if can access directly instead of via a pointer */
+       if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
+               direct = 1;
+       }
+
+       /* If the pointer value is not in a the FSR then need to put it in */
+       if (!AOP_INPREG(AOP(left)) && !direct) {
                /* 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);
+               if (PCOP(AOP(result))->type == PO_LITERAL) /* XXX: check me */ 
+                       emitpcode(POC_MOVLW, popGet(AOP(left),0));
+               else
+                       emitpcode(POC_MOVFW, popGet(AOP(left),0));
+               emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
+       }
        
-       aopOp (result,ic,FALSE);
        
+//     sym_link *etype;
        /* if bitfield then unpack the bits */
        if (IS_BITFIELD(retype)) 
-               genUnpackBits (result,rname,POINTER);
+               genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
        else {
                /* we have can just get the values */
                int size = AOP_SIZE(result);
@@ -7966,29 +8666,20 @@ static void genNearPointerGet (operand *left,
                
                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)
+                       if (direct)
+                               emitpcode(POC_MOVWF,popGet(AOP(left),0));
+                       else
+                               emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+                       if (AOP_TYPE(result) == AOP_LIT) {
+                               emitpcode(POC_MOVLW,popGet(AOP(result),offset));
+                       } else {
+                               emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+                       }
+                       if (size && !direct)
                                emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+                       offset++;
                }
-               /*
-               while (size--) {
-               if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
-               
-                 pic14_emitcode("mov","a,@%s",rname);
-                 aopPut(AOP(result),"a",offset);
-                 } else {
-                 sprintf(buffer,"@%s",rname);
-                 aopPut(AOP(result),buffer,offset);
-                 }
-                 offset++ ;
-                 if (size)
-                 pic14_emitcode("inc","%s",rname);
-                 }
-               */
        }
        
        /* now some housekeeping stuff */
@@ -7997,10 +8688,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 &&
@@ -8009,14 +8700,14 @@ 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));
                }
        }
        
        /* done */
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
-       
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -8031,6 +8722,7 @@ static void genPagedPointerGet (operand *left,
        char *rname ;
        sym_link *rtype, *retype;    
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        rtype = operandType(result);
@@ -8056,7 +8748,7 @@ static void genPagedPointerGet (operand *left,
        
        /* if bitfield then unpack the bits */
        if (IS_BITFIELD(retype)) 
-               genUnpackBits (result,rname,PPOINTER);
+               genUnpackBits (result,left,rname,PPOINTER,0);
        else {
                /* we have can just get the values */
                int size = AOP_SIZE(result);
@@ -8109,6 +8801,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);
@@ -8134,7 +8827,7 @@ static void genFarPointerGet (operand *left,
        
        /* if bit then unpack */
        if (IS_BITFIELD(retype)) 
-               genUnpackBits(result,"dptr",FPOINTER);
+               genUnpackBits(result,left,"dptr",FPOINTER,0);
        else {
                size = AOP_SIZE(result);
                offset = 0 ;
@@ -8184,7 +8877,7 @@ static void genCodePointerGet (operand *left,
        
        /* if bit then unpack */
        if (IS_BITFIELD(retype)) 
-               genUnpackBits(result,"dptr",CPOINTER);
+               genUnpackBits(result,left,"dptr",CPOINTER,0);
        else {
                size = AOP_SIZE(result);
                offset = 0 ;
@@ -8210,6 +8903,7 @@ static void genGenPointerGet (operand *left,
        int size, offset ;
        sym_link *retype = getSpec(operandType(result));
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        aopOp(left,ic,FALSE);
        aopOp(result,ic,FALSE);
@@ -8261,37 +8955,85 @@ static void genConstPointerGet (operand *left,
                                                                operand *result, iCode *ic)
 {
        //sym_link *retype = getSpec(operandType(result));
-       symbol *albl = newiTempLabel(NULL);
-       symbol *blbl = newiTempLabel(NULL);
+       symbol *albl, *blbl;//, *clbl;
        PIC_OPCODE poc;
+       int i, size, lit;
        pCodeOp *pcop;
        
+       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__);
-       
-       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));
-       
+
+       lit = aop_isLitLike (AOP(left));
+       poc = lit ? POC_MOVLW : POC_MOVFW;
+
+       if (lit)
+       {
+               for (i = 0; i < size; i++)
+               {
+                       albl = newiTempLabel(NULL);
+                       blbl = newiTempLabel(NULL);
+                       
+                       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);
+                       emitpcode(poc,popGetAddr(AOP(left),1,i));
+                       emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+                       emitpcode(poc,popGetAddr(AOP(left),0,i));
+                       emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+               
+                       emitpLabel(blbl->key);
+                       emitpcode(POC_MOVWF,popGet(AOP(result),i));
+               } // for
+       } else {
+               albl = newiTempLabel(NULL);
+               blbl = newiTempLabel(NULL);
+               //clbl = newiTempLabel(NULL);
+
+               emitpcode (POC_GOTO, popGetLabel (blbl->key));
+               
+               emitpLabel(albl->key);
+               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);
+               
+               for (i = 0; i < size; i++)
+               {
+                       emitpcode(POC_CALL,popGetLabel(albl->key));
+                       /* the next two instructions (plus clbl) might be useless... */
+                       //pcop = popGetLabel(clbl->key);
+                       //emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+                       //emitpcode(POC_GOTO,pcop);
+                       //emitpLabel(clbl->key);
+
+                       if (i+1 < size) {
+                               emitpcode (POC_INCF, popGet (AOP(left), 0));
+                               emitSKPNZ;
+                               emitpcode (POC_INCF, popGet (AOP(left), 1));
+                       }
+                       emitpcode(POC_MOVWF,popGet(AOP(result),i));
+               } // for
+               if (size > 1) {
+                       /* restore left's value */
+                       emitpcode (POC_MOVLW, popGetLit (size-1));
+                       emitpcode (POC_SUBWF, popGet (AOP(left), 0));
+                       emitSKPC;
+                       emitpcode (POC_DECF, popGet (AOP(left), 1));
+               } // if
+       } // if (lit)
        
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
@@ -8304,8 +9046,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);
@@ -8372,186 +9115,311 @@ static void genPointerGet (iCode *ic)
                break;
                
        case GPOINTER:
-               if (IS_PTR_CONST(type))
+               if (IS_CODEPTR(type) || IS_PTR_CONST(type) || SPEC_CONST(etype))
                        genConstPointerGet (left,result,ic);
                else
                        genGenPointerGet (left,result,ic);
                break;
+       default:
+               assert ( !"unhandled pointer type" );
+               break;
        }
        
 }
 
 /*-----------------------------------------------------------------*/
-/* genPackBits - generates code for packed bit storage             */
+/* emitPtrByteGet - for legacy 8051 emits code to get a byte into  */
+/* A through a pointer register (R0, R1, or DPTR). The original    */
+/* value of A can be preserved in B.                               */
+/* PIC has to use INDF register.                                   */
 /*-----------------------------------------------------------------*/
-static void genPackBits (sym_link    *etype ,
-                                                operand *right ,
-                                                char *rname, int p_type)
-{
-       int shCount = 0 ;
-       int offset = 0  ;
-       int rLen = 0 ;
-       int blen, bstr ;   
-       char *l ;
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       blen = SPEC_BLEN(etype);
-       bstr = SPEC_BSTR(etype);
-       
-       l = aopGet(AOP(right),offset++,FALSE,FALSE);
-       MOVA(l);   
-       
-       /* if the bit lenth is less than or    */
-       /* it exactly fits a byte then         */
-       if (SPEC_BLEN(etype) <= 8 )  {
-               shCount = SPEC_BSTR(etype) ;
-               
-               /* shift left acc */
-               AccLsh(shCount);
+static void
+emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
+{
+    FENTRY;
+    switch (p_type)
+    {
+    case IPOINTER:
+    case POINTER:
+               if (preserveAinB)
+                       pic14_emitcode ("mov", "b,a");
+//             pic14_emitcode ("mov", "a,@%s", rname);
+               emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
+               break;
                
-               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");
-               }
-       }
-       
-       switch (p_type) {
-       case POINTER:
-               pic14_emitcode("mov","@%s,a",rname);
+    case PPOINTER:
+               if (preserveAinB)
+                       pic14_emitcode ("mov", "b,a");
+               pic14_emitcode ("movx", "a,@%s", rname);
                break;
                
-       case FPOINTER:
-               pic14_emitcode("movx","@dptr,a");
+    case FPOINTER:
+               if (preserveAinB)
+                       pic14_emitcode ("mov", "b,a");
+               pic14_emitcode ("movx", "a,@dptr");
                break;
                
-       case GPOINTER:
-               DEBUGpic14_emitcode(";lcall","__gptrput");
+    case CPOINTER:
+               if (preserveAinB)
+                       pic14_emitcode ("mov", "b,a");
+               pic14_emitcode ("clr", "a");
+               pic14_emitcode ("movc", "a,@a+dptr");
                break;
-       }
-       
-       /* if we r done */
-       if ( SPEC_BLEN(etype) <= 8 )
-               return ;
-       
-       pic14_emitcode("inc","%s",rname);
-       rLen = SPEC_BLEN(etype) ;     
-       
-       /* now generate for lengths greater than one byte */
-       while (1) {
                
-               l = aopGet(AOP(right),offset++,FALSE,TRUE);
+    case GPOINTER:
+               if (preserveAinB)
+        {
+                       pic14_emitcode ("push", "b");
+                       pic14_emitcode ("push", "acc");
+        }
+               pic14_emitcode ("lcall", "__gptrget");
+               if (preserveAinB)
+                       pic14_emitcode ("pop", "b");
+               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 (char *rname, int p_type, char *src)
+{
+    FENTRY;
+    switch (p_type)
+    {
+    case IPOINTER:
+    case POINTER:
+               if (*src=='@')
+        {
+                       MOVA (src);
+                       pic14_emitcode ("mov", "@%s,a", rname);
+        }
+               else
+//                     pic14_emitcode ("mov", "@%s,%s", rname, src);
+                       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
+               break;
                
-               rLen -= 8 ;
-               if (rLen <= 0 )
-                       break ;
+    case PPOINTER:
+               MOVA (src);
+               pic14_emitcode ("movx", "@%s,a", rname);
+               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);
-       }
-       
-       MOVA(l);
-       
-       /* last last was not complete */
-       if (rLen)   {
-               /* save the byte & read byte */
-               switch (p_type) {
-               case POINTER:
-                       pic14_emitcode ("mov","b,a");
-                       pic14_emitcode("mov","a,@%s",rname);
-                       break;
-                       
-               case FPOINTER:
-                       pic14_emitcode ("mov","b,a");
-                       pic14_emitcode("movx","a,@dptr");
-                       break;
-                       
-               case GPOINTER:
-                       pic14_emitcode ("push","b");
-                       pic14_emitcode ("push","acc");
-                       pic14_emitcode ("lcall","__gptrget");
-                       pic14_emitcode ("pop","b");
-                       break;
-               }
+    case FPOINTER:
+               MOVA (src);
+               pic14_emitcode ("movx", "@dptr,a");
+               break;
                
-               pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
-               pic14_emitcode ("orl","a,b");
-       }
+    case GPOINTER:
+               MOVA (src);
+               pic14_emitcode ("lcall", "__gptrput");
+               break;
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage             */
+/*-----------------------------------------------------------------*/
+static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
+{
+       int offset = 0;       /* source byte offset */
+       int rlen = 0;         /* remaining bitfield length */
+       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__);
        
-       if (p_type == GPOINTER)
-               pic14_emitcode("pop","b");
+       blen = SPEC_BLEN (etype);
+       bstr = SPEC_BSTR (etype);
        
-       switch (p_type) {
-               
-       case POINTER:
-               pic14_emitcode("mov","@%s,a",rname);
-               break;
+       /* If the bitfield length is less than a byte */
+       if (blen < 8)
+    {
+               mask = ((unsigned char) (0xFF << (blen + bstr)) |
+                       (unsigned char) (0xFF >> (8 - bstr)));
                
-       case FPOINTER:
-               pic14_emitcode("movx","@dptr,a");
-               break;
+               if (AOP_TYPE (right) == AOP_LIT)
+        {
+                       /* Case with a bitfield length <8 and literal source
+                       */
+                       int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+                       if (blen == 1) {
+                               if (p_type == -1) {
+                                       pCodeOp *pcop;
+                                       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);
+                               } else {
+                                       emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
+                               }
+                               return;
+                       } else {
+                               litval = lit << bstr;
+                               litval &= (~mask) & 0xff;
+                               if (p_type == -1)
+                                       emitpcode(POC_MOVFW,popGet(AOP(result),0));
+                               else
+                                       emitPtrByteGet (rname, p_type, FALSE);
+                               if ((mask|litval)!=0xff)
+                                       emitpcode(POC_ANDLW,popGetLit(mask));
+                               if (litval)
+                                       emitpcode(POC_IORLW,popGetLit(litval));
+                       }
+        }
+               else
+        {
+                       if (blen==1) {
+                               if (p_type == -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));
+                                       return;
+                               } else if (p_type!=GPOINTER) {
+                                       /* Case with a bitfield length == 1 and no generic pointer
+                                       */
+                                       if (AOP_TYPE (right) == AOP_CRY)
+                                               pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
+                                       else
+                                       {
+                                               MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
+                                               pic14_emitcode ("rrc","a");
+                                       }
+                                       emitPtrByteGet (rname, p_type, FALSE);
+                                       pic14_emitcode ("mov","acc.%d,c",bstr);
+                               }
+            }
+                       else
+            {
+                               //bool pushedB;
+                               /* Case with a bitfield length < 8 and arbitrary source
+                               */
+                               MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
+                               /* shift and mask source value */
+                               AccLsh (right,0,bstr);
+                               pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
+                               emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
+                               
+                               //pushedB = pushB ();
+                               if (p_type == -1)
+                                       emitpcode(POC_MOVFW,popGet(AOP(result),0));
+                               else
+                                       emitPtrByteGet (rname, p_type, TRUE);
+                               
+                               pic14_emitcode ("anl", "a,#0x%02x", mask);
+                               pic14_emitcode ("orl", "a,b");
+                               emitpcode(POC_ANDLW,popGetLit(mask));
+                               emitpcode(POC_IORFW,popGet(AOP(right),0));
+                               if (p_type == GPOINTER)
+                                       pic14_emitcode ("pop", "b");
+                               
+                               //popB (pushedB);
+                       }
+        }
                
-       case GPOINTER:
-               DEBUGpic14_emitcode(";lcall","__gptrput");
-               break;      
+               if (p_type == -1)
+                       emitpcode(POC_MOVWF,popGet(AOP(result),0));
+               else
+                       emitPtrByteSet (rname, p_type, "a");
+               return;
+    }
+       
+       /* Bit length is greater than 7 bits. In this case, copy  */
+       /* all except the partial byte at the end                 */
+       for (rlen=blen;rlen>=8;rlen-=8)
+    {
+               emitPtrByteSet (rname, p_type,
+                       aopGet (AOP (right), offset++, FALSE, TRUE) );
+               if (rlen>8)
+                       pic14_emitcode ("inc", "%s", rname);
+    }
+       
+       /* If there was a partial byte at the end */
+       if (rlen)
+    {
+               mask = (((unsigned char) -1 << rlen) & 0xff);
+               
+               if (AOP_TYPE (right) == AOP_LIT)
+        {
+               /* Case with partial byte and literal source
+                       */
+                       litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+                       litval >>= (blen-rlen);
+                       litval &= (~mask) & 0xff;
+                       emitPtrByteGet (rname, p_type, FALSE);
+                       if ((mask|litval)!=0xff)
+                               pic14_emitcode ("anl","a,#0x%02x", mask);
+                       if (litval)
+                               pic14_emitcode ("orl","a,#0x%02x", litval);
+        }
+               else
+        {
+                       //bool pushedB;
+                       /* Case with partial byte and arbitrary source
+                       */
+                       MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
+                       pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
+                       
+                       //pushedB = pushB ();
+                       /* transfer A to B and get next byte */
+                       emitPtrByteGet (rname, p_type, TRUE);
+                       
+                       pic14_emitcode ("anl", "a,#0x%02x", mask);
+                       pic14_emitcode ("orl", "a,b");
+                       if (p_type == GPOINTER)
+                               pic14_emitcode ("pop", "b");
+                       
+                       //popB (pushedB);
+        }
+               emitPtrByteSet (rname, p_type, "a");
+    }
+       
+}
+
+/*-----------------------------------------------------------------*/
+/* SetIrp - Set IRP bit                                            */
+/*-----------------------------------------------------------------*/
+void SetIrp(operand *result) {
+       FENTRY;
+       if (AOP_TYPE(result) == AOP_LIT) {
+               unsigned lit = (unsigned)operandLitValue(result);
+               emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
+       } else {
+               if (PCOP(AOP(result))->type == PO_LITERAL) {
+                       int addrs = PCOL(AOP(result))->lit;
+                       emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
+               } else {
+                       emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* 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));
+                               emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
+                       }
+               }
        }
 }
+
 /*-----------------------------------------------------------------*/
 /* 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];
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        aopOp(right,ic,FALSE);
+       aopOp(result,ic,FALSE);
        
-       l = aopGet(AOP(result),0,FALSE,TRUE);
        size = AOP_SIZE(right);
        /*
        if ( AOP_TYPE(result) == AOP_PCODE) {
@@ -8563,36 +9431,20 @@ 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=%i, offset=%i", __FILE__,__LINE__, size, offset);
                
                if (AOP_TYPE(right) == AOP_LIT) {
                        unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
                        lit = lit >> (8*offset);
                        if(lit&0xff) {
-                               pic14_emitcode("movlw","%d",lit);
-                               pic14_emitcode("movwf","%s",buffer);
-                               
                                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 {
                        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++;
@@ -8603,98 +9455,86 @@ 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 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 &&
+       if (AOP_TYPE(result) == AOP_PCODE &&
                DCL_TYPE(ptype) == POINTER   &&
-               !IS_BITFIELD(retype)) {
+               !IS_BITVAR (retype) &&
+               !IS_BITVAR (letype)) {
                genDataPointerSet (right,result,ic);
                freeAsmop(result,NULL,ic,TRUE);
                return;
        }
-       
+
        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);
+       /* Check if can access directly instead of via a pointer */
+       if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
+               direct = 1;
+       }
+
+       /* If the pointer value is not in a the FSR then need to put it in */
+       if (!AOP_INPREG(AOP(result)) && !direct) {
                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));
+               if (PCOP(AOP(result))->type == PO_LITERAL) 
+                       emitpcode(POC_MOVLW, popGet(AOP(result),0));
+               else
+                       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);
-       
-       
-       /* if bitfield then unpack the bits */
-       if (IS_BITFIELD(retype)) {
-               werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                       "The programmer is obviously confused");
-               //genPackBits (retype,right,rname,POINTER);
-               exit(1);
        }
-       else {
+
+       /* 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)
+               SetIrp(result);
+
+       /* if bitfield then unpack the bits */
+       if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
+               genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
+       } else {
                /* 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++;
                }
        }
@@ -8705,10 +9545,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 &&
@@ -8717,14 +9557,13 @@ 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);
 }
@@ -8741,6 +9580,7 @@ static void genPagedPointerSet (operand *right,
        char *rname , *l;
        sym_link *retype;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        retype= getSpec(operandType(right));
@@ -8765,7 +9605,7 @@ static void genPagedPointerSet (operand *right,
        
        /* if bitfield then unpack the bits */
        if (IS_BITFIELD(retype)) 
-               genPackBits (retype,right,rname,PPOINTER);
+               genPackBits (retype,result,right,rname,PPOINTER);
        else {
                /* we have can just get the values */
                int size = AOP_SIZE(right);
@@ -8819,6 +9659,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);
        
@@ -8843,7 +9684,7 @@ static void genFarPointerSet (operand *right,
        
        /* if bit then unpack */
        if (IS_BITFIELD(retype)) 
-               genPackBits(retype,right,"dptr",FPOINTER);
+               genPackBits(retype,result,right,"dptr",FPOINTER);
        else {
                size = AOP_SIZE(right);
                offset = 0 ;
@@ -8866,14 +9707,15 @@ static void genFarPointerSet (operand *right,
 static void genGenPointerSet (operand *right,
                                                          operand *result, iCode *ic)
 {
-       int size, offset ;
+       sym_link *ptype = operandType(result);
        sym_link *retype = getSpec(operandType(right));
+       sym_link *letype = getSpec (ptype);
        
+       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);
        
@@ -8885,84 +9727,43 @@ static void genGenPointerSet (operand *right,
                        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;
-                       
+               else {
+                       emitpcode(POC_MOVFW,popGet(AOP(result),0));
+                       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
+
+                       /* 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. */
+                       SetIrp(result);
                }
        }
-       /* so dptr know contains the address */
-       
-       
-       /* if bit then unpack */
-       if (IS_BITFIELD(retype)) 
-               genPackBits(retype,right,"dptr",GPOINTER);
-       else {
-               size = AOP_SIZE(right);
-               offset = 0 ;
-               
-               DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
+
+       /* if bitfield then unpack the bits */
+       if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
+               genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
+       } else {
+               /* we have can just get the values */
+               int size = AOP_SIZE(right);
+               int offset = 0 ;    
                
+               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
                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));
-                       
+                       char *l = aopGet(AOP(right),offset,FALSE,TRUE);
+                       if (*l == '@' ) {
+                               emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+                       } else {
+                               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));
+                       }
+                       if (size)
+                               emitpcode(POC_INCF,popCopyReg(&pc_fsr));
                        offset++;
                }
        }
        
-release:
        freeAsmop(right,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
@@ -8976,6 +9777,7 @@ static void genPointerSet (iCode *ic)
        sym_link *type, *etype;
        int p_type;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        right = IC_RIGHT(ic);
@@ -9044,6 +9846,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);
@@ -9084,6 +9887,7 @@ static void genAddrOf (iCode *ic)
        operand *right, *result, *left;
        int size, offset ;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        
@@ -9094,6 +9898,27 @@ 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));
        offset = 0;
@@ -9156,6 +9981,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 */
@@ -9170,7 +9996,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) {
                
@@ -9279,6 +10125,7 @@ static void genJumpTab (iCode *ic)
        symbol *jtab;
        char *l;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        aopOp(IC_JTCOND(ic),ic,FALSE);
@@ -9328,6 +10175,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));
@@ -9457,6 +10305,7 @@ static void genCast (iCode *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)))
@@ -9544,9 +10393,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__);
@@ -9613,7 +10462,7 @@ static void genCast (iCode *ic)
                                        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_MOVLW, popGetAddr(AOP(right),offset,0));
                                                emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                                        } else { 
                                                aopPut(AOP(result),
@@ -9727,6 +10576,7 @@ release:
 static int genDjnz (iCode *ic, iCode *ifx)
 {
        symbol *lbl, *lbl1;
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if (!ifx)
@@ -9788,6 +10638,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)) &&
@@ -9825,6 +10676,7 @@ static void genReceive (iCode *ic)
 static void
 genDummyRead (iCode * ic)
 {
+       FENTRY;
        pic14_emitcode ("; genDummyRead","");
        pic14_emitcode ("; not implemented","");
        
@@ -9847,7 +10699,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"));
@@ -9863,28 +10717,23 @@ void genpic14Code (iCode *lic)
        
        for (ic = lic ; ic ; ic = ic->next ) {
                
-               DEBUGpic14_emitcode(";ic","");
-               if ( cln != ic->lineno ) {
-                       if ( options.debug ) {
-                               debugFile->writeCLine (ic);
-                       }
-                       /*
-                       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
@@ -9911,12 +10760,12 @@ 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
-               we need to check for this condition and handle it */
+                       /* IPOP happens only when trying to restore a 
+                       spilt live range, if there is an ifx statement
+                       following this pop then the if statement might
+                       be using some of the registers being popped which
+                       would destory the contents of the register so
+                       we need to check for this condition and handle it */
                        if (ic->next            && 
                                ic->next->op == IFX &&
                                regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
@@ -9986,7 +10835,7 @@ 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");
@@ -10100,3 +10949,27 @@ void genpic14Code (iCode *lic)
        
        return;
 }
+
+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) || (aop->aopu.pcop->type == PO_IMMEDIATE)))
+  {
+    /* 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;
+  return 0;
+}