* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / src / pic / gen.c
index ff785fa63fb57a3a23e1acb0f63462dd4a22f5d3..ac092203ff2f3a87528a1a7ca874d2f6fb4f7d78 100644 (file)
@@ -42,7 +42,6 @@
 #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 *);
@@ -63,7 +62,7 @@ pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
 unsigned int pic14aopLiteral (value *val, int offset);
 const char *AopType(short type);
 
-#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
@@ -78,7 +77,7 @@ char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
 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;
 
@@ -175,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);   
@@ -205,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));
@@ -234,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);   
        
@@ -399,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);
@@ -818,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);
@@ -827,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 
@@ -860,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;
+               }
        }
        
        {
@@ -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));
        
@@ -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 */
@@ -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);
@@ -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)
@@ -2927,6 +3047,8 @@ static void genRet (iCode *ic)
 {
        int size,offset = 0 , pushed = 0;
        
+       FENTRY;
+
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* if we have no return value then
        just generate the "ret" */
@@ -2954,7 +3076,7 @@ static void genRet (iCode *ic)
                                        AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
                                        ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
                                        ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
-                                       emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
+                                       emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                }else {
                                        emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
                                }
@@ -2994,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)
@@ -3009,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);
 }
@@ -3021,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)))
@@ -3045,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);
@@ -3148,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);
@@ -3192,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));
@@ -3216,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;
@@ -3297,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);
@@ -3336,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);
@@ -3359,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)) {
@@ -3431,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);
@@ -3470,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 */
@@ -3514,6 +3653,7 @@ static void genIfxJump (iCode *ic, char *jval)
 /*-----------------------------------------------------------------*/
 static void genSkip(iCode *ifx,int status_bit)
 {
+       FENTRY;
        if(!ifx)
                return;
        
@@ -3564,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;
 }
 
@@ -3581,6 +3723,7 @@ static void genSkipc(resolvedIfx *rifx)
 /*-----------------------------------------------------------------*/
 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
 {
+       FENTRY;
        if(!rifx)
                return;
        
@@ -3598,6 +3741,7 @@ static void genSkipz2(resolvedIfx *rifx, int invert_condition)
 /*-----------------------------------------------------------------*/
 static void genSkipz(iCode *ifx, int condition)
 {
+       FENTRY;
        if(!ifx)
                return;
        
@@ -3617,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;
        
@@ -3634,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
 /*-----------------------------------------------------------------*/
@@ -3664,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                       */
 /*-----------------------------------------------------------------*/
@@ -3675,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) {
@@ -3763,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 {
@@ -3771,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" );
                                        }
                                }
                                
@@ -3822,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;
@@ -3838,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;
@@ -3854,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;
@@ -3902,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);
                                
@@ -3940,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);
 
@@ -4005,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;
@@ -4029,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);
@@ -4099,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;
@@ -4151,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);
                                        
@@ -4193,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);
@@ -4229,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)
@@ -4263,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;
@@ -4297,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;
@@ -4323,6 +4708,7 @@ static void genCmp (operand *left,operand *right,
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genCmpGt :- greater than comparison                             */
@@ -4333,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);
@@ -4362,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);
@@ -4390,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;
@@ -4439,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 
@@ -4477,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));
@@ -4488,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;
@@ -4505,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__);
@@ -4522,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) && 
@@ -4538,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:
@@ -4574,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));
@@ -4599,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"))
@@ -4615,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));
        
@@ -4625,6 +5049,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        
        if(ifx)
                ifx->generated = 1;
+#endif
 }
 
 #if 0
@@ -4659,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)
@@ -4677,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;
@@ -4843,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) {
@@ -4952,6 +5378,7 @@ release:
 /*-----------------------------------------------------------------*/
 static iCode *ifxForOp ( operand *op, iCode *ic )
 {
+       FENTRY;
        /* if true symbol then needs to be assigned */
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if (IS_TRUE_SYMOP(op))
@@ -4998,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
@@ -5049,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);
@@ -5098,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])
@@ -5110,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);
@@ -5121,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);
@@ -5132,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)){
@@ -5159,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);
@@ -5423,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);
@@ -5717,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);
@@ -5782,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");
                                        }
@@ -5958,6 +6394,7 @@ static void genInline (iCode *ic)
 {
   char *buffer, *bp, *bp1;
 
+  FENTRY;
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
   _G.inLine += (!options.asmpeep);
@@ -6004,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);
@@ -6046,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);
@@ -6093,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));
@@ -6116,6 +6556,7 @@ static void genGetHbit (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void AccRol (operand *op,int offset,int shCount)
 {
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        shCount &= 0x0007;              // shCount : 0..7
        switch(shCount){
@@ -6165,31 +6606,19 @@ static void AccRol (operand *op,int offset,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");
+       if(shCount != 0) {
+               if (shCount == 1)
+               {
                        emitCLRC;
-                       emitpcode(POC_RLF,popGet(AOP(op),offset));
+                       emitpcode (POC_RLF, popGet (AOP(op), 0));
                } else {
-                       if(shCount == 2) {
-                               pic14_emitcode("add","a,acc");
-                               emitCLRC;
-                               emitpcode(POC_RLF,popGet(AOP(op),offset));
-                               pic14_emitcode("add","a,acc");
-                               emitCLRC;
-                               emitpcode(POC_RLF,popGet(AOP(op),offset));
-                       } else {
-               */
-               {
-                       {
-                               /* rotate left accumulator */
-                               AccRol(op,offset,shCount);
-                               /* and kill the lower order bits */
-                               pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
-                               emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
-                       }
+                       /* 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));
                }
        }
 }
@@ -6199,16 +6628,18 @@ static void AccLsh (operand *op,int offset,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(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));
                }
        }
 }
@@ -6243,7 +6674,7 @@ static void AccSRsh (int shCount)
                }
        }
 }
-#endif
+
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
 /*-----------------------------------------------------------------*/
@@ -6253,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);
@@ -6364,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);
@@ -6457,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);
@@ -6520,6 +6954,7 @@ static void shiftL1Left2Result (operand *left, int offl,
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* movLeft2Result - move byte from left to result                  */
@@ -6528,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);
@@ -6542,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__);
        
@@ -6669,6 +7293,7 @@ static void shiftL2Left2Result (operand *left, int offl,
        }
        
 }
+
 /*-----------------------------------------------------------------*/
 /* shiftR2Left2Result - shift right two bytes from left to result  */
 /*-----------------------------------------------------------------*/
@@ -6678,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));
        
@@ -6820,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(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))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -6843,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(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))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -6858,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);
 }
@@ -6869,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);
        
@@ -6903,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);
@@ -6963,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);
        
@@ -7038,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              */
 /*-----------------------------------------------------------------*/
@@ -7048,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
@@ -7092,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.
@@ -7103,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)
@@ -7133,6 +7767,7 @@ static void genLeftShift (iCode *ic)
        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 */
@@ -7204,10 +7841,7 @@ static void genLeftShift (iCode *ic)
                        
                        tlbl = newiTempLabel(NULL);
                        if (!pic14_sameRegs(AOP(left),AOP(result))) {
-                               if (AOP_TYPE(left) == AOP_LIT)
-                                       emitpcode(POC_MOVLW,  popGetLit(lit));
-                               else
-                                       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
+                               mov2w (AOP(left), 0);
                                emitpcode(POC_MOVWF,  popGet(AOP(result),0));
                        }
                        
@@ -7297,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);
 }
@@ -7313,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) {
@@ -7343,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7376,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 ) {
@@ -7441,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);
        
@@ -7459,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)){
@@ -7504,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              */
@@ -7524,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);
@@ -7536,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 
@@ -7660,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)));
@@ -7682,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 ;
        }
        
@@ -7698,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 */
@@ -7779,6 +8427,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
        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));
@@ -7792,7 +8441,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
                        resolvedIfx rIfx;
                        resolveIfx(&rIfx,ifx);
                        if (ptype == -1) /* direct */
-                               pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
+                               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);
@@ -7800,23 +8449,29 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
                        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(AOP(left)->aopu.pcop->name,bstr,0);
+                               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(AOP(result)->aopu.pcop->name,bstr,0));
-
-                       if (ptype == -1) /* direct */
-                               pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
-                       else
-                               pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
-                       emitpcode(POC_BTFSS,pcop);
-                       emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
+                       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) {
                
@@ -7910,17 +8565,17 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
        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__);
        
        
@@ -7928,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++;
        }
@@ -7959,7 +8618,7 @@ static void genNearPointerGet (operand *left,
        sym_link *retype= getSpec(rtype);      /* bitfield type information */
        int direct = 0;
 
-       
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        
@@ -7972,7 +8631,7 @@ 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 ;
        }
        
@@ -7988,7 +8647,7 @@ static void genNearPointerGet (operand *left,
        if (!AOP_INPREG(AOP(left)) && !direct) {
                /* otherwise get a free pointer register */
                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               if (PCOP(AOP(result))->type == PO_LITERAL) 
+               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));
@@ -8063,6 +8722,7 @@ static void genPagedPointerGet (operand *left,
        char *rname ;
        sym_link *rtype, *retype;    
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        rtype = operandType(result);
@@ -8141,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);
@@ -8242,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);
@@ -8293,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);
@@ -8336,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);
@@ -8404,11 +9115,14 @@ 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;
        }
        
 }
@@ -8422,7 +9136,8 @@ static void genPointerGet (iCode *ic)
 static void
 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
 {
-       switch (p_type)
+    FENTRY;
+    switch (p_type)
     {
     case IPOINTER:
     case POINTER:
@@ -8471,7 +9186,8 @@ emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
 static void
 emitPtrByteSet (char *rname, int p_type, char *src)
 {
-       switch (p_type)
+    FENTRY;
+    switch (p_type)
     {
     case IPOINTER:
     case POINTER:
@@ -8513,7 +9229,8 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,char *rna
        int bstr;             /* bitfield starting bit within byte */
        int litval;           /* source literal value (if AOP_LIT) */
        unsigned char mask;   /* bitmask within current byte */
-       
+
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        blen = SPEC_BLEN (etype);
@@ -8534,7 +9251,7 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,char *rna
                                if (p_type == -1) {
                                        pCodeOp *pcop;
                                        if (AOP(result)->type == AOP_PCODE)
-                                               pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
+                                               pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
                                        else
                                                pcop = popGet(AOP(result),0);
                                        emitpcode(lit?POC_BSF:POC_BCF,pcop);
@@ -8560,11 +9277,12 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,char *rna
                        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_RLF,popGet(AOP(right),0));
+                                       emitpcode(POC_RRFW,popGet(AOP(right),0));
                                        emitSKPC;
-                                       emitpcode(POC_BCF,popGet(AOP(result),0));
+                                       emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
                                        emitSKPNC;
-                                       emitpcode(POC_BSF,popGet(AOP(result),0));
+                                       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
                                        */
@@ -8670,6 +9388,7 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,char *rna
 /* 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));
@@ -8691,16 +9410,16 @@ void SetIrp(operand *result) {
 /* 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) {
@@ -8712,24 +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) {
                                emitpcode(POC_MOVLW, popGetLit(lit&0xff));
-                               emitpcode(POC_MOVWF, popGet(AOP(result),0));
+                               emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                        } else {
-                               emitpcode(POC_CLRF, popGet(AOP(result),0));
+                               emitpcode(POC_CLRF, popGet(AOP(result),offset));
                        }
                } else {
                        emitpcode(POC_MOVFW, popGet(AOP(right),offset));
-                       emitpcode(POC_MOVWF, popGet(AOP(result),0));
+                       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                }
                
                offset++;
@@ -8753,6 +9468,7 @@ static void genNearPointerSet (operand *right,
        int direct = 0;
        
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        aopOp(result,ic,FALSE);
        
@@ -8864,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));
@@ -8942,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);
        
@@ -8993,6 +9711,7 @@ static void genGenPointerSet (operand *right,
        sym_link *retype = getSpec(operandType(right));
        sym_link *letype = getSpec (ptype);
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        aopOp(result,ic,FALSE);
@@ -9058,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);
@@ -9126,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);
@@ -9166,6 +9887,7 @@ static void genAddrOf (iCode *ic)
        operand *right, *result, *left;
        int size, offset ;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        
@@ -9176,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;
@@ -9238,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 */
@@ -9252,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) {
                
@@ -9361,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);
@@ -9410,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));
@@ -9539,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)))
@@ -9626,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__);
@@ -9695,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),
@@ -9809,6 +10576,7 @@ release:
 static int genDjnz (iCode *ic, iCode *ifx)
 {
        symbol *lbl, *lbl1;
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if (!ifx)
@@ -9870,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)) &&
@@ -9907,6 +10676,7 @@ static void genReceive (iCode *ic)
 static void
 genDummyRead (iCode * ic)
 {
+       FENTRY;
        pic14_emitcode ("; genDummyRead","");
        pic14_emitcode ("; not implemented","");
        
@@ -9929,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"));
@@ -9945,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
@@ -10182,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;
+}