* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / src / pic / gen.c
index c85d097f1eb5c2d2303276e3fa37c1ebe57c5bf8..ac092203ff2f3a87528a1a7ca874d2f6fb4f7d78 100644 (file)
@@ -77,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;
 
@@ -174,7 +174,7 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
 {
        va_list ap;
        char lb[INITIAL_INLINEASM];  
-       char *lbp = lb;
+       unsigned char *lbp = lb;
        
        if(!debug_verbose && !options.debug)
                return;
@@ -246,7 +246,10 @@ 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));
@@ -269,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);   
        
@@ -434,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);
@@ -853,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);
@@ -862,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 
@@ -895,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;
+               }
        }
        
        {
@@ -1352,8 +1364,13 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        /* offset is greater than
        size then zero */
 
-       assert (offset >= 0 && offset < aop->size);
+       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;
@@ -1439,7 +1456,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
                        __LINE__, 
                        ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
-               emitpComment ("popGet; name %s, offset: %i\n", aop->aopu.pcop->name, 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:
@@ -1469,19 +1486,19 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 /* 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)
+pCodeOp *popGetAddr (asmop *aop, int offset, int index)
 {
   if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
   {
     pCodeOp *pcop = aop->aopu.pcop;
-    emitpComment ("popGet; name %s, offset: %i\n", pcop->name, offset);
     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);
+    return popGet (aop, offset + index);
   }
 }
 
@@ -1727,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));
        
@@ -1888,7 +1903,7 @@ void pic14_toBoolean(operand *oper)
 /*-----------------------------------------------------------------*/
 static void genNot (iCode *ic)
 {
-       symbol *tlbl;
+       //symbol *tlbl;
        int size;
 
        FENTRY;
@@ -1912,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 */
@@ -2598,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);
@@ -3060,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, popGetAddr(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));
                                }
@@ -3693,11 +3709,12 @@ static void genSkipc(resolvedIfx *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;
 }
 
@@ -3744,6 +3761,8 @@ static void genSkipz(iCode *ifx, int condition)
                pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
        
 }
+
+#if 0
 /*-----------------------------------------------------------------*/
 /* genSkipCond                                                     */
 /*-----------------------------------------------------------------*/
@@ -3762,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
 /*-----------------------------------------------------------------*/
@@ -3792,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                       */
 /*-----------------------------------------------------------------*/
@@ -3893,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 {
@@ -3901,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" );
                                        }
                                }
                                
@@ -3952,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;
@@ -3968,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;
@@ -3984,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;
@@ -4032,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);
                                
@@ -4070,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);
 
@@ -4135,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;
@@ -4159,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);
@@ -4229,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;
@@ -4281,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);
                                        
@@ -4323,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);
@@ -4359,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)
@@ -4393,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;
@@ -4427,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;
@@ -4453,6 +4708,7 @@ static void genCmp (operand *left,operand *right,
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genCmpGt :- greater than comparison                             */
@@ -4529,7 +4785,6 @@ static void genc16bit2lit(operand *op, int lit, int offset)
        else
                i=0;
        
-       emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
        switch( BYTEofLONG(lit,i)) { 
        case 0:
                emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
@@ -4547,7 +4802,6 @@ static void genc16bit2lit(operand *op, int lit, int offset)
        
        i ^= 1;
        
-       emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
        switch( BYTEofLONG(lit,i)) { 
        case 0:
                emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
@@ -4574,21 +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 
@@ -4613,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));
@@ -4624,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;
@@ -4641,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__);
@@ -4658,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) && 
@@ -4674,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:
@@ -4710,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));
@@ -4735,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"))
@@ -4751,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));
        
@@ -4761,6 +5049,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        
        if(ifx)
                ifx->generated = 1;
+#endif
 }
 
 #if 0
@@ -4814,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;
@@ -4980,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) {
@@ -5928,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");
                                        }
@@ -6318,30 +6608,17 @@ 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));
                }
        }
 }
@@ -6355,13 +6632,14 @@ static void AccRsh (operand *op,int offset,int shCount)
        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));
                }
        }
 }
@@ -6396,7 +6674,7 @@ static void AccSRsh (int shCount)
                }
        }
 }
-#endif
+
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
 /*-----------------------------------------------------------------*/
@@ -6676,6 +6954,7 @@ static void shiftL1Left2Result (operand *left, int offl,
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* movLeft2Result - move byte from left to result                  */
@@ -6699,6 +6978,194 @@ 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   */
 /*-----------------------------------------------------------------*/
@@ -6826,6 +7293,7 @@ static void shiftL2Left2Result (operand *left, int offl,
        }
        
 }
+
 /*-----------------------------------------------------------------*/
 /* shiftR2Left2Result - shift right two bytes from left to result  */
 /*-----------------------------------------------------------------*/
@@ -6978,7 +7446,6 @@ static void shiftR2Left2Result (operand *left, int offl,
   }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
 /*-----------------------------------------------------------------*/
@@ -6987,13 +7454,12 @@ static void shiftLLeftOrResult (operand *left, int offl,
 {
        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))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -7004,13 +7470,12 @@ static void shiftRLeftOrResult (operand *left, int offl,
 {
        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))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -7202,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              */
 /*-----------------------------------------------------------------*/
@@ -7212,7 +7679,7 @@ 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__);
@@ -7220,7 +7687,7 @@ static void genLeftShiftLiteral (operand *left,
        
        aopOp(left,ic,FALSE);
        aopOp(result,ic,FALSE);
-       
+
        size = getSize(operandType(result));
        
 #if VIEW_SIZE
@@ -7257,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.
@@ -7307,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 ;
        }
        
@@ -7321,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 */
@@ -7371,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));
                        }
                        
@@ -7464,6 +7931,7 @@ release:
        freeAsmop(result,NULL,ic,TRUE);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genrshOne - right shift a one byte quantity by known count      */
 /*-----------------------------------------------------------------*/
@@ -7512,32 +7980,35 @@ static void genrshTwo (operand *result,operand *left,
 static void shiftRLong (operand *left, int offl,
                                                operand *result, int sign)
 {
+       int size, same;
+       
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       if(!sign)
-               pic14_emitcode("clr","c");
-       MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
-       if(sign)
-               pic14_emitcode("mov","c,acc.7");
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB32-offl);
-       if(offl == MSB16)
-               /* add sign of "a" */
-               addSign(result, MSB32, sign);
-       
-       MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB24-offl);
        
-       MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB16-offl);
+       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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7631,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)){
@@ -7676,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              */
@@ -7709,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 
@@ -7856,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 ;
        }
        
@@ -7872,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 */
@@ -7967,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);
@@ -7975,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) {
                
@@ -8167,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));
@@ -8475,9 +8955,9 @@ 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;
@@ -8485,28 +8965,75 @@ static void genConstPointerGet (operand *left,
        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);
@@ -8519,7 +9046,7 @@ 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__);
@@ -8588,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;
        }
        
 }
@@ -8721,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);
@@ -8747,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
                                        */
@@ -8883,13 +9414,12 @@ static void genDataPointerSet(operand *right,
        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) {
@@ -8902,11 +9432,6 @@ static void genDataPointerSet(operand *right,
        // tsd, was l+1 - the underline `_' prefix was being stripped
        while (size--) {
                emitpComment ("%s:%u: size=%i, offset=%i", __FILE__,__LINE__, size, offset);
-               if (offset) {
-                       sprintf(buffer,"(%s + %d)",l,offset);
-                       fprintf(stderr,"%s:%i: oops  %s (%i, AOP_LIT=%i)\n",__FILE__,__LINE__,buffer, AOP_TYPE(right), AOP_LIT);
-               } else
-                       sprintf(buffer,"%s",l);
                
                if (AOP_TYPE(right) == AOP_LIT) {
                        unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
@@ -9373,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;
@@ -9450,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) {
                
@@ -9827,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, popGetAddr(AOP(right),0));
+                       emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
                        emitpcode(POC_MOVWF, popGet(AOP(result),0));
-                       emitpcode(POC_MOVLW, popGetAddr(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__);
@@ -9896,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, popGetAddr(AOP(right),offset));
+                                               emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset,0));
                                                emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                                        } else { 
                                                aopPut(AOP(result),
@@ -10133,6 +10699,7 @@ void genpic14Code (iCode *lic)
 {
        iCode *ic;
        int cln = 0;
+       const char *cline;
        
        FENTRY;
        lineHead = lineCurr = NULL;
@@ -10158,7 +10725,10 @@ void genpic14Code (iCode *lic)
                if (!options.noCcodeInAsm && (cln != ic->lineno)) {
                  cln = ic->lineno;
                  //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
-                 emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, printCLine (ic->filename, cln));
+                 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) {
@@ -10379,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;
+}