- Parameter passing now works
[fw/sdcc] / src / pic / gen.c
index 265e9fc0a6d9cb73ff883477711c0062e481f31c..912840c41aaf20da8414c9e93615977b659af77a 100644 (file)
 #include "pcode.h"
 #include "gen.h"
 
+/*
+  if(IC_RESULT(ic) && AOP(IC_RESULT(ic)))
+    DEBUGpic14_emitcode ("; ","result %s",
+                        AopType(AOP_TYPE(IC_RESULT(ic))));
+
+  if(IC_LEFT(ic) && AOP(IC_LEFT(ic)))
+    DEBUGpic14_emitcode ("; ","left %s",
+                      AopType(AOP_TYPE(IC_LEFT(ic))));
+
+  if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic)))
+    DEBUGpic14_emitcode ("; ","right %s",
+                      AopType(AOP_TYPE(IC_RIGHT(ic))));
+*/
+
+
 static int labelOffset=0;
 static int debug_verbose=1;
 static int optimized_for_speed = 0;
 
+/* max_key keeps track of the largest label number used in 
+   a function. This is then used to adjust the label offset
+   for the next function.
+*/
+static int max_key=0;
+static int GpsuedoStkPtr=0;
+
 unsigned int pic14aopLiteral (value *val, int offset);
+const char *AopType(short type);
+
+#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
 
 /* this is the down and dirty file with all kinds of 
    kludgy & hacky stuff. This is what it is all about
@@ -93,7 +118,15 @@ static struct {
     set *sendSet;
 } _G;
 
-char *Safe_strdup(char *str);  // in pcode.c
+/* Resolved ifx structure. This structure stores information
+   about an iCode ifx that makes it easier to generate code.
+*/
+typedef struct resolvedIfx {
+  symbol *lbl;     /* pointer to a label */
+  int condition;   /* true or false ifx */
+  int generated;   /* set true when the code associated with the ifx
+                   * is generated */
+} resolvedIfx;
 
 extern int pic14_ptrRegReq ;
 extern int pic14_nRegs;
@@ -135,26 +168,15 @@ static int my_powof2 (unsigned long num)
   return -1;
 }
 
-static void emitpLabel(int key)
-{
-  addpCode2pBlock(pb,newpCodeLabel(key));
-}
-
-void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
-{
-
-  addpCode2pBlock(pb,newpCode(poc,pcop));
-
-}
-/*-----------------------------------------------------------------*/
-/* pic14_emitcode - writes the code into a file : for now it is simple    */
-/*-----------------------------------------------------------------*/
-void pic14_emitcode (char *inst,char *fmt, ...)
+void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
 {
     va_list ap;
     char lb[INITIAL_INLINEASM];  
     char *lbp = lb;
 
+    if(!debug_verbose)
+      return;
+
     va_start(ap,fmt);   
 
     if (inst && *inst) {
@@ -175,21 +197,42 @@ void pic14_emitcode (char *inst,char *fmt, ...)
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
 
-    if(debug_verbose)
-      addpCode2pBlock(pb,newpCodeCharP(lb));
+    addpCode2pBlock(pb,newpCodeCharP(lb));
 
     va_end(ap);
 }
 
-void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
+
+static void emitpLabel(int key)
+{
+  addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
+}
+
+void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+{
+
+  if(pcop)
+    addpCode2pBlock(pb,newpCode(poc,pcop));
+  else
+    DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
+}
+
+void emitpcodeNULLop(PIC_OPCODE poc)
+{
+
+  addpCode2pBlock(pb,newpCode(poc,NULL));
+
+}
+
+/*-----------------------------------------------------------------*/
+/* pic14_emitcode - writes the code into a file : for now it is simple    */
+/*-----------------------------------------------------------------*/
+void pic14_emitcode (char *inst,char *fmt, ...)
 {
     va_list ap;
     char lb[INITIAL_INLINEASM];  
     char *lbp = lb;
 
-    if(!debug_verbose)
-      return;
-
     va_start(ap,fmt);   
 
     if (inst && *inst) {
@@ -210,7 +253,8 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
 
-    addpCode2pBlock(pb,newpCodeCharP(lb));
+    if(debug_verbose)
+      addpCode2pBlock(pb,newpCodeCharP(lb));
 
     va_end(ap);
 }
@@ -325,6 +369,40 @@ static void genSetDPTR(int n)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* resolveIfx - converts an iCode ifx into a form more useful for  */
+/*              generating code                                    */
+/*-----------------------------------------------------------------*/
+static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
+{
+  if(!resIfx) 
+    return;
+
+  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+  resIfx->condition = 1;    /* assume that the ifx is true */
+  resIfx->generated = 0;    /* indicate that the ifx has not been used */
+
+  if(!ifx) {
+    resIfx->lbl = 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);
+  } else {
+    if(IC_TRUE(ifx)) {
+      resIfx->lbl = IC_TRUE(ifx);
+    } else {
+      resIfx->lbl = IC_FALSE(ifx);
+      resIfx->condition = 0;
+    }
+    if(IC_TRUE(ifx)) 
+      DEBUGpic14_emitcode("; ***","ifx true is non-null");
+    if(IC_FALSE(ifx)) 
+      DEBUGpic14_emitcode("; ***","ifx false is non-null");
+  }
+
+  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
+
+}
 /*-----------------------------------------------------------------*/
 /* pointerCode - returns the code for a pointer type               */
 /*-----------------------------------------------------------------*/
@@ -492,6 +570,17 @@ static asmop *aopForRemat (symbol *sym)
     return aop;        
 }
 
+int aopIdx (asmop *aop, int offset)
+{
+  if(!aop)
+    return -1;
+
+  if(aop->type !=  AOP_REG)
+    return -2;
+       
+  return aop->aopu.aop_reg[offset]->rIdx;
+
+}
 /*-----------------------------------------------------------------*/
 /* regsInCommon - two operands have some registers in common       */
 /*-----------------------------------------------------------------*/
@@ -962,6 +1051,12 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
 /*-----------------------------------------------------------------*/
 pCodeOp *popGetLabel(unsigned int key)
 {
+
+  DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
+
+  if(key>max_key)
+    max_key = key;
+
   return newpCodeOpLabel(key+100+labelOffset);
 }
 
@@ -1044,6 +1139,25 @@ pCodeOp *popRegFromString(char *str)
   return pcop;
 }
 
+pCodeOp *popRegFromIdx(int rIdx)
+{
+  pCodeOp *pcop;
+
+  DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
+                      __FUNCTION__,__LINE__,rIdx);
+
+  pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+
+  PCOR(pcop)->rIdx = rIdx;
+  PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+  PCOR(pcop)->r->isFree = 0;
+  PCOR(pcop)->r->wasUsed = 1;
+
+  pcop->type = PCOR(pcop)->r->pc_type;
+
+
+  return pcop;
+}
 /*-----------------------------------------------------------------*/
 /* popGet - asm operator to pcode operator conversion              */
 /*-----------------------------------------------------------------*/
@@ -1070,17 +1184,17 @@ pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
     case AOP_DPTR:
     case AOP_DPTR2:
     case AOP_ACC:
-        DEBUGpic14_emitcode(";8051 legacy","%d",__LINE__);
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       pcop->type = PO_SFR_REGISTER;
+        DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
+       //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+       //pcop->type = PO_SFR_REGISTER;
 
-       PCOR(pcop)->rIdx = -1;
-       PCOR(pcop)->r = NULL;
+       //PCOR(pcop)->rIdx = -1;
+       //PCOR(pcop)->r = NULL;
        // Really nasty hack to check for temporary registers
 
-       pcop->name = Safe_strdup("BAD_REGISTER");
+       //pcop->name = Safe_strdup("BAD_REGISTER");
 
-       return pcop;
+       return NULL;
        
     case AOP_IMMD:
       DEBUGpic14_emitcode(";","%d",__LINE__);
@@ -1117,7 +1231,7 @@ pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
       {
        int rIdx = aop->aopu.aop_reg[offset]->rIdx;
 
-       DEBUGpic14_emitcode(";","%d",__LINE__);
+       DEBUGpic14_emitcode(";","%d, rIdx=0x%x",__LINE__,rIdx);
        if(bit16)
          pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
        else
@@ -1513,8 +1627,10 @@ int pic14_getDataSize(operand *op)
 /*-----------------------------------------------------------------*/
 void pic14_outAcc(operand *result)
 {
-    int size, offset;
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+    DEBUGpic14_emitcode ("; ***","%s  %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
+
+#if 0
     size = pic14_getDataSize(result);
     if(size){
         aopPut(AOP(result),"a",0);
@@ -1525,6 +1641,7 @@ void pic14_outAcc(operand *result)
             aopPut(AOP(result),zero,offset++);
         }
     }
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -1747,7 +1864,7 @@ static void saveRegisters(iCode *lic)
     int i;
     iCode *ic;
     bitVect *rsave;
-    sym_link *detype;
+    sym_link *dtype;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* look for call */
@@ -1762,7 +1879,7 @@ static void saveRegisters(iCode *lic)
 
     /* if the registers have been saved already then
     do nothing */
-    if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
+    if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
         return ;
 
     /* find the registers in use at this time 
@@ -1794,13 +1911,13 @@ static void saveRegisters(iCode *lic)
                pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
        }
 
-    detype = getSpec(operandType(IC_LEFT(ic)));
-    if (detype        && 
-        (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
-       IS_ISR(currFunc->etype) &&
+    dtype = operandType(IC_LEFT(ic));
+    if (dtype        && 
+        (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
+       IFFUNC_ISISR(currFunc->type) &&
         !ic->bankSaved) 
 
-        saverbank(SPEC_BANK(detype),ic,TRUE);
+        saverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
 }
 /*-----------------------------------------------------------------*/
@@ -1847,6 +1964,7 @@ static void unsaveRegisters (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void pushSide(operand * oper, int size)
 {
+#if 0
        int offset = 0;
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        while (size--) {
@@ -1859,6 +1977,7 @@ static void pushSide(operand * oper, int size)
                } else
                        pic14_emitcode("push","%s",l);
        }
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -1866,21 +1985,29 @@ static void pushSide(operand * oper, int size)
 /*-----------------------------------------------------------------*/
 static void assignResultValue(operand * oper)
 {
-       int offset = 0;
-       int size = AOP_SIZE(oper);
+  int offset = 0;
+  int size = AOP_SIZE(oper);
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    // The last byte in the assignment is in W
-    aopPut(AOP(oper),"W",size-1);
+  if(!GpsuedoStkPtr) {
+    /* The last byte in the assignment is in W */
+    //aopPut(AOP(oper),"W",size-1);
+    emitpcode(POC_MOVWF, popGet(AOP(oper),0,FALSE,FALSE));
+    GpsuedoStkPtr++;
+    if(size == 1)
+      return;
+    size--;
+    offset++;
+  }
 
-    if(size>1) {
-      while (--size) {
-       aopPut(AOP(oper),fReturn[offset],offset);
-       offset++;
+  while (size--) {
+    emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
+    emitpcode(POC_MOVWF, popGet(AOP(oper),offset,FALSE,FALSE));
+    offset++;
+    GpsuedoStkPtr++;
 
-      }
-    }
+  }
 }
 
 
@@ -2102,105 +2229,133 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
-    sym_link *detype;   
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  sym_link *dtype;   
 
-    /* if caller saves & we have not saved then */
-    if (!ic->regsSaved)
-        saveRegisters(ic);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    /* if we are calling a function that is not using
-    the same register bank then we need to save the
-    destination registers on the stack */
-    detype = getSpec(operandType(IC_LEFT(ic)));
-    if (detype        && 
-        (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
-       IS_ISR(currFunc->etype) &&
-        !ic->bankSaved) 
+  /* if caller saves & we have not saved then */
+  if (!ic->regsSaved)
+    saveRegisters(ic);
 
-        saverbank(SPEC_BANK(detype),ic,TRUE);
+  /* if we are calling a function that is not using
+     the same register bank then we need to save the
+     destination registers on the stack */
+  dtype = operandType(IC_LEFT(ic));
+  if (dtype        && 
+      (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
+      IFFUNC_ISISR(currFunc->type) &&
+      !ic->bankSaved) 
 
-    /* if send set is not empty the assign */
-    if (_G.sendSet) {
-       iCode *sic ;
+    saverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
-       for (sic = setFirstItem(_G.sendSet) ; sic ; 
-            sic = setNextItem(_G.sendSet)) {
-           int size, offset = 0;
+  /* if send set is not empty the assign */
+  if (_G.sendSet) {
+    iCode *sic;
+    /* For the Pic port, there is no data stack.
+     * So parameters passed to functions are stored
+     * in registers. (The pCode optimizer will get
+     * rid of most of these :).
+     */
+    int psuedoStkPtr=0; 
+    int firstTimeThruLoop = 1;
 
-           aopOp(IC_LEFT(sic),sic,FALSE);
-           size = AOP_SIZE(IC_LEFT(sic));
-           while (size--) {
-               char *l = aopGet(AOP(IC_LEFT(sic)),offset,
-                               FALSE,FALSE);
-               DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
+    for (sic = setFirstItem(_G.sendSet) ; sic ; 
+        sic = setNextItem(_G.sendSet)) {
+      int size, offset = 0;
 
-               if (strcmp(l,fReturn[offset])) {
+      aopOp(IC_LEFT(sic),sic,FALSE);
+      size = AOP_SIZE(IC_LEFT(sic));
 
-                 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
-                      ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
-                   emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
-                 //pic14_emitcode("movlw","%s",l);
-                 else
-                   emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
-                 //pic14_emitcode("movf","%s,w",l);
 
-                 // The last one is passed in W
-                 if(size)
-                   pic14_emitcode("movwf","%s",fReturn[offset]);
-               }
-               offset++;
-           }
-           freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+      while (size--) {
+       char *l = aopGet(AOP(IC_LEFT(sic)),offset,
+                        FALSE,FALSE);
+       DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
+                            AopType(AOP_TYPE(IC_LEFT(sic))));
+
+       if(!firstTimeThruLoop) {
+         /* If is not the first time we've been through the loop
+          * then we need to save the parameter in a temporary
+          * register. The last byte of the last parameter is
+          * passed in W. */
+         pic14_emitcode("movwf","%s",fReturn[offset]);
+         emitpcode(POC_MOVWF,popRegFromIdx(psuedoStkPtr + Gstack_base_addr));
+         psuedoStkPtr++;
+         DEBUGpic14_emitcode ("; ","%d save param in %d",__LINE__,
+                              psuedoStkPtr+Gstack_base_addr);
        }
-       _G.sendSet = NULL;
-    }
-    /* make the call */
-    emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
-                                       OP_SYMBOL(IC_LEFT(ic))->rname :
-                                       OP_SYMBOL(IC_LEFT(ic))->name));
+       firstTimeThruLoop=0;
 
-    pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
-                           OP_SYMBOL(IC_LEFT(ic))->rname :
-                           OP_SYMBOL(IC_LEFT(ic))->name));
+       if (strcmp(l,fReturn[offset])) {
 
-    /* if we need assign a result value */
-    if ((IS_ITEMP(IC_RESULT(ic)) && 
-         (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
-          OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
-        IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+         if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
+              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
+           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
+         //pic14_emitcode("movlw","%s",l);
+         else
+           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
+         //pic14_emitcode("movf","%s,w",l);
 
-        _G.accInUse++;
-        aopOp(IC_RESULT(ic),ic,FALSE);
-        _G.accInUse--;
+         /* The last one is passed in W but all others are passed on 
+            the psuedo stack */
+         /*
+         if(size) {
+           pic14_emitcode("movwf","%s",fReturn[offset]);
+           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
+         }
+         */
+       }
+       offset++;
+      }
+      freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+    }
+    _G.sendSet = NULL;
+  }
+  /* make the call */
+  emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
+                                     OP_SYMBOL(IC_LEFT(ic))->rname :
+                                     OP_SYMBOL(IC_LEFT(ic))->name));
+
+  GpsuedoStkPtr=0;
+  /* if we need assign a result value */
+  if ((IS_ITEMP(IC_RESULT(ic)) && 
+       (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+       OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
+      IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+
+    _G.accInUse++;
+    aopOp(IC_RESULT(ic),ic,FALSE);
+    _G.accInUse--;
 
-       assignResultValue(IC_RESULT(ic));
+    assignResultValue(IC_RESULT(ic));
+
+    DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
+                        AopType(AOP_TYPE(IC_RESULT(ic))));
                
-        freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
-    }
+    freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
+  }
 
-    /* adjust the stack for parameters if 
-    required */
-    if (ic->parmBytes) {
-        int i;
-        if (ic->parmBytes > 3) {
-            pic14_emitcode("mov","a,%s",spname);
-            pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
-            pic14_emitcode("mov","%s,a",spname);
-        } else 
-            for ( i = 0 ; i <  ic->parmBytes ;i++)
-                pic14_emitcode("dec","%s",spname);
+  /* adjust the stack for parameters if 
+     required */
+  if (ic->parmBytes) {
+    int i;
+    if (ic->parmBytes > 3) {
+      pic14_emitcode("mov","a,%s",spname);
+      pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
+      pic14_emitcode("mov","%s,a",spname);
+    } else 
+      for ( i = 0 ; i <  ic->parmBytes ;i++)
+       pic14_emitcode("dec","%s",spname);
 
-    }
+  }
 
-    /* if register bank was saved then pop them */
-    if (ic->bankSaved)
-        unsaverbank(SPEC_BANK(detype),ic,TRUE);
+  /* if register bank was saved then pop them */
+  if (ic->bankSaved)
+    unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
-    /* if we hade saved some registers then unsave them */
-    if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
-        unsaveRegisters (ic);
+  /* if we hade saved some registers then unsave them */
+  if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
+    unsaveRegisters (ic);
 
 
 }
@@ -2210,7 +2365,7 @@ static void genCall (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genPcall (iCode *ic)
 {
-    sym_link *detype;
+    sym_link *dtype;
     symbol *rlbl = newiTempLabel(NULL);
 
 
@@ -2222,11 +2377,11 @@ static void genPcall (iCode *ic)
     /* if we are calling a function that is not using
     the same register bank then we need to save the
     destination registers on the stack */
-    detype = getSpec(operandType(IC_LEFT(ic)));
-    if (detype        && 
-       IS_ISR(currFunc->etype) &&
-        (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
-        saverbank(SPEC_BANK(detype),ic,TRUE);
+    dtype = operandType(IC_LEFT(ic));
+    if (dtype        && 
+       IFFUNC_ISISR(currFunc->type) &&
+        (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
+        saverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
 
     /* push the return address on to the stack */
@@ -2305,10 +2460,9 @@ static void genPcall (iCode *ic)
     }
 
     /* if register bank was saved then unsave them */
-    if (detype        && 
-        (SPEC_BANK(currFunc->etype) != 
-         SPEC_BANK(detype)))
-        unsaverbank(SPEC_BANK(detype),ic,TRUE);
+    if (dtype        && 
+        (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
+        unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
     /* if we hade saved some registers then
     unsave them */
@@ -2367,11 +2521,13 @@ static bool inExcludeList(char *s)
 static void genFunction (iCode *ic)
 {
     symbol *sym;
-    sym_link *fetype;
+    sym_link *ftype;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    labelOffset += FUNCTION_LABEL_INC;
+    DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
 
+    labelOffset += (max_key+4);
+    max_key=0;
+    GpsuedoStkPtr=0;
     _G.nRegsSaved = 0;
     /* create the function header */
     pic14_emitcode(";","-----------------------------------------");
@@ -2381,19 +2537,19 @@ static void genFunction (iCode *ic)
     pic14_emitcode("","%s:",sym->rname);
     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
 
-    fetype = getSpec(operandType(IC_LEFT(ic)));
+    ftype = operandType(IC_LEFT(ic));
 
     /* if critical function then turn interrupts off */
-    if (SPEC_CRTCL(fetype))
+    if (IFFUNC_ISCRITICAL(ftype))
         pic14_emitcode("clr","ea");
 
     /* here we need to generate the equates for the
        register bank if required */
 #if 0
-    if (SPEC_BANK(fetype) != rbank) {
+    if (FUNC_REGBANK(ftype) != rbank) {
         int i ;
 
-        rbank = SPEC_BANK(fetype);
+        rbank = FUNC_REGBANK(ftype);
         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
             if (strcmp(regspic14[i].base,"0") == 0)
                 pic14_emitcode("","%s = 0x%02x",
@@ -2410,7 +2566,7 @@ static void genFunction (iCode *ic)
 
     /* if this is an interrupt service routine then
     save acc, b, dpl, dph  */
-    if (IS_ISR(sym->etype)) {
+    if (IFFUNC_ISISR(sym->type)) {
         
        if (!inExcludeList("acc"))          
            pic14_emitcode ("push","acc");      
@@ -2437,12 +2593,12 @@ static void genFunction (iCode *ic)
        /* if this isr has no bank i.e. is going to
           run with bank 0 , then we need to save more
           registers :-) */
-       if (!SPEC_BANK(sym->etype)) {
+       if (!FUNC_REGBANK(sym->type)) {
 
            /* if this function does not call any other
               function then we can be economical and
               save only those registers that are used */
-           if (! sym->hasFcall) {
+           if (! IFFUNC_HASFCALL(sym->type)) {
                int i;
 
                /* if any registers used */
@@ -2465,7 +2621,7 @@ static void genFunction (iCode *ic)
     } else {
        /* if callee-save to be used for this function
           then save the registers being used in this function */
-       if (sym->calleeSave) {
+       if (IFFUNC_CALLEESAVES(sym->type)) {
            int i;
            
            /* if any registers used */
@@ -2483,12 +2639,12 @@ static void genFunction (iCode *ic)
     }
 
     /* set the register bank to the desired value */
-    if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
+    if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
         pic14_emitcode("push","psw");
-        pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);   
+        pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
     }
 
-    if (IS_RENT(sym->etype) || options.stackAuto) {
+    if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
 
        if (options.useXstack) {
            pic14_emitcode("mov","r0,%s",spname);
@@ -2541,7 +2697,7 @@ static void genEndFunction (iCode *ic)
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    if (IS_RENT(sym->etype) || options.stackAuto)
+    if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
     {
         pic14_emitcode ("mov","%s,_bp",spname);
     }
@@ -2556,7 +2712,7 @@ static void genEndFunction (iCode *ic)
     }
 
 
-    if ((IS_RENT(sym->etype) || options.stackAuto)) {
+    if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
        if (options.useXstack) {
            pic14_emitcode("mov","r0,%s",spname);
            pic14_emitcode("movx","a,@r0");
@@ -2570,21 +2726,21 @@ static void genEndFunction (iCode *ic)
     }
 
     /* restore the register bank  */    
-    if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
+    if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
         pic14_emitcode ("pop","psw");
 
-    if (IS_ISR(sym->etype)) {
+    if (IFFUNC_ISISR(sym->type)) {
 
        /* now we need to restore the registers */
        /* if this isr has no bank i.e. is going to
           run with bank 0 , then we need to save more
           registers :-) */
-       if (!SPEC_BANK(sym->etype)) {
+       if (!FUNC_REGBANK(sym->type)) {
            
            /* if this function does not call any other
               function then we can be economical and
               save only those registers that are used */
-           if (! sym->hasFcall) {
+           if (! IFFUNC_HASFCALL(sym->type)) {
                int i;
                
                /* if any registers used */
@@ -2625,7 +2781,7 @@ static void genEndFunction (iCode *ic)
        if (!inExcludeList("acc"))
            pic14_emitcode ("pop","acc");
 
-        if (SPEC_CRTCL(sym->etype))
+        if (IFFUNC_ISCRITICAL(sym->type))
             pic14_emitcode("setb","ea");
 
        /* if debug then send end of function */
@@ -2645,10 +2801,10 @@ static void genEndFunction (iCode *ic)
         pic14_emitcode ("reti","");
     }
     else {
-        if (SPEC_CRTCL(sym->etype))
+        if (IFFUNC_ISCRITICAL(sym->type))
             pic14_emitcode("setb","ea");
        
-       if (sym->calleeSave) {
+       if (IFFUNC_CALLEESAVES(sym->type)) {
            int i;
            
            /* if any registers used */
@@ -2677,7 +2833,7 @@ static void genEndFunction (iCode *ic)
        }
 
         pic14_emitcode ("return","");
-       emitpcode(POC_RETURN,NULL);
+       emitpcodeNULLop(POC_RETURN);
 
        /* Mark the end of a function */
        addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
@@ -2690,63 +2846,68 @@ static void genEndFunction (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genRet (iCode *ic)
 {
-    int size,offset = 0 , pushed = 0;
+  int size,offset = 0 , pushed = 0;
     
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if we have no return value then
-       just generate the "ret" */
-    if (!IC_LEFT(ic)) 
-       goto jumpret;       
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  /* if we have no return value then
+     just generate the "ret" */
+  if (!IC_LEFT(ic)) 
+    goto jumpret;       
     
-    /* we have something to return then
-       move the return value into place */
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    size = AOP_SIZE(IC_LEFT(ic));
+  /* we have something to return then
+     move the return value into place */
+  aopOp(IC_LEFT(ic),ic,FALSE);
+  size = AOP_SIZE(IC_LEFT(ic));
     
-    while (size--) {
-           char *l ;
-           if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
-                   /* #NOCHANGE */
-                   l = aopGet(AOP(IC_LEFT(ic)),offset++,
-                          FALSE,TRUE);
-                   pic14_emitcode("push","%s",l);
-                   pushed++;
-           } else {
-                   l = aopGet(AOP(IC_LEFT(ic)),offset,
-                              FALSE,FALSE);
-                   if (strcmp(fReturn[offset],l)) {
-                     if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
-                         ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
-                       pic14_emitcode("movlw","%s",l);
-                     else
-                       pic14_emitcode("movf","%s,w",l);
-                     if(size)
-                       pic14_emitcode("movwf","%s",fReturn[offset]);
-                     offset++;
-                   }
-           }
-    }    
-
-    if (pushed) {
-       while(pushed) {
-           pushed--;
-           if (strcmp(fReturn[pushed],"a"))
-               pic14_emitcode("pop",fReturn[pushed]);
-           else
-               pic14_emitcode("pop","acc");
+  while (size--) {
+    char *l ;
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
+      /* #NOCHANGE */
+      l = aopGet(AOP(IC_LEFT(ic)),offset++,
+                FALSE,TRUE);
+      pic14_emitcode("push","%s",l);
+      pushed++;
+    } else {
+      l = aopGet(AOP(IC_LEFT(ic)),offset,
+                FALSE,FALSE);
+      if (strcmp(fReturn[offset],l)) {
+       if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
+           ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
+         emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
+         pic14_emitcode("movlw","%s",l);
+       }else {
+         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
+         pic14_emitcode("movf","%s,w",l);
        }
+       if(size) {
+         emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
+         pic14_emitcode("movwf","%s",fReturn[offset]);
+       }
+       offset++;
+      }
+    }
+  }    
+
+  if (pushed) {
+    while(pushed) {
+      pushed--;
+      if (strcmp(fReturn[pushed],"a"))
+       pic14_emitcode("pop",fReturn[pushed]);
+      else
+       pic14_emitcode("pop","acc");
     }
-    freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
+  }
+  freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
     
  jumpret:
-       /* generate a jump to the return label
-          if the next is not the return statement */
-    if (!(ic->next && ic->next->op == LABEL &&
-         IC_LABEL(ic->next) == returnLabel)) {
+  /* generate a jump to the return label
+     if the next is not the return statement */
+  if (!(ic->next && ic->next->op == LABEL &&
+       IC_LABEL(ic->next) == returnLabel)) {
        
-       emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
-       pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
-    }
+    emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
+    pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
+  }
     
 }
 
@@ -2760,7 +2921,7 @@ static void genLabel (iCode *ic)
     if (IC_LABEL(ic) == entryLabel)
         return ;
 
-    emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
+    emitpLabel(IC_LABEL(ic)->key);
     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
 }
 
@@ -2934,7 +3095,7 @@ static void genMult (iCode *ic)
     }
 
     /* should have been converted to function call */       
-    assert(1) ;
+    assert(0) ;
 
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
@@ -3079,7 +3240,7 @@ static void genDiv (iCode *ic)
     }
 
     /* should have been converted to function call */
-    assert(1);
+    assert(0);
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
@@ -3213,7 +3374,7 @@ static void genMod (iCode *ic)
     }
 
     /* should have been converted to function call */
-    assert(1);
+    assert(0);
 
 release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
@@ -3322,26 +3483,18 @@ static void genSkip(iCode *ifx,int status_bit)
 /*-----------------------------------------------------------------*/
 /* genSkipc                                                        */
 /*-----------------------------------------------------------------*/
-static void genSkipc(iCode *ifx, int condition)
+static void genSkipc(resolvedIfx *rifx)
 {
-  if(!ifx)
+  if(!rifx)
     return;
 
-  if(condition)
-    emitSKPNC;
-  else
+  if(rifx->condition)
     emitSKPC;
-
-  if ( IC_TRUE(ifx) )
-    emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-  else
-    emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-
-  if ( IC_TRUE(ifx) )
-    pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
   else
-    pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+    emitSKPNC;
 
+  emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+  rifx->generated = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -3376,8 +3529,16 @@ static void genCmp (operand *left,operand *right,
 {
   int size, offset = 0 ;
   unsigned long lit = 0L,i = 0;
+  resolvedIfx rIfx;
 
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  if(ifx) {
+  DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
+  DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
+  }
+
+  resolveIfx(&rIfx,ifx);
+
   /* if left & right are bit variables */
   if (AOP_TYPE(left) == AOP_CRY &&
       AOP_TYPE(right) == AOP_CRY ) {
@@ -3401,58 +3562,106 @@ static void genCmp (operand *left,operand *right,
     } else {
 
       if(AOP_TYPE(right) == AOP_LIT) {
-
-       DEBUGpic14_emitcode(";right lit","%d",sign);
+       symbol *lbl = newiTempLabel(NULL);
 
        lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-       //default:
+
+       DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
+
+       size--;
+       i = (lit >> (size*8)) & 0xff;
+       if(sign) {
+         if(i & 0x80) {
+           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
+         } else {
+           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
+         }
+         emitpcode(POC_GOTO,popGetLabel(lbl->key));
+       }
+
+       emitpcode(POC_MOVLW, popGetLit(i));
+       emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
        while(size--) {
          i = (lit >> (size*8)) & 0xff;
-         if(i == 0) {
-           emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
-           pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
-           genSkipz(ifx,IC_TRUE(ifx) == NULL);
-         } else {
-           emitpcode(POC_MOVLW, popGetLit(i));
-           emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
+         emitpcode(POC_MOVLW, popGetLit(i));
+         emitSKPNC;
+         emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
+       }
 
-           pic14_emitcode("movlw","0x%x",i);
-           pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
-           genSkipc(ifx,IC_TRUE(ifx) == NULL);
-         }
+       if(ifx) {
+         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+         //genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
+         genSkipc(&rIfx);
+         //if(sign)
+           emitpLabel(lbl->key);
 
+         ifx->generated = 1;
        }
-       ifx->generated = 1;
        return;
       }
+
       if(AOP_TYPE(left) == AOP_LIT) {
+       //symbol *lbl = newiTempLabel(NULL);
 
-       DEBUGpic14_emitcode(";left lit","%d",sign);
+       lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
 
-       lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
+       DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
 
-       //default:
-       while(size--) {
+       if(size==1) {
+         if(sign) {
+           if(lit & 0x80) {
+             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
+           } else {
+             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
+           }
+           if(ifx) {
+             if(IC_TRUE(ifx) != NULL)
+               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
+             else
+               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
+           }
+         }
+         emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
+         emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
+         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+         rIfx.condition ^= 1;
+         genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,1,1);//IC_TRUE(ifx)!=NULL);
+       } else {
+         size--;
+         //lit++;
          i = (lit >> (size*8)) & 0xff;
-         if(i == 0) {
-           emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
-           genSkipz(ifx,IC_TRUE(ifx) != NULL);
-         } else if( i == 1 ) {
-           emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
-           pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
-           genSkipz(ifx,IC_TRUE(ifx) != NULL);
 
-         } else {
-           emitpcode(POC_MOVLW, popGetLit(i));
-           emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
+         if(sign) {
+           if(i & 0x80) {
+             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+           } else {
+             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+           }
+           if(ifx) {
+             if(IC_TRUE(ifx) != NULL)
+               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
+             else
+               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
+           }
+         }
 
-           pic14_emitcode("movlw","0x%x",i);
-           pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
-           genSkipc(ifx,IC_TRUE(ifx) != NULL);
+         emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
+         emitpcode(POC_SUBLW, popGetLit((i)&0xff));
+         while(size--) {
+           i = (lit >> (size*8)) & 0xff;
+           emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
+           emitSKPNC;
+           emitpcode(POC_SUBLW, popGetLit((i)&0xff));
          }
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+         genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,0,1);  //IC_TRUE(ifx) == NULL);
+
        }
-       ifx->generated = 1;
+/*
+       if(sign)
+         emitpLabel(lbl->key);
+*/
+       if(ifx) ifx->generated = 1;
        return;
       }
 
@@ -3561,91 +3770,223 @@ static void genCmpLt (iCode *ic, iCode *ifx)
 }
 
 /*-----------------------------------------------------------------*/
-/* gencjneshort - compare and jump if not equal                    */
+/* genc16bit2lit - compare a 16 bit value to a literal             */
 /*-----------------------------------------------------------------*/
-static void gencjneshort(operand *left, operand *right, symbol *lbl)
+static void genc16bit2lit(operand *op, int lit, int offset)
 {
-    int size = max(AOP_SIZE(left),AOP_SIZE(right));
-    int offset = 0;
-    unsigned long lit = 0L;
+  int i;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if the left side is a literal or 
-    if the right is in a pointer register and left 
-    is not */
-    if ((AOP_TYPE(left) == AOP_LIT) || 
-        (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
-        operand *t = right;
-        right = left;
-        left = t;
+  DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
+  if( (lit&0xff) == 0) 
+    i=1;
+  else
+    i=0;
+
+  switch( BYTEofLONG(lit,i)) { 
+  case 0:
+    emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+    break;
+  case 1:
+    emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+    break;
+  case 0xff:
+    emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+    break;
+  default:
+    emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+    emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
+  }
+
+  i ^= 1;
+
+  switch( BYTEofLONG(lit,i)) { 
+  case 0:
+    emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+    break;
+  case 1:
+    emitSKPNZ;
+    emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+    break;
+  case 0xff:
+    emitSKPNZ;
+    emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+    break;
+  default:
+    emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
+    emitSKPNZ;
+    emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
+
+  }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* gencjneshort - compare and jump if not equal                    */
+/*-----------------------------------------------------------------*/
+static void gencjne(operand *left, operand *right, iCode *ifx)
+{
+  int size = max(AOP_SIZE(left),AOP_SIZE(right));
+  int offset = 0;
+  resolvedIfx rIfx;
+  symbol *lbl;
+
+  unsigned long lit = 0L;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic14_emitcode ("; ","left %s=%s, right %s=%s, size = %d",
+                      AopType(AOP_TYPE(left)),
+                      aopGet(AOP(left),0,TRUE,FALSE),
+                      AopType(AOP_TYPE(right)),
+                      aopGet(AOP(right),0,FALSE,FALSE),
+                      size);
+
+  resolveIfx(&rIfx,ifx);
+  lbl =  newiTempLabel(NULL);
+
+
+  /* if the left side is a literal or 
+     if the right is in a pointer register and left 
+     is not */
+  if ((AOP_TYPE(left) == AOP_LIT) || 
+      (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+    operand *t = right;
+    right = left;
+    left = t;
+  }
+  if(AOP_TYPE(right) == AOP_LIT)
+    lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+
+  /* if the right side is a literal then anything goes */
+  if (AOP_TYPE(right) == AOP_LIT &&
+      AOP_TYPE(left) != AOP_DIR ) {
+    switch(size) {
+    case 2:
+      genc16bit2lit(left, lit, 0);
+      emitSKPNZ;
+      pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
+      emitpcode(POC_GOTO,popGetLabel(lbl->key));
+      break;
+    default:
+      while (size--) {
+       if(lit & 0xff) {
+         emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
+         pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
+         pic14_emitcode("xorlw","0x%x",lit & 0xff);
+       } else {
+         emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
+         pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+       }
+
+       emitSKPNZ;
+       pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
+       emitpcode(POC_GOTO,popGetLabel(lbl->key));
+       offset++;
+       lit >>= 8;
+      }
+      break;
     }
-    if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+  }
 
-    /* if the right side is a literal then anything goes */
-    if (AOP_TYPE(right) == AOP_LIT &&
-        AOP_TYPE(left) != AOP_DIR ) {
-        while (size--) {
-         if(lit & 0xff) {
-           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-           pic14_emitcode("xorlw","0x%x",lit & 0xff);
-         } else
-           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+  /* if the right side is in a register or in direct space or
+     if the left is a pointer register & right is not */    
+  else if (AOP_TYPE(right) == AOP_REG ||
+          AOP_TYPE(right) == AOP_DIR || 
+          (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
+          (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
+    switch(size) {
+    case 2:
+      genc16bit2lit(left, lit, 0);
+      emitSKPNZ;
+      pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
+      emitpcode(POC_GOTO,popGetLabel(lbl->key));
+      break;
+    default:
+      while (size--) {
+       int emit_skip=1;
+       if((AOP_TYPE(left) == AOP_DIR) && 
+          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
 
-         emitSKPNZ;
-         pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
-         offset++;
+         emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+         emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
+
+       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
+           
+         switch (lit & 0xff) {
+         case 0:
+           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+           break;
+         case 1:
+           emitpcode(POC_DECFSZ,popGet(AOP(left),offset,FALSE,FALSE));
+           emitpcode(POC_GOTO,popGetLabel(lbl->key));
+           emit_skip=0;
+           break;
+         case 0xff:
+           emitpcode(POC_INCFSZ,popGet(AOP(left),offset,FALSE,FALSE));
+           emitpcode(POC_GOTO,popGetLabel(lbl->key));
+           emit_skip=0;
+           break;
+         default:
+           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
+         }
          lit >>= 8;
-        }
-    }
 
-    /* if the right side is in a register or in direct space or
-    if the left is a pointer register & right is not */    
-    else if (AOP_TYPE(right) == AOP_REG ||
-             AOP_TYPE(right) == AOP_DIR || 
-             (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
-             (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
-        while (size--) {
-         if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
-            ( (lit & 0xff) != 0)) {
-           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-           pic14_emitcode("xorlw","0x%x",lit & 0xff);
-           lit >>= 8;
-         } else
-           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+       } else {
+         emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
+         pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+       }
+       if(emit_skip) {
+         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
+         if(rIfx.condition)
+           emitSKPNZ;
+         else
+           emitSKPZ;
+         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+         if(ifx)
+           ifx->generated=1;
+       }
+       emit_skip++;
+       offset++;
+      }
+      break;
+    }
+  } else if(AOP_TYPE(right) == AOP_REG &&
+           AOP_TYPE(left) != AOP_DIR){
 
-         emitSKPZ;
-         pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
-         offset++;
-/*
-            MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
-            if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
-               ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
-                pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
-            else
-                pic14_emitcode("cjne","a,%s,%05d_DS_",
-                         aopGet(AOP(right),offset,FALSE,TRUE),
-                         lbl->key+100);
-            offset++;
-*/
-        }
-    } else {
-        /* right is a pointer reg need both a & b */
-        while(size--) {
-            char *l = aopGet(AOP(left),offset,FALSE,FALSE);
-            if(strcmp(l,"b"))
-                pic14_emitcode("mov","b,%s",l);
-            MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-            pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
-            offset++;
-        }
+    while(size--) {
+      emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+      emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
+      pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
+      if(rIfx.condition)
+       emitSKPNZ;
+      else
+       emitSKPZ;
+      emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+      offset++;
+    }
+      
+  }else{
+    /* right is a pointer reg need both a & b */
+    while(size--) {
+      char *l = aopGet(AOP(left),offset,FALSE,FALSE);
+      if(strcmp(l,"b"))
+       pic14_emitcode("mov","b,%s",l);
+      MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+      pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
+      offset++;
     }
+  }
+  emitpLabel(lbl->key);
+
+  if(ifx)
+    ifx->generated = 1;
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* gencjne - compare and jump if not equal                         */
 /*-----------------------------------------------------------------*/
-static void gencjne(operand *left, operand *right, symbol *lbl)
+static void gencjne(operand *left, operand *right, iCode *ifx)
 {
     symbol *tlbl  = newiTempLabel(NULL);
 
@@ -3657,8 +3998,12 @@ static void gencjne(operand *left, operand *right, symbol *lbl)
     pic14_emitcode("","%05d_DS_:",lbl->key+100);
     pic14_emitcode("clr","a");
     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-}
 
+    emitpLabel(lbl->key);
+    emitpLabel(tlbl->key);
+
+}
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genCmpEq - generates code for equal to                          */
@@ -3670,6 +4015,7 @@ static void genCmpEq (iCode *ic, iCode *ifx)
     int size,offset=0;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
     if(ifx)
       DEBUGpic14_emitcode ("; ifx is non-null","");
     else
@@ -3679,7 +4025,22 @@ static void genCmpEq (iCode *ic, iCode *ifx)
     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
     aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
+/*
+    DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
+                        AopType(AOP_TYPE(IC_RESULT(ic))),
+                        AopType(AOP_TYPE(IC_LEFT(ic))),
+                        AopType(AOP_TYPE(IC_RIGHT(ic))));
+*/
     size = max(AOP_SIZE(left),AOP_SIZE(right));
+    DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
+                        AopType(AOP_TYPE(result)),
+                        aopGet(AOP(result),0,TRUE,FALSE),
+                        AopType(AOP_TYPE(left)),
+                        aopGet(AOP(left),0,TRUE,FALSE),
+                        AopType(AOP_TYPE(right)),
+                        aopGet(AOP(right),0,FALSE,FALSE),
+                        size);
+
 
     /* if literal, literal on the right or 
     if the right is in a pointer register and left 
@@ -3729,157 +4090,82 @@ static void genCmpEq (iCode *ic, iCode *ifx)
 
          /* They're not both bit variables. Is the right a literal? */
          if(AOP_TYPE(right) == AOP_LIT) {
-
            lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-           while (size--) {
-
-             if(size >= 1) {
-               int l = lit & 0xff;
-               int h = (lit>>8) & 0xff;
-               int optimized=0;
-
-               /* Check special cases for integers */
-               switch(lit & 0xffff) {
-               case 0x0000:
-                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0x0001:
-                 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0x0100:
-                 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0x00ff:
-                 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               case 0xff00:
-                 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 genSkip(ifx,'z');
-                 optimized++;
-                 break;
-               default:
-                 if(h == 0) {
-                   emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-                   emitpcode(POC_XORLW,popGetLit(l));
-                   emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-
-                   pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                   pic14_emitcode("xorlw","0x%x",l);
-                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                   optimized++;
-                   genSkip(ifx,'z');
-                 } else if (l == 0) {
-                   emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-                   emitpcode(POC_XORLW,popGetLit(h));
-                   emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
-
-                   pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-                   pic14_emitcode("xorlw","0x%x",h);
-                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                   optimized++;
-                   genSkip(ifx,'z');
-                 } else {
-                   emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-                   emitpcode(POC_XORLW,popGetLit(l));
-                   emitpcode(POC_MOVLW,popGetLit(h));
-                   emitSKPZ;
-                   emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
-/*
-                   pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                   pic14_emitcode("xorlw","0x%x",l);
-                   pic14_emitcode("movlw","0x%x",h);
-                   emitSKPZ;
-                   pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
-*/
-                   optimized++;
-                   genSkip(ifx,'z');
-                 }
+           
 
-               }
-               if(optimized) {
-                 size--;
-                 offset+=2;
-                 lit>>=16;
+           switch(size) {
 
-                 continue;
-               }
-                 
-             }
-               
+           case 1:
              switch(lit & 0xff) {
              case 1:
                if ( IC_TRUE(ifx) ) {
-
-                 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-
                  emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
                  emitSKPNZ;
                  emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-
-                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
                } else {
                  emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
                  emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-
-                 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
                }
                break;
              case 0xff:
                if ( IC_TRUE(ifx) ) {
-                 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-
                  emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
                  emitSKPNZ;
                  emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-
-                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
                } else {
                  emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
                  emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-
-                 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
-                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
                }
                break;
              default:
                emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-               //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
                if(lit)
                  emitpcode(POC_XORLW,popGetLit(lit & 0xff));
-               //pic14_emitcode("xorlw","0x%x",lit & 0xff);
                genSkip(ifx,'z');
              }
 
 
-             //              pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
-             //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
-             offset++;
-             lit >>= 8;
+             /* end of size == 1 */
+             break;
+             
+           case 2:
+             genc16bit2lit(left,lit,offset);
+             genSkip(ifx,'z');
+             break;
+             /* end of size == 2 */
+
+           default:
+             /* size is 4 */
+             if(lit==0) {
+               emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
+               emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
+               emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
+               emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
+
+             } else {
+
+               /* search for patterns that can be optimized */
+
+               genc16bit2lit(left,lit,0);
+               lit >>= 16;
+               if(lit) {
+                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
+                 //genSkip(ifx,'z');
+                 genc16bit2lit(left,lit,2);
+               } else {
+                 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
+                 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
+
+               }
+               
+             }
+
+             genSkip(ifx,'z');
            }
+         
+           ifx->generated = 1;
+           goto release ;
+           
 
          } else if(AOP_TYPE(right) == AOP_CRY ) {
            /* we know the left is not a bit, but that the right is */
@@ -3949,7 +4235,7 @@ static void genCmpEq (iCode *ic, iCode *ifx)
              offset++;
            }
            if(s>1 && IC_TRUE(ifx)) {
-             emitpLabel(tlbl->key+100+labelOffset);
+             emitpLabel(tlbl->key);
              pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
            }
          }
@@ -3993,20 +4279,34 @@ static void genCmpEq (iCode *ic, iCode *ifx)
         then put the result in place */
         pic14_outBitC(result);
     } else {
-        gencjne(left,right,newiTempLabel(NULL));    
-        if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-            aopPut(AOP(result),"a",0);
-            goto release ;
-        }
-        if (ifx) {
-            genIfxJump (ifx,"a");
-            goto release ;
-        }
-        /* if the result is used in an arithmetic operation
-        then put the result in place */
-        if (AOP_TYPE(result) != AOP_CRY) 
-            pic14_outAcc(result);
-        /* leave the result in acc */
+      
+      gencjne(left,right,ifx);
+/*
+      if(ifx) 
+       gencjne(left,right,newiTempLabel(NULL));
+      else {
+       if(IC_TRUE(ifx)->key)
+         gencjne(left,right,IC_TRUE(ifx)->key);
+       else
+         gencjne(left,right,IC_FALSE(ifx)->key);
+       ifx->generated = 1;
+       goto release ;
+      }
+      if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
+       aopPut(AOP(result),"a",0);
+       goto release ;
+      }
+
+      if (ifx) {
+       genIfxJump (ifx,"a");
+       goto release ;
+      }
+*/
+      /* if the result is used in an arithmetic operation
+        then put the result in place */
+      if (AOP_TYPE(result) != AOP_CRY) 
+       pic14_outAcc(result);
+      /* leave the result in acc */
     }
 
 release:
@@ -4034,6 +4334,28 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
         OP_SYMBOL(op)->liveTo <= ic->next->seq )
         return ic->next;
 
+    if (ic->next &&
+        ic->next->op == IFX &&
+        IC_COND(ic->next)->key == op->key) {
+      DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
+      return ic->next;
+    }
+
+    DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
+    if (ic->next &&
+        ic->next->op == IFX)
+      DEBUGpic14_emitcode ("; ic-next"," is an IFX");
+
+    if (ic->next &&
+        ic->next->op == IFX &&
+        IC_COND(ic->next)->key == op->key) {
+      DEBUGpic14_emitcode ("; "," key is okay");
+      DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
+                          OP_SYMBOL(op)->liveTo,
+                          ic->next->seq);
+    }
+
+
     return NULL;
 }
 /*-----------------------------------------------------------------*/
@@ -4191,287 +4513,291 @@ static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
 /*-----------------------------------------------------------------*/
 static void genAnd (iCode *ic, iCode *ifx)
 {
-    operand *left, *right, *result;
-    int size, offset=0;  
-    unsigned long lit = 0L;
-    int bytelit = 0;
-    //    char buffer[10];
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    aopOp((left = IC_LEFT(ic)),ic,FALSE);
-    aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,TRUE);
+  operand *left, *right, *result;
+  int size, offset=0;  
+  unsigned long lit = 0L;
+  int bytelit = 0;
+  resolvedIfx rIfx;
 
-#ifdef DEBUG_TYPE
-    pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
-             AOP_TYPE(result),
-             AOP_TYPE(left), AOP_TYPE(right));
-    pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
-             AOP_SIZE(result),
-             AOP_SIZE(left), AOP_SIZE(right));
-#endif
 
-    /* if left is a literal & right is not then exchange them */
-    if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
-       AOP_NEEDSACC(left)) {
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  aopOp((left = IC_LEFT(ic)),ic,FALSE);
+  aopOp((right= IC_RIGHT(ic)),ic,FALSE);
+  aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+  resolveIfx(&rIfx,ifx);
+
+  /* if left is a literal & right is not then exchange them */
+  if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
+      AOP_NEEDSACC(left)) {
+    operand *tmp = right ;
+    right = left;
+    left = tmp;
+  }
 
-    /* if result = right then exchange them */
-    if(pic14_sameRegs(AOP(result),AOP(right))){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
+  /* if result = right then exchange them */
+  if(pic14_sameRegs(AOP(result),AOP(right))){
+    operand *tmp = right ;
+    right = left;
+    left = tmp;
+  }
 
-    /* if right is bit then exchange them */
-    if (AOP_TYPE(right) == AOP_CRY &&
-        AOP_TYPE(left) != AOP_CRY){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
-    if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+  /* if right is bit then exchange them */
+  if (AOP_TYPE(right) == AOP_CRY &&
+      AOP_TYPE(left) != AOP_CRY){
+    operand *tmp = right ;
+    right = left;
+    left = tmp;
+  }
+  if(AOP_TYPE(right) == AOP_LIT)
+    lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
 
-    size = AOP_SIZE(result);
+  size = AOP_SIZE(result);
 
-    // if(bit & yy)
-    // result = bit & yy;
-    if (AOP_TYPE(left) == AOP_CRY){
-        // c = bit & literal;
-        if(AOP_TYPE(right) == AOP_LIT){
-            if(lit & 1) {
-                if(size && pic14_sameRegs(AOP(result),AOP(left)))
-                    // no change
-                    goto release;
-                pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-            } else {
-                // bit(result) = 0;
-                if(size && (AOP_TYPE(result) == AOP_CRY)){
-                    pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
-                    goto release;
-                }
-                if((AOP_TYPE(result) == AOP_CRY) && ifx){
-                    jumpIfTrue(ifx);
-                    goto release;
-                }
-                pic14_emitcode("clr","c");
-            }
-        } else {
-            if (AOP_TYPE(right) == AOP_CRY){
-                // c = bit & bit;
-                pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-                pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
-            } else {
-                // c = bit & val;
-                MOVA(aopGet(AOP(right),0,FALSE,FALSE));
-                // c = lsb
-                pic14_emitcode("rrc","a");
-                pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
-            }
-        }
-        // bit = c
-        // val = c
-        if(size)
-            pic14_outBitC(result);
-        // if(bit & ...)
-        else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-            genIfxJump(ifx, "c");           
-        goto release ;
+  DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
+                      AopType(AOP_TYPE(result)),
+                      aopGet(AOP(result),0,TRUE,FALSE),
+                      AopType(AOP_TYPE(left)),
+                      aopGet(AOP(left),0,TRUE,FALSE),
+                      AopType(AOP_TYPE(right)),
+                      aopGet(AOP(right),0,FALSE,FALSE),
+                      size);
+  // if(bit & yy)
+  // result = bit & yy;
+  if (AOP_TYPE(left) == AOP_CRY){
+    // c = bit & literal;
+    if(AOP_TYPE(right) == AOP_LIT){
+      if(lit & 1) {
+       if(size && pic14_sameRegs(AOP(result),AOP(left)))
+         // no change
+         goto release;
+       pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+      } else {
+       // bit(result) = 0;
+       if(size && (AOP_TYPE(result) == AOP_CRY)){
+         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
+         goto release;
+       }
+       if((AOP_TYPE(result) == AOP_CRY) && ifx){
+         jumpIfTrue(ifx);
+         goto release;
+       }
+       pic14_emitcode("clr","c");
+      }
+    } else {
+      if (AOP_TYPE(right) == AOP_CRY){
+       // c = bit & bit;
+       pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+       pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+      } else {
+       // c = bit & val;
+       MOVA(aopGet(AOP(right),0,FALSE,FALSE));
+       // c = lsb
+       pic14_emitcode("rrc","a");
+       pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+      }
     }
+    // bit = c
+    // val = c
+    if(size)
+      pic14_outBitC(result);
+    // if(bit & ...)
+    else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+      genIfxJump(ifx, "c");           
+    goto release ;
+  }
 
-    // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
-    // bit = val & 0xZZ     - size = 1, ifx = FALSE -
-    if((AOP_TYPE(right) == AOP_LIT) &&
-       (AOP_TYPE(result) == AOP_CRY) &&
-       (AOP_TYPE(left) != AOP_CRY)){
-        int posbit = isLiteralBit(lit);
-        /* left &  2^n */
-        if(posbit){
-         posbit--;
-         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
-            // bit = left & 2^n
-         if(size)
-           pic14_emitcode("mov","c,acc.%d",posbit&0x07);
-            // if(left &  2^n)
+  // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
+  // bit = val & 0xZZ     - size = 1, ifx = FALSE -
+  if((AOP_TYPE(right) == AOP_LIT) &&
+     (AOP_TYPE(result) == AOP_CRY) &&
+     (AOP_TYPE(left) != AOP_CRY)){
+    int posbit = isLiteralBit(lit);
+    /* left &  2^n */
+    if(posbit){
+      posbit--;
+      //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
+      // bit = left & 2^n
+      if(size)
+       pic14_emitcode("mov","c,acc.%d",posbit&0x07);
+      // if(left &  2^n)
+      else{
+       if(ifx){
+/*
+         if(IC_TRUE(ifx)) {
+           emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
+           emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
+         } else {
+           emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
+           emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
+         }
+*/
+         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
+                   newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
+         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+         
+         ifx->generated = 1;
+       }
+       goto release;
+      }
+    } else {
+      symbol *tlbl = newiTempLabel(NULL);
+      int sizel = AOP_SIZE(left);
+      if(size)
+       pic14_emitcode("setb","c");
+      while(sizel--){
+       if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
+         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
+         // byte ==  2^n ?
+         if((posbit = isLiteralBit(bytelit)) != 0)
+           pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
          else{
-           if(ifx){
-             pCodeOp *pcorb = popGet(AOP(left),0,TRUE,FALSE);
-             PCORB(pcorb)->subtype = PCOP(pcorb)->type;
-             PCOP(pcorb)->type = PO_GPR_BIT;
-             PCORB(pcorb)->bit = posbit;
-             if(IC_TRUE(ifx)) {
-               emitpcode(POC_BTFSC, pcorb); 
-               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
-             } else {
-               emitpcode(POC_BTFSS, pcorb); 
-               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
-             }
-             ifx->generated = 1;
-           }
-           goto release;
+           if(bytelit != 0x0FFL)
+             pic14_emitcode("anl","a,%s",
+                            aopGet(AOP(right),offset,FALSE,TRUE));
+           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
          }
-        } else {
-            symbol *tlbl = newiTempLabel(NULL);
-            int sizel = AOP_SIZE(left);
-            if(size)
-                pic14_emitcode("setb","c");
-            while(sizel--){
-                if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
-                    MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
-                    // byte ==  2^n ?
-                    if((posbit = isLiteralBit(bytelit)) != 0)
-                        pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
-                    else{
-                        if(bytelit != 0x0FFL)
-                            pic14_emitcode("anl","a,%s",
-                                     aopGet(AOP(right),offset,FALSE,TRUE));
-                        pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
-                    }
-                }
-                offset++;
-            }
-            // bit = left & literal
-            if(size){
-                pic14_emitcode("clr","c");
-                pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-            }
-            // if(left & literal)
-            else{
-                if(ifx)
-                    jmpTrueOrFalse(ifx, tlbl);
-                goto release ;
-            }
-        }
-        pic14_outBitC(result);
-        goto release ;
+       }
+       offset++;
+      }
+      // bit = left & literal
+      if(size){
+       pic14_emitcode("clr","c");
+       pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+      }
+      // if(left & literal)
+      else{
+       if(ifx)
+         jmpTrueOrFalse(ifx, tlbl);
+       goto release ;
+      }
     }
+    pic14_outBitC(result);
+    goto release ;
+  }
 
-    /* if left is same as result */
-    if(pic14_sameRegs(AOP(result),AOP(left))){
-      for(;size--; offset++,lit>>=8) {
+  /* if left is same as result */
+  if(pic14_sameRegs(AOP(result),AOP(left))){
+    int know_W = -1;
+    for(;size--; offset++,lit>>=8) {
+      if(AOP_TYPE(right) == AOP_LIT){
+       switch(lit & 0xff) {
+       case 0x00:
+         /*  and'ing with 0 has clears the result */
+         pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
+         emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
+         break;
+       case 0xff:
+         /* and'ing with 0xff is a nop when the result and left are the same */
+         break;
+
+       default:
+         {
+           int p = my_powof2( (~lit) & 0xff );
+           if(p>=0) {
+             /* only one bit is set in the literal, so use a bcf instruction */
+             pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
+             //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
+             emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+
+           } else {
+             pic14_emitcode("movlw","0x%x", (lit & 0xff));
+             pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
+             if(know_W != (lit&0xff))
+               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+             know_W = lit &0xff;
+             emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
+           }
+         }    
+       }
+      } else {
+       if (AOP_TYPE(left) == AOP_ACC) {
+         emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
+       } else {                    
+         emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
+         emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
+
+       }
+      }
+    }
+
+  } else {
+    // left & result in different registers
+    if(AOP_TYPE(result) == AOP_CRY){
+      // result = bit
+      // if(size), result in bit
+      // if(!size && ifx), conditional oper: if(left & right)
+      symbol *tlbl = newiTempLabel(NULL);
+      int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
+      if(size)
+       pic14_emitcode("setb","c");
+      while(sizer--){
+       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+       pic14_emitcode("anl","a,%s",
+                      aopGet(AOP(left),offset,FALSE,FALSE));
+       pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
+       offset++;
+      }
+      if(size){
+       CLRC;
+       pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+       pic14_outBitC(result);
+      } else if(ifx)
+       jmpTrueOrFalse(ifx, tlbl);
+    } else {
+      for(;(size--);offset++) {
+       // normal case
+       // result = left & right
        if(AOP_TYPE(right) == AOP_LIT){
-         switch(lit & 0xff) {
+         int t = (lit >> (offset*8)) & 0x0FFL;
+         switch(t) { 
          case 0x00:
-           /*  and'ing with 0 has clears the result */
-           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
+           pic14_emitcode("clrf","%s",
+                          aopGet(AOP(result),offset,FALSE,FALSE));
            emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
            break;
          case 0xff:
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF,popGet(AOP(right),offset,FALSE,FALSE));
+           pic14_emitcode("movf","%s,w",
+                          aopGet(AOP(left),offset,FALSE,FALSE));
+           pic14_emitcode("movwf","%s",
+                          aopGet(AOP(result),offset,FALSE,FALSE));
+           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
            break;
-
          default:
-           {
-             int p = my_powof2( (~lit) & 0xff );
-             if(p>=0) {
-               /* only one bit is set in the literal, so use a bcf instruction */
-               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
-               emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
-             } else {
-               pic14_emitcode("movlw","0x%x", (lit & 0xff));
-               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
-               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-               emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
-             }
-           }    
-         }
-       } else {
-         if (AOP_TYPE(left) == AOP_ACC) {
-           pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
-
-         } else {                  
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
+           pic14_emitcode("movlw","0x%x",t);
+           pic14_emitcode("andwf","%s,w",
+                          aopGet(AOP(left),offset,FALSE,FALSE));
+           pic14_emitcode("movwf","%s",
+                          aopGet(AOP(result),offset,FALSE,FALSE));
+             
+           emitpcode(POC_MOVLW, popGetLit(t));
            emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
-
+           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
          }
+         continue;
        }
-      }
 
-    } else {
-        // left & result in different registers
-        if(AOP_TYPE(result) == AOP_CRY){
-            // result = bit
-            // if(size), result in bit
-            // if(!size && ifx), conditional oper: if(left & right)
-            symbol *tlbl = newiTempLabel(NULL);
-            int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
-            if(size)
-                pic14_emitcode("setb","c");
-            while(sizer--){
-                MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                pic14_emitcode("anl","a,%s",
-                         aopGet(AOP(left),offset,FALSE,FALSE));
-                pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
-                offset++;
-            }
-            if(size){
-                CLRC;
-                pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-                pic14_outBitC(result);
-            } else if(ifx)
-                jmpTrueOrFalse(ifx, tlbl);
-        } else {
-         for(;(size--);offset++) {
-           // normal case
-           // result = left & right
-           if(AOP_TYPE(right) == AOP_LIT){
-             int t = (lit >> (offset*8)) & 0x0FFL;
-             switch(t) { 
-             case 0x00:
-               pic14_emitcode("clrf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-               emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
-               break;
-             case 0xff:
-               pic14_emitcode("movf","%s,w",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-               break;
-             default:
-               pic14_emitcode("movlw","0x%x",t);
-               pic14_emitcode("andwf","%s,w",
+       if (AOP_TYPE(left) == AOP_ACC) {
+         pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+         emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
+       } else {
+         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+         pic14_emitcode("andwf","%s,w",
                         aopGet(AOP(left),offset,FALSE,FALSE));
-               pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
-             
-               emitpcode(POC_MOVLW, popGetLit(t));
-               emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
-               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-             }
-             continue;
-           }
-
-           if (AOP_TYPE(left) == AOP_ACC) {
-             pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-             emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
-           } else {
-             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-             pic14_emitcode("andwf","%s,w",
-                      aopGet(AOP(left),offset,FALSE,FALSE));
-             emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
-             emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
-           }
-           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
-         }
+         emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
+         emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
        }
+       pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
+      }
     }
+  }
 
-release :
+  release :
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);     
+  freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+  freeAsmop(result,NULL,ic,TRUE);     
 }
 
 /*-----------------------------------------------------------------*/
@@ -4513,6 +4839,11 @@ static void genOr (iCode *ic, iCode *ifx)
         left = tmp;
     }
 
+    DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
+                        AopType(AOP_TYPE(result)),
+                        AopType(AOP_TYPE(left)),
+                        AopType(AOP_TYPE(right)));
+
     if(AOP_TYPE(right) == AOP_LIT)
         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
 
@@ -4559,30 +4890,49 @@ static void genOr (iCode *ic, iCode *ifx)
                         AOP(result)->aopu.aop_dir,
                         AOP(result)->aopu.aop_dir);
              } else {
+               if( AOP_TYPE(result) == AOP_ACC) {
+                 emitpcode(POC_MOVLW, popGetLit(0));
+                 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
+                 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
+                 emitpcode(POC_MOVLW, popGetLit(1));
 
-               emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
-               emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
-               emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
-               emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
+               } else {
 
-               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
-               pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
-                        AOP(right)->aopu.aop_dir,
-                        AOP(right)->aopu.aop_dir);
-               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                        AOP(left)->aopu.aop_dir,
-                        AOP(left)->aopu.aop_dir);
-               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
-                        AOP(result)->aopu.aop_dir,
-                        AOP(result)->aopu.aop_dir);
+                 emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
+                 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
+                 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
+                 emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
+
+                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
+                                AOP(result)->aopu.aop_dir,
+                                AOP(result)->aopu.aop_dir);
+                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
+                                AOP(right)->aopu.aop_dir,
+                                AOP(right)->aopu.aop_dir);
+                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+                                AOP(left)->aopu.aop_dir,
+                                AOP(left)->aopu.aop_dir);
+                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
+                                AOP(result)->aopu.aop_dir,
+                                AOP(result)->aopu.aop_dir);
+               }
              }
-            }
-            else{
+            } else {
                 // c = bit | val;
                 symbol *tlbl = newiTempLabel(NULL);
                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
+
+               emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
+               if( AOP_TYPE(right) == AOP_ACC) {
+                 emitpcode(POC_IORLW, popGetLit(0));
+                 emitSKPNZ;
+                 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
+                 emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
+               }
+
+
+
                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
                     pic14_emitcode(";XXX setb","c");
                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
@@ -4643,6 +4993,7 @@ static void genOr (iCode *ic, iCode *ifx)
 
     /* if left is same as result */
     if(pic14_sameRegs(AOP(result),AOP(left))){
+      int know_W = -1;
       for(;size--; offset++,lit>>=8) {
        if(AOP_TYPE(right) == AOP_LIT){
          if((lit & 0xff) == 0)
@@ -4652,14 +5003,13 @@ static void genOr (iCode *ic, iCode *ifx)
            int p = my_powof2(lit & 0xff);
            if(p>=0) {
              /* only one bit is set in the literal, so use a bsf instruction */
-             emitpcode(POC_BSF,   popGet(AOP(left),offset,FALSE,FALSE));
-             pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
+             emitpcode(POC_BSF,
+                       newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
            } else {
-             emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+             if(know_W != (lit & 0xff))
+               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+             know_W = lit & 0xff;
              emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
-
-             pic14_emitcode("movlw","0x%x", (lit & 0xff));
-             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
            }
                    
          }
@@ -4687,6 +5037,7 @@ static void genOr (iCode *ic, iCode *ifx)
             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
            pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
 
+
             if(size)
                 pic14_emitcode(";XXX setb","c");
             while(sizer--){
@@ -5291,7 +5642,7 @@ static void shiftR1Left2Result (operand *left, int offl,
 
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-  same = (left == result) || (AOP(left) == AOP(result));
+  same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
 
   /* Copy the msb into the carry if signed. */
   if(sign) {
@@ -5339,13 +5690,13 @@ static void shiftR1Left2Result (operand *left, int offl,
       
   case 4:
     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0x1f));
+    emitpcode(POC_ANDLW, popGetLit(0x0f));
     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
     break;
 
   case 5:
     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
-    emitpcode(POC_ANDLW, popGetLit(0x1f));
+    emitpcode(POC_ANDLW, popGetLit(0x0f));
     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
     emitCLRC;
     emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
@@ -5353,7 +5704,7 @@ static void shiftR1Left2Result (operand *left, int offl,
     break;
   case 6:
 
-    emitpcode(POC_RLFW,  popGet(AOP(left),offr,FALSE,FALSE));
+    emitpcode(POC_RLFW,  popGet(AOP(left),offl,FALSE,FALSE));
     emitpcode(POC_ANDLW, popGetLit(0x80));
     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
     emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
@@ -5579,6 +5930,7 @@ static void AccAXLsh (char *x, int shCount)
     }
 }
 #endif
+#if 0
 /*-----------------------------------------------------------------*/
 /* AccAXRsh - right shift a:x known count (0..7)                   */
 /*-----------------------------------------------------------------*/
@@ -5633,7 +5985,7 @@ static void AccAXRsh (char *x, int shCount)
             break;
     }
 }
-
+#endif
 /*-----------------------------------------------------------------*/
 /* AccAXRshS - right shift signed a:x known count (0..7)           */
 /*-----------------------------------------------------------------*/
@@ -5774,6 +6126,7 @@ static void shiftL2Left2Result (operand *left, int offl,
       break;
     case 1:
     case 2:
+    case 3:
       /* note, use a mov/add for the shift since the mov has a
         chance of getting optimized out */
       emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
@@ -5788,7 +6141,7 @@ static void shiftL2Left2Result (operand *left, int offl,
        emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
       }
       break;
-    case 3:
+
     case 4:
     case 5:
       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
@@ -5800,10 +6153,7 @@ static void shiftL2Left2Result (operand *left, int offl,
       emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
 
-      if(shCount == 3) {
-       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
-       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
-      }
+
       if(shCount == 5) {
        emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
        emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
@@ -5844,8 +6194,9 @@ static void shiftR2Left2Result (operand *left, int offl,
   int same=0;
 
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  if(pic14_sameRegs(AOP(result), AOP(left)) &&
-     ((offl + MSB16) == offr)){
+  same = pic14_sameRegs(AOP(result), AOP(left));
+
+  if(same && ((offl + MSB16) == offr)){
     same=1;
     /* don't crash result[offr] */
     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
@@ -5858,12 +6209,97 @@ static void shiftR2Left2Result (operand *left, int offl,
   if(sign)
     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
   else {
-      //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+    //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
     
-    //    switch() {
-    //}
-    if(pic14_getDataSize(result) > 1)
-      aopPut(AOP(result),"a",offr+MSB16);
+    switch(shCount) {
+    case 0:
+      break;
+    case 1:
+    case 2:
+    case 3:
+      emitCLRC;
+      if(same) {
+       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
+      } else {
+
+       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+      }
+
+      while(--shCount) {
+       emitCLRC;
+       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
+      }
+      break;
+    case 4:
+    case 5:
+      if(same) {
+
+       emitpcode(POC_MOVLW, popGetLit(0xf0));
+       emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
+
+       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
+      } else {
+       emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
+       emitpcode(POC_ANDLW, popGetLit(0x0f));
+       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+
+       emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
+       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_ANDLW, popGetLit(0xf0));
+       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
+      }
+
+      if(shCount >=5) {
+       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
+      }
+
+      break;
+
+    case 6:
+      if(same) {
+
+       emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+
+       emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_ANDLW,popGetLit(0x03));
+       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+      } else {
+       emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_ANDLW,popGetLit(0x03));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+      }
+
+      break;
+    case 7:
+      emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
+      emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+    }
   }
 }
 
@@ -6220,7 +6656,7 @@ static void genLeftShift (iCode *ic)
 
        emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
        emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
-       emitpLabel(tlbl->key+100+labelOffset);
+       emitpLabel(tlbl->key);
        emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
        emitpcode(POC_ADDLW,  popGetLit(1));
        emitSKPC;
@@ -6283,7 +6719,11 @@ static void genrshTwo (operand *result,operand *left,
                                shCount, sign);
         else 
             movLeft2Result(left, MSB16, result, LSB, sign);
-        addSign(result, MSB16, sign);
+       if(sign)
+         addSign(result, MSB16, sign);
+       else
+         emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
+
     }
 
     /*  1 <= shCount <= 7 */
@@ -6638,7 +7078,7 @@ static void genRightShift (iCode *ic)
 
        emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
        emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
-       emitpLabel(tlbl->key+100+labelOffset);
+       emitpLabel(tlbl->key);
        emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
        emitpcode(POC_ADDLW,  popGetLit(1));
        emitSKPC;
@@ -7098,69 +7538,50 @@ static void pic14_emitcodePointerGet (operand *left,
 static void genGenPointerGet (operand *left,
                               operand *result, iCode *ic)
 {
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(result));
+  int size, offset ;
+  sym_link *retype = getSpec(operandType(result));
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    aopOp(left,ic,FALSE);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  aopOp(left,ic,FALSE);
+  aopOp(result,ic,FALSE);
 
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(left) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(left) == AOP_IMMD) {
-            pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
-           pic14_emitcode("mov","b,#%d",pointerCode(retype));
-       }
-        else { /* we need to get it byte by byte */
-         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
-         //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
-         //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
-         pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
-         pic14_emitcode("movwf","FSR");
-         /*
-            pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
-               pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
-            }
-            else
-            {
-               pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
-            }
-         */
-        }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE); 
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genUnpackBits(result,"dptr",GPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
+  DEBUGpic14_emitcode ("; ","result %s, left %s",
+                        AopType(AOP_TYPE(result)),
+                        AopType(AOP_TYPE(left)));
 
-        while (size--) {
-         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+  /* if the operand is already in dptr 
+     then we do nothing else we move the value to dptr */
+  if (AOP_TYPE(left) != AOP_STR) {
+    /* if this is remateriazable */
+    if (AOP_TYPE(left) == AOP_IMMD) {
+      pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
+      pic14_emitcode("mov","b,#%d",pointerCode(retype));
+    }
+    else { /* we need to get it byte by byte */
 
-         emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
-         if(size)
-           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
-/*
-         pic14_emitcode("movf","indf,w");
-         pic14_emitcode("movwf","%s",
-                  aopGet(AOP(result),offset++,FALSE,FALSE));
-         if (size)
-           pic14_emitcode("incf","fsr,f");
-*/
-        }
+      size = AOP_SIZE(result);
+      offset = 0 ;
+
+      while(size--) {
+       emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+       emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
+       if(size)
+         emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+      }
+      goto release;
     }
+  }
+  /* so dptr know contains the address */
+
+  /* if bit then unpack */
+  if (IS_BITVAR(retype)) 
+    genUnpackBits(result,"dptr",GPOINTER);
+
+ release:
+  freeAsmop(left,NULL,ic,TRUE);
+  freeAsmop(result,NULL,ic,TRUE);
 
-    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7697,59 +8118,95 @@ static void genFarPointerSet (operand *right,
 static void genGenPointerSet (operand *right,
                               operand *result, iCode *ic)
 {
-    int size, offset ;
-    sym_link *retype = getSpec(operandType(right));
+  int size, offset ;
+  sym_link *retype = getSpec(operandType(right));
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    aopOp(result,ic,FALSE);
+  aopOp(result,ic,FALSE);
+  aopOp(right,ic,FALSE);
+  size = AOP_SIZE(right);
+
+  DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
+                      AopType(AOP_TYPE(result)),
+                      aopGet(AOP(result),0,TRUE,FALSE),
+                      AopType(AOP_TYPE(right)),
+                      aopGet(AOP(right),0,FALSE,FALSE),
+                      size);
+
+  /* if the operand is already in dptr 
+     then we do nothing else we move the value to dptr */
+  if (AOP_TYPE(result) != AOP_STR) {
+    /* if this is remateriazable */
+    if (AOP_TYPE(result) == AOP_IMMD) {
+      pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
+      pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
+    }
+    else { /* we need to get it byte by byte */
+      //char *l = aopGet(AOP(result),0,FALSE,FALSE);
+      size = AOP_SIZE(right);
+      offset = 0 ;
 
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(result) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(result) == AOP_IMMD) {
-            pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
-            pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
-        }
-        else { /* we need to get it byte by byte */
-         char *l = aopGet(AOP(result),0,FALSE,FALSE);
+      /* hack hack! see if this the FSR. If so don't load W */
+      if(AOP_TYPE(right) != AOP_ACC) {
+
+       if(size==2)
+         emitpcode(POC_DECF,popCopyReg(&pc_fsr));
+
+       if(size==4) {
+         emitpcode(POC_MOVLW,popGetLit(0xfd));
+         emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
+       }
 
-         if(strcmp("FSR",l))
-           emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
+       while(size--) {
+         emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
          emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
+         
+         if(size)
+           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+       }
 
-         if(strcmp("FSR",l))
-           pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
 
-         pic14_emitcode("movwf","INDF");
-        }
+       goto release;
+      } 
+
+      if(aopIdx(AOP(result),0) != 4) {
+
+       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
+       goto release;
+      }
+
+      emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
+      goto release;
+
     }
-    /* so dptr know contains the address */
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp(right,ic,FALSE);
+  }
+  /* so dptr know contains the address */
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genPackBits(retype,right,"dptr",GPOINTER);
-    else {
-        size = AOP_SIZE(right);
-        offset = 0 ;
 
-        while (--size) {
-         //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
-           if(size)
-             pic14_emitcode("incf","fsr,f");
-           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
-           pic14_emitcode("movwf","indf");
-            //MOVA(l);
-            //DEBUGpic14_emitcode(";lcall","__gptrput");
-            //if (size)
-            //    pic14_emitcode("inc","dptr");
-        }
+  /* if bit then unpack */
+  if (IS_BITVAR(retype)) 
+    genPackBits(retype,right,"dptr",GPOINTER);
+  else {
+    size = AOP_SIZE(right);
+    offset = 0 ;
+
+    while (--size) {
+      //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
+      if(size)
+       pic14_emitcode("incf","fsr,f");
+      pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
+      pic14_emitcode("movwf","indf");
+      //MOVA(l);
+      //DEBUGpic14_emitcode(";lcall","__gptrput");
+      //if (size)
+      //    pic14_emitcode("inc","dptr");
     }
+  }
 
-    freeAsmop(right,NULL,ic,TRUE);
+ release:
+  freeAsmop(right,NULL,ic,TRUE);
+  freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7823,44 +8280,39 @@ static void genPointerSet (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genIfx (iCode *ic, iCode *popIc)
 {
-    operand *cond = IC_COND(ic);
-    int isbit =0;
+  operand *cond = IC_COND(ic);
+  int isbit =0;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    aopOp(cond,ic,FALSE);
-
-    /* get the value into acc */
-    if (AOP_TYPE(cond) != AOP_CRY)
-        pic14_toBoolean(cond);
-    else
-        isbit = 1;
-    /* the result is now in the accumulator */
-    freeAsmop(cond,NULL,ic,TRUE);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    /* if there was something to be popped then do it */
-    if (popIc)
-        genIpop(popIc);
+  aopOp(cond,ic,FALSE);
 
-    /* if the condition is  a bit variable */
-    if (isbit && IS_ITEMP(cond) && 
-       SPIL_LOC(cond)) {
-      genIfxJump(ic,SPIL_LOC(cond)->rname);
-      DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
-    }
-    else {
-      /*
-       if (isbit && !IS_ITEMP(cond))
-         DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
-       else
-         DEBUGpic14_emitcode ("; isbit","a");
-      */
+  /* get the value into acc */
+  if (AOP_TYPE(cond) != AOP_CRY)
+    pic14_toBoolean(cond);
+  else
+    isbit = 1;
+  /* the result is now in the accumulator */
+  freeAsmop(cond,NULL,ic,TRUE);
+
+  /* if there was something to be popped then do it */
+  if (popIc)
+    genIpop(popIc);
+
+  /* if the condition is  a bit variable */
+  if (isbit && IS_ITEMP(cond) && 
+      SPIL_LOC(cond)) {
+    genIfxJump(ic,SPIL_LOC(cond)->rname);
+    DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
+  }
+  else {
+    if (isbit && !IS_ITEMP(cond))
+      genIfxJump(ic,OP_SYMBOL(cond)->rname);
+    else
+      genIfxJump(ic,"a");
+  }
+  ic->generated = 1;
 
-       if (isbit && !IS_ITEMP(cond))
-           genIfxJump(ic,OP_SYMBOL(cond)->rname);
-       else
-           genIfxJump(ic,"a");
-    }
-    ic->generated = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -7868,71 +8320,54 @@ static void genIfx (iCode *ic, iCode *popIc)
 /*-----------------------------------------------------------------*/
 static void genAddrOf (iCode *ic)
 {
-    symbol *sym = OP_SYMBOL(IC_LEFT(ic));
-    int size, offset ;
+  //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+  operand *right, *result, *left;
+  //int size, offset ;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    aopOp(IC_RESULT(ic),ic,FALSE);
 
-    /* if the operand is on the stack then we 
-    need to get the stack offset of this
-    variable */
-    if (sym->onStack) {
-        /* if it has an offset then we need to compute
-        it */
-        if (sym->stack) {
-            pic14_emitcode("mov","a,_bp");
-            pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
-            aopPut(AOP(IC_RESULT(ic)),"a",0);       
-        } else {
-            /* we can just move _bp */
-            aopPut(AOP(IC_RESULT(ic)),"_bp",0);
-        }
-        /* fill the result with zero */
-        size = AOP_SIZE(IC_RESULT(ic)) - 1;
-        
-        
-        if (options.stack10bit && size < (FPTRSIZE - 1))
-        {
-            fprintf(stderr, 
-                   "*** warning: pointer to stack var truncated.\n");
-        }
-        
-        offset = 1;
-        while (size--)
-        {
-            /* Yuck! */
-            if (options.stack10bit && offset == 2)
-            {
-                aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
-            }
-            else
-            {
-               aopPut(AOP(IC_RESULT(ic)),zero,offset++);
-            }
-        }
+  //aopOp(IC_RESULT(ic),ic,FALSE);
 
-        goto release;
-    }
+  aopOp((left=IC_LEFT(ic)),ic,FALSE);
+  aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+  aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
-    /* object not on stack then we need the name */
-    size = AOP_SIZE(IC_RESULT(ic));
-    offset = 0;
+  if(result)
+    DEBUGpic14_emitcode ("; ","result %s",
+                        AopType(AOP_TYPE(IC_RESULT(ic))));
 
-    while (size--) {
-        char s[SDCC_NAME_MAX];
-        if (offset) 
-            sprintf(s,"#(%s >> %d)",
-                    sym->rname,
-                    offset*8);
-        else
-            sprintf(s,"#%s",sym->rname);
-        aopPut(AOP(IC_RESULT(ic)),s,offset++);
-    }
+  if(left)
+    DEBUGpic14_emitcode ("; ","left %s",
+                        AopType(AOP_TYPE(IC_LEFT(ic))));
+  if(right)
+    DEBUGpic14_emitcode ("; ","right %s",
+                        AopType(AOP_TYPE(IC_RIGHT(ic))));
+  
+  emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
+  emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+
+#if 0
+  /* object not on stack then we need the name */
+  size = AOP_SIZE(IC_RESULT(ic));
+  offset = 0;
+
+  while (size--) {
+    char s[SDCC_NAME_MAX];
+    if (offset) 
+      sprintf(s,"#(%s >> %d)",
+             sym->rname,
+             offset*8);
+    else
+      sprintf(s,"#%s",sym->rname);
+    aopPut(AOP(IC_RESULT(ic)),s,offset++);
+  }
+#endif
 
-release:
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+
+  //  freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+  freeAsmop(left,NULL,ic,FALSE);
+  freeAsmop(result,NULL,ic,TRUE);
 
 }
 
@@ -7970,121 +8405,126 @@ static void genFarFarAssign (operand *result, operand *right, iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genAssign (iCode *ic)
 {
-    operand *result, *right;
-    int size, offset ;
-       unsigned long lit = 0L;
+  operand *result, *right;
+  int size, offset,know_W;
+  unsigned long lit = 0L;
 
-    result = IC_RESULT(ic);
-    right  = IC_RIGHT(ic) ;
+  result = IC_RESULT(ic);
+  right  = IC_RIGHT(ic) ;
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    /* if they are the same */
-    if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
-        return ;
+  /* if they are the same */
+  if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
+    return ;
 
-    aopOp(right,ic,FALSE);
-    aopOp(result,ic,TRUE);
+  aopOp(right,ic,FALSE);
+  aopOp(result,ic,TRUE);
 
-    /* if they are the same registers */
-    if (pic14_sameRegs(AOP(right),AOP(result)))
-        goto release;
+  DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
+                      AopType(AOP_TYPE(IC_RESULT(ic))),
+                      AopType(AOP_TYPE(IC_RIGHT(ic))),
+                      AOP_SIZE(result));
 
-    /* if the result is a bit */
-    if (AOP_TYPE(result) == AOP_CRY) {
+  /* if they are the same registers */
+  if (pic14_sameRegs(AOP(right),AOP(result)))
+    goto release;
 
-        /* if the right size is a literal then
-        we know what the value is */
-        if (AOP_TYPE(right) == AOP_LIT) {
+  /* if the result is a bit */
+  if (AOP_TYPE(result) == AOP_CRY) {
+
+    /* if the right size is a literal then
+       we know what the value is */
+    if (AOP_TYPE(right) == AOP_LIT) {
          
-         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
-                     popGet(AOP(result),0,FALSE,FALSE));
+      emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+                 popGet(AOP(result),0,FALSE,FALSE));
 
-            if (((int) operandLitValue(right))) 
-             pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
+      if (((int) operandLitValue(right))) 
+       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
                       AOP(result)->aopu.aop_dir,
                       AOP(result)->aopu.aop_dir);
-            else
-             pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
-                AOP(result)->aopu.aop_dir,
-                AOP(result)->aopu.aop_dir);
-            goto release;
-        }
+      else
+       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
+                      AOP(result)->aopu.aop_dir,
+                      AOP(result)->aopu.aop_dir);
+      goto release;
+    }
 
-        /* the right is also a bit variable */
-        if (AOP_TYPE(right) == AOP_CRY) {
-         emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
-         emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
-         emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
+    /* the right is also a bit variable */
+    if (AOP_TYPE(right) == AOP_CRY) {
+      emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
+      emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
+      emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
+
+      pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
+                    AOP(result)->aopu.aop_dir,
+                    AOP(result)->aopu.aop_dir);
+      pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
+                    AOP(right)->aopu.aop_dir,
+                    AOP(right)->aopu.aop_dir);
+      pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
+                    AOP(result)->aopu.aop_dir,
+                    AOP(result)->aopu.aop_dir);
+      goto release ;
+    }
 
-         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
-                  AOP(result)->aopu.aop_dir,
-                  AOP(result)->aopu.aop_dir);
-         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
-                  AOP(right)->aopu.aop_dir,
-                  AOP(right)->aopu.aop_dir);
-         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
-                  AOP(result)->aopu.aop_dir,
-                  AOP(result)->aopu.aop_dir);
-         goto release ;
-        }
+    /* we need to or */
+    emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
+    pic14_toBoolean(right);
+    emitSKPZ;
+    emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
+    //aopPut(AOP(result),"a",0);
+    goto release ;
+  }
 
-        /* we need to or */
-       emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
-        pic14_toBoolean(right);
-       emitSKPZ;
-       emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
-        //aopPut(AOP(result),"a",0);
-        goto release ;
-    }
+  /* bit variables done */
+  /* general case */
+  size = AOP_SIZE(result);
+  offset = 0 ;
+  if(AOP_TYPE(right) == AOP_LIT)
+    lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
 
-    /* bit variables done */
-    /* general case */
-    size = AOP_SIZE(result);
-    offset = 0 ;
-    if(AOP_TYPE(right) == AOP_LIT)
-       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-    if((AOP_TYPE(result) != AOP_REG) &&
-       (AOP_TYPE(right) == AOP_LIT) &&
-       !IS_FLOAT(operandType(right)) &&
-       (lit < 256L)){
+  if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
+    if(aopIdx(AOP(result),0) == 4) {
+      emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
+      goto release;
+    } else
+      DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
+  }
 
-       while (size--) {
-         if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
-           //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
-             emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
-           }else {
-             emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
-             emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
-             //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
-             //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
-           }
-       }
+  know_W=-1;
+  while (size--) {
+    if(AOP_TYPE(right) == AOP_LIT) {
+      if(lit&0xff) {
+       if(know_W != (lit&0xff))
+         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
+       know_W = lit&0xff;
+       emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
+      } else
+       emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
+
+      lit >>= 8;
+
+    } else if (AOP_TYPE(right) == AOP_CRY) {
+      emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
+      if(offset == 0) {
+       emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
+       emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
+      }
     } else {
-       while (size--) {
-         if(AOP_TYPE(right) == AOP_LIT) {
-           emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
-
-         } else if (AOP_TYPE(right) == AOP_CRY) {
-           emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
-           if(offset == 0) {
-             emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
-             emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
-           }
-         } else {
-           emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
-           emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
-         }
-           
-         //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
-         offset++;
-       }
+      emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
     }
+           
+    offset++;
+  }
+
     
-release:
-    freeAsmop (right,NULL,ic,FALSE);
-    freeAsmop (result,NULL,ic,TRUE);
+ release:
+  freeAsmop (right,NULL,ic,FALSE);
+  freeAsmop (result,NULL,ic,TRUE);
 }   
 
 /*-----------------------------------------------------------------*/
@@ -8115,7 +8555,7 @@ static void genJumpTab (iCode *ic)
     emitSKPNC;
     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
-    emitpLabel(jtab->key+100+labelOffset);
+    emitpLabel(jtab->key);
 
     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
 
@@ -8453,10 +8893,12 @@ static void genCast (iCode *ic)
     offset = 0 ;
     while (size--) {
       pic14_emitcode(";","%d",__LINE__);
-        aopPut(AOP(result),
-               aopGet(AOP(right),offset,FALSE,FALSE),
-               offset);
-        offset++;
+      /* aopPut(AOP(result),
+            aopGet(AOP(right),offset,FALSE,FALSE),
+            offset); */
+      emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
+      emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
+      offset++;
     }
 
     /* now depending on the sign of the destination */
@@ -8470,11 +8912,14 @@ static void genCast (iCode *ic)
       }
     } else {
       /* we need to extend the sign :{ */
-      //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
-      //MOVA(l);
 
-      emitpcode(POC_CLRW,    NULL);
-      emitpcode(POC_BTFSC,   popGet(AOP(right),0,FALSE,FALSE));
+      emitpcodeNULLop(POC_CLRW);
+
+      if(offset)
+       emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
+      else
+       emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
+
       emitpcode(POC_MOVLW,   popGetLit(0xff));
 
         pic14_emitcode("clrw","");
@@ -8646,7 +9091,7 @@ void genpic14Code (iCode *lic)
                         ic->level,ic->block);
                _G.debugLine = 0;
            }
-           pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
+           pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
            cln = ic->lineno ;
        }
        /* if the result is marked as