Fixed bug #621531 (const & volatile confusion in the type chain).
[fw/sdcc] / src / pic / gen.c
index 6057496d23188ae559de4775c6598427eda982ca..f8b48f8d243ca284937b96dfdb9a542947fccc0e 100644 (file)
@@ -1,5 +1,5 @@
 /*-------------------------------------------------------------------------
-  SDCCgen51.c - source file for code generation for 8051
+  gen.c - source file for code generation for pic
   
   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
 #include "SDCCglobl.h"
 #include "newalloc.h"
 
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
-#else
-#ifdef HAVE_MACHINE_ENDIAN_H
-#include <machine/endian.h>
-#else
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#else
-#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
-#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
-#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
-#endif
-#endif
-#endif
-#endif
-
 #include "common.h"
 #include "SDCCpeeph.h"
 #include "ralloc.h"
 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 void genMult8X8_8 (operand *, operand *,operand *);
+pCode *AssembleLine(char *line);
+extern void printpBlock(FILE *of, pBlock *pb);
 
 static int labelOffset=0;
-static int debug_verbose=1;
+extern int debug_verbose;
 static int optimized_for_speed = 0;
 
 /* max_key keeps track of the largest label number used in 
@@ -75,7 +60,7 @@ static int optimized_for_speed = 0;
 static int max_key=0;
 static int GpsuedoStkPtr=0;
 
-pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
+pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
 unsigned int pic14aopLiteral (value *val, int offset);
 const char *AopType(short type);
 static iCode *ifxForOp ( operand *op, iCode *ic );
@@ -231,7 +216,6 @@ void emitpLabel(int key)
 
 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
 {
-
   if(pcop)
     addpCode2pBlock(pb,newpCode(poc,pcop));
   else
@@ -245,6 +229,16 @@ void emitpcodeNULLop(PIC_OPCODE poc)
 
 }
 
+void emitpcodePagesel(const char *label)
+{
+
+  char code[81];
+  strcpy(code,"\tpagesel ");
+  strcat(code,label);
+  addpCode2pBlock(pb,newpCodeInlineP(code));
+
+}
+
 /*-----------------------------------------------------------------*/
 /* pic14_emitcode - writes the code into a file : for now it is simple    */
 /*-----------------------------------------------------------------*/
@@ -399,15 +393,17 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
   if(!resIfx) 
     return;
 
-  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+  //  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);
@@ -415,13 +411,15 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
       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);
+  //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
 
 }
 /*-----------------------------------------------------------------*/
@@ -534,11 +532,19 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
 
     /* special case for a function */
     if (IS_FUNC(sym->type)) {   
+
+      sym->aop = aop = newAsmop(AOP_PCODE);
+      aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
+      PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+      PCOI(aop->aopu.pcop)->_function = 1;
+      PCOI(aop->aopu.pcop)->index = 0;
+      aop->size = FPTRSIZE; 
+      /*
         sym->aop = aop = newAsmop(AOP_IMMD);    
-        //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
        aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
         strcpy(aop->aopu.aop_immd,sym->rname);
         aop->size = FPTRSIZE; 
+      */
        DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
         return aop;
     }
@@ -548,12 +554,12 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
     /* in which case DPTR gets the address */
     sym->aop = aop = newAsmop(AOP_PCODE);
 
-    aop->aopu.pcop = popGetImmd(sym->rname,0,0);
+    aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
     PCOI(aop->aopu.pcop)->index = 0;
 
-    DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
-                       sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+    DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+                       __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
 
     allocDirReg (IC_LEFT(ic));
 
@@ -603,12 +609,16 @@ static asmop *aopForRemat (operand *op) // x symbol *sym)
   }
 
   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
-  aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
+  aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
+#if 0
   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
+#else
+  PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
+#endif
   PCOI(aop->aopu.pcop)->index = val;
 
-  DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
-                     OP_SYMBOL(IC_LEFT(ic))->rname,
+  DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+                     __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
                      val, IS_PTR_CONST(operandType(op)));
 
   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
@@ -757,7 +767,11 @@ void aopOp (operand *op, iCode *ic, bool result)
 
     {
       sym_link *type = operandType(op);
+#if 0
       if(IS_PTR_CONST(type))
+#else
+      if(IS_CODEPTR(type))
+#endif
        DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
     }
 
@@ -824,22 +838,34 @@ void aopOp (operand *op, iCode *ic, bool result)
        }
 
         if (sym->ruonly ) {
-         /*
-         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
-         aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
-         //allocDirReg (IC_LEFT(ic));
-         aop->size = getSize(sym->type);
-         */
+         if(sym->isptr) {  // && sym->uptr 
+           aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
+           aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
 
-         unsigned i;
+           //PCOI(aop->aopu.pcop)->_const = 0;
+           //PCOI(aop->aopu.pcop)->index = 0;
+           /*
+             DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+             __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+           */
+           //allocDirReg (IC_LEFT(ic));
 
-         aop = op->aop = sym->aop = newAsmop(AOP_STR);
-         aop->size = getSize(sym->type);
-         for ( i = 0 ; i < fReturnSizePic ; i++ )
-           aop->aopu.aop_str[i] = fReturn[i];
+           aop->size = getSize(sym->type);
+           DEBUGpic14_emitcode(";","%d",__LINE__);
+           return;
 
-         DEBUGpic14_emitcode(";","%d",__LINE__);
-         return;
+         } else {
+
+           unsigned i;
+
+           aop = op->aop = sym->aop = newAsmop(AOP_STR);
+           aop->size = getSize(sym->type);
+           for ( i = 0 ; i < fReturnSizePic ; i++ )
+             aop->aopu.aop_str[i] = fReturn[i];
+
+           DEBUGpic14_emitcode(";","%d",__LINE__);
+           return;
+         }
         }
 
         /* else spill location  */
@@ -864,7 +890,11 @@ void aopOp (operand *op, iCode *ic, bool result)
 
     {
       sym_link *type = operandType(op);
+#if 0
       if(IS_PTR_CONST(type)) 
+#else
+      if(IS_CODEPTR(type)) 
+#endif
        DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
     }
 
@@ -1106,11 +1136,11 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
        return rs;
        
     case AOP_STR:
-        DEBUGpic14_emitcode(";","%d",__LINE__);
        aop->coff = offset ;
        if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
            dname)
            return "acc";
+        DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
        
        return aop->aopu.aop_str[offset];
        
@@ -1173,12 +1203,28 @@ pCodeOp *popGetLabel(unsigned int key)
 
   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
 
-  if(key>max_key)
+  if(key>(unsigned int)max_key)
     max_key = key;
 
   return newpCodeOpLabel(NULL,key+100+labelOffset);
 }
 
+/*-------------------------------------------------------------------*/
+/* popGetLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
+/*-------------------------------------------------------------------*/
+pCodeOp *popGetHighLabel(unsigned int key)
+{
+  pCodeOp *pcop;
+  DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
+
+  if(key>(unsigned int)max_key)
+    max_key = key;
+
+  pcop = newpCodeOpLabel(NULL,key+100+labelOffset);
+  PCOLAB(pcop)->offset = 1;
+  return pcop;
+}
+
 /*-----------------------------------------------------------------*/
 /* popCopyReg - copy a pcode operator                              */
 /*-----------------------------------------------------------------*/
@@ -1215,10 +1261,10 @@ pCodeOp *popGetLit(unsigned int lit)
 /*-----------------------------------------------------------------*/
 /* popGetImmd - asm operator to pcode immediate conversion         */
 /*-----------------------------------------------------------------*/
-pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
+pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
 {
 
-  return newpCodeOpImmd(name, offset,index, 0);
+  return newpCodeOpImmd(name, offset,index, 0, is_func);
 }
 
 
@@ -1322,7 +1368,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        
     case AOP_IMMD:
       DEBUGpic14_emitcode(";","%d",__LINE__);
-      return popGetImmd(aop->aopu.aop_immd,offset,0);
+      return popGetImmd(aop->aopu.aop_immd,offset,0,0);
 
     case AOP_DIR:
       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
@@ -1368,7 +1414,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        PCOR(pcop)->instance = offset;
        pcop->type = PCOR(pcop)->r->pc_type;
        //rs = aop->aopu.aop_reg[offset]->name;
-       //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
+       DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
        return pcop;
       }
 
@@ -1448,7 +1494,7 @@ void aopPut (asmop *aop, char *s, int offset)
              emitpcode(POC_CLRF,popGet(aop,offset));
              break;
            } else
-             emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
+             emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
          }
 
          emitpcode(POC_MOVWF,popGet(aop,offset));
@@ -1648,8 +1694,11 @@ void mov2w (asmop *aop, int offset)
   if(!aop)
     return;
 
+  DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
+
   if ( aop->type == AOP_PCODE ||
-       aop->type == AOP_LIT )
+       aop->type == AOP_LIT ||
+       aop->type == AOP_IMMD )
     emitpcode(POC_MOVLW,popGet(aop,offset));
   else
     emitpcode(POC_MOVFW,popGet(aop,offset));
@@ -1695,44 +1744,6 @@ static void reAdjustPreg (asmop *aop)
 
 }
 
-/*-----------------------------------------------------------------*/
-/* genNotFloat - generates not for float operations              */
-/*-----------------------------------------------------------------*/
-static void genNotFloat (operand *op, operand *res)
-{
-    int size, offset;
-    char *l;
-    symbol *tlbl ;
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* we will put 127 in the first byte of 
-    the result */
-    aopPut(AOP(res),"#127",0);
-    size = AOP_SIZE(op) - 1;
-    offset = 1;
-
-    l = aopGet(op->aop,offset++,FALSE,FALSE);
-    MOVA(l);    
-
-    while(size--) {
-        pic14_emitcode("orl","a,%s",
-                 aopGet(op->aop,
-                        offset++,FALSE,FALSE));
-    }
-    tlbl = newiTempLabel(NULL);
-
-    tlbl = newiTempLabel(NULL);
-    aopPut(res->aop,one,1);
-    pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
-    aopPut(res->aop,zero,1);
-    pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
-
-    size = res->aop->size - 2;
-    offset = 2;    
-    /* put zeros in the rest */
-    while (size--) 
-        aopPut(res->aop,zero,offset++);
-}
 
 #if 0
 /*-----------------------------------------------------------------*/
@@ -1847,7 +1858,6 @@ void pic14_toBoolean(operand *oper)
 static void genNot (iCode *ic)
 {
   symbol *tlbl;
-  sym_link *optype = operandType(IC_LEFT(ic));
   int size;
 
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -1869,13 +1879,7 @@ static void genNot (iCode *ic)
     goto release;
   }
 
-  /* if type float then do float */
-  if (IS_FLOAT(optype)) {
-    genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
-    goto release;
-  }
-
-  size = AOP_SIZE(IC_RESULT(ic));
+  size = AOP_SIZE(IC_LEFT(ic));
   if(size == 1) {
     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
     emitpcode(POC_ANDLW,popGetLit(1));
@@ -1901,39 +1905,42 @@ static void genNot (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genCpl (iCode *ic)
 {
-    int offset = 0;
-    int size ;
+  operand *left, *result;
+  int size, offset=0;  
 
 
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* assign asmOps to operand & result */
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  aopOp((left = IC_LEFT(ic)),ic,FALSE);
+  aopOp((result=IC_RESULT(ic)),ic,TRUE);
 
-    /* if both are in bit space then 
-    a special case */
-    if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
-        AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
+  /* if both are in bit space then 
+     a special case */
+  if (AOP_TYPE(result) == AOP_CRY &&
+      AOP_TYPE(left) == AOP_CRY ) { 
 
-        pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
-        pic14_emitcode("cpl","c"); 
-        pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
-        goto release; 
-    
+    pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
+    pic14_emitcode("cpl","c"); 
+    pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
+    goto release; 
+  } 
 
-    size = AOP_SIZE(IC_RESULT(ic));
-    while (size--) {
-        char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
-        MOVA(l);       
-        pic14_emitcode("cpl","a");
-        aopPut(AOP(IC_RESULT(ic)),"a",offset++);
-    }
+  size = AOP_SIZE(result);
+  while (size--) {
+
+    if(AOP_TYPE(left) == AOP_ACC) 
+      emitpcode(POC_XORLW, popGetLit(0xff));
+    else
+      emitpcode(POC_COMFW,popGet(AOP(left),offset));
+
+    emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+
+  }
 
 
 release:
     /* release the aops */
-    freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2162,6 +2169,7 @@ static void assignResultValue(operand * oper)
     size--;
     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
     GpsuedoStkPtr++;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
   }
 
   while (size--) {
@@ -2492,8 +2500,10 @@ static void genCall (iCode *ic)
 static void genPcall (iCode *ic)
 {
     sym_link *dtype;
-    symbol *rlbl = newiTempLabel(NULL);
-
+    symbol *albl = newiTempLabel(NULL);
+    symbol *blbl = newiTempLabel(NULL);
+    PIC_OPCODE poc;
+    operand *left;
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* if caller saves & we have not saved then */
@@ -2509,54 +2519,49 @@ static void genPcall (iCode *ic)
         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
-
-    /* push the return address on to the stack */
-    pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
-    pic14_emitcode("push","acc");    
-    pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
-    pic14_emitcode("push","acc");
-    
-    if (options.model == MODEL_FLAT24)
-    {
-       pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
-       pic14_emitcode("push","acc");    
-    }
-
-    /* now push the calling address */
-    aopOp(IC_LEFT(ic),ic,FALSE);
+    left = IC_LEFT(ic);
+    aopOp(left,ic,FALSE);
+    DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
 
     pushSide(IC_LEFT(ic), FPTRSIZE);
 
-    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
-
-    /* if send set is not empty the assign */
+    /* if send set is not empty, assign parameters */
     if (_G.sendSet) {
-       iCode *sic ;
 
-       for (sic = setFirstItem(_G.sendSet) ; sic ; 
-            sic = setNextItem(_G.sendSet)) {
-           int size, offset = 0;
-           aopOp(IC_LEFT(sic),sic,FALSE);
-           size = AOP_SIZE(IC_LEFT(sic));
-           while (size--) {
-               char *l = aopGet(AOP(IC_LEFT(sic)),offset,
-                               FALSE,FALSE);
-               if (strcmp(l,fReturn[offset]))
-                   pic14_emitcode("mov","%s,%s",
-                            fReturn[offset],
-                            l);
-               offset++;
-           }
-           freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
-       }
-       _G.sendSet = NULL;
+       DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
+       /* no way to pass args - W always gets used to make the call */
+    }
+/* first idea - factor out a common helper function and call it.
+   But don't know how to get it generated only once in its own block
+
+    if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
+           char *rname;
+           char *buffer;
+           rname = IC_LEFT(ic)->aop->aopu.aop_dir;
+           DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
+           buffer = Safe_calloc(1,strlen(rname)+16);
+           sprintf(buffer, "%s_goto_helper", rname);
+           addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
+           free(buffer);
     }
+*/
+    emitpcode(POC_CALL,popGetLabel(albl->key));
+    emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
+    emitpcode(POC_GOTO,popGetLabel(blbl->key));
+    emitpLabel(albl->key);
 
-    pic14_emitcode("ret","");
-    pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
+    poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
+    
+    emitpcode(poc,popGet(AOP(left),1));
+    emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+    emitpcode(poc,popGet(AOP(left),0));
+    emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
 
+    emitpLabel(blbl->key);
+
+    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
 
-    /* if we need assign a result value */
+    /* if we need to assign a result value */
     if ((IS_ITEMP(IC_RESULT(ic)) &&
          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
@@ -2571,20 +2576,6 @@ static void genPcall (iCode *ic)
         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
     }
 
-    /* adjust the stack for parameters if 
-    required */
-    if (ic->parmBytes) {
-        int i;
-        if (ic->parmBytes > 3) {
-            pic14_emitcode("mov","a,%s",spname);
-            pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
-            pic14_emitcode("mov","%s,a",spname);
-        } else 
-            for ( i = 0 ; i <  ic->parmBytes ;i++)
-                pic14_emitcode("dec","%s",spname);
-
-    }
-
     /* if register bank was saved then unsave them */
     if (currFunc && dtype && 
         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
@@ -2602,17 +2593,17 @@ static void genPcall (iCode *ic)
 /*-----------------------------------------------------------------*/
 static int resultRemat (iCode *ic)
 {
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if (SKIP_IC(ic) || ic->op == IFX)
-        return 0;
+  //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  if (SKIP_IC(ic) || ic->op == IFX)
+    return 0;
 
-    if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
-        symbol *sym = OP_SYMBOL(IC_RESULT(ic));
-        if (sym->remat && !POINTER_SET(ic)) 
-            return 1;
-    }
+  if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
+    symbol *sym = OP_SYMBOL(IC_RESULT(ic));
+    if (sym->remat && !POINTER_SET(ic)) 
+      return 1;
+  }
 
-    return 0;
+  return 0;
 }
 
 #if defined(__BORLANDC__) || defined(_MSC_VER)
@@ -2693,17 +2684,21 @@ static void genFunction (iCode *ic)
     }
 #endif
 
-    /* if this is an interrupt service routine then
-    save acc, b, dpl, dph  */
+    /* if this is an interrupt service routine */
     if (IFFUNC_ISISR(sym->type)) {
+/*  already done in pic14createInterruptVect() - delete me
       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
       emitpcodeNULLop(POC_NOP);
       emitpcodeNULLop(POC_NOP);
       emitpcodeNULLop(POC_NOP);
+*/
       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
+      emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
+      emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
+      emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* durring an interrupt PCLATH must be cleared before a goto or call statement */
 
       pBlockConvert2ISR(pb);
 #if 0  
@@ -2938,18 +2933,17 @@ static void genEndFunction (iCode *ic)
                pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
            _G.debugLine = 0;
        }
-       
-        pic14_emitcode ("reti","");
-
-       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
-       emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
-       emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
-       emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
-       emitpcode(POC_MOVFW,  popCopyReg(&pc_wsave));
-       addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
-
-       emitpcodeNULLop(POC_RETFIE);
 
+        pic14_emitcode ("reti","");
+        emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
+        emitpcode(POC_CLRF,   popCopyReg(&pc_status));
+        emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
+        emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
+        emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
+        addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
+        emitpcodeNULLop(POC_RETFIE);
     }
     else {
         if (IFFUNC_ISCRITICAL(sym->type))
@@ -3022,8 +3016,10 @@ static void genRet (iCode *ic)
       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) ) {
+      if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
+          AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
+         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
+         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
          emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
        }else {
          emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
@@ -3746,16 +3742,19 @@ static void genCmp (operand *left,operand *right,
   //  resolvedIfx rTrueIfx;
   symbol *truelbl;
   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(&rFalseIfx,ifx);
   truelbl  = newiTempLabel(NULL);
   size = max(AOP_SIZE(left),AOP_SIZE(right));
 
+  DEBUGpic14_AopType(__LINE__,left,right,result);
+
 #define _swapp
 
   /* if literal is on the right then swap with left */
@@ -3764,10 +3763,8 @@ static void genCmp (operand *left,operand *right,
     unsigned long mask = (0x100 << (8*(size-1))) - 1;
     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
 #ifdef _swapp
-    DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
-    lit = (lit - 1) & mask;
-    DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
 
+    lit = (lit - 1) & mask;
     right = left;
     left = tmp;
     rFalseIfx.condition ^= 1;
@@ -4035,7 +4032,8 @@ static void genCmp (operand *left,operand *right,
 
 
     }
-#endif
+#endif  // _swapp
+
     if(AOP_TYPE(left) == AOP_LIT) {
       //symbol *lbl = newiTempLabel(NULL);
 
@@ -4093,6 +4091,7 @@ static void genCmp (operand *left,operand *right,
            genSkipc(&rFalseIfx);
            break;
          }
+         if(ifx) ifx->generated = 1;
        } else {
          /* unsigned comparisons to a literal byte */
 
@@ -4100,10 +4099,12 @@ static void genCmp (operand *left,operand *right,
          case 0:
            emitpcode(POC_MOVFW, popGet(AOP(right),0));
            genSkipz2(&rFalseIfx,0);
+           if(ifx) ifx->generated = 1;
            break;
          case 0x7f:
            rFalseIfx.condition ^= 1;
            genSkipCond(&rFalseIfx,right,0,7);
+           if(ifx) ifx->generated = 1;
            break;
 
          default:
@@ -4111,12 +4112,21 @@ static void genCmp (operand *left,operand *right,
            emitpcode(POC_SUBFW, popGet(AOP(right),0));
            DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
            rFalseIfx.condition ^= 1;
-           genSkipc(&rFalseIfx);
+           if (AOP_TYPE(result) == AOP_CRY) {
+             genSkipc(&rFalseIfx);
+             if(ifx) ifx->generated = 1;
+           } else {
+             DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
+             emitpcode(POC_CLRF, popGet(AOP(result),0));
+             emitpcode(POC_RLF, popGet(AOP(result),0));
+             emitpcode(POC_MOVLW, popGetLit(0x01));
+             emitpcode(POC_XORWF, popGet(AOP(result),0));
+           }         
            break;
          }
        }
 
-       if(ifx) ifx->generated = 1;
+       //goto check_carry;
        return;
 
       } else {
@@ -4366,15 +4376,26 @@ static void genCmp (operand *left,operand *right,
     emitpLabel(lbl->key);
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    genSkipc(&rFalseIfx);
+    if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
+       (AOP_TYPE(result) == AOP_REG)) {
+      emitpcode(POC_CLRF, popGet(AOP(result),0));
+      emitpcode(POC_RLF, popGet(AOP(result),0));
+    } else {
+      genSkipc(&rFalseIfx);
+    }        
+    //genSkipc(&rFalseIfx);
     if(ifx) ifx->generated = 1;
+
     return;
 
   }
 
+  // check_carry:
   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
+    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     pic14_outBitC(result);
   } else {
+    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* if the result is used in the next
        ifx conditional branch then generate
        code a little differently */
@@ -4504,13 +4525,16 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
 {
   int size = max(AOP_SIZE(left),AOP_SIZE(right));
   int offset = 0;
+  int res_offset = 0;  /* the result may be a different size then left or right */
+  int res_size = AOP_SIZE(result);
   resolvedIfx rIfx;
   symbol *lbl;
 
   unsigned long lit = 0L;
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  DEBUGpic14_AopType(__LINE__,left,right,NULL);
-
+  DEBUGpic14_AopType(__LINE__,left,right,result);
+  if(result)
+    DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
   resolveIfx(&rIfx,ifx);
   lbl =  newiTempLabel(NULL);
 
@@ -4548,6 +4572,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        emitSKPNZ;
        emitpcode(POC_GOTO,popGetLabel(lbl->key));
        offset++;
+       if(res_offset < res_size-1)
+         res_offset++;
        lit >>= 8;
       }
       break;
@@ -4560,71 +4586,90 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
           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;
-      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))) {
+    //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
+    int lbl_key = lbl->key;
+
+    if(result) {
+      emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
+      //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+    }else {
+      DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
+      fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
+             __FUNCTION__,__LINE__);
+      return;
+    }
 
-         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-         emitpcode(POC_XORFW,popGet(AOP(right),offset));
+/*     switch(size) { */
+/*     case 2: */
+/*       genc16bit2lit(left, lit, 0); */
+/*       emitSKPNZ; */
+/*       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))) {
 
-       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
+       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+       emitpcode(POC_XORFW,popGet(AOP(right),offset));
+
+      } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
            
-         switch (lit & 0xff) {
-         case 0:
-           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-           break;
-         case 1:
-           emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
-           emitpcode(POC_GOTO,popGetLabel(lbl->key));
-           emit_skip=0;
-           break;
-         case 0xff:
-           emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
-           emitpcode(POC_GOTO,popGetLabel(lbl->key));
-           emit_skip=0;
-           break;
-         default:
-           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
-         }
-         lit >>= 8;
+       switch (lit & 0xff) {
+       case 0:
+         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+         break;
+       case 1:
+         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
+         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
+         emit_skip=0;
+         break;
+       case 0xff:
+         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
+         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
+         emitpcode(POC_GOTO,popGetLabel(lbl_key));
+         emit_skip=0;
+         break;
+       default:
+         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
+       }
+       lit >>= 8;
 
+      } else {
+       emitpcode(POC_MOVF,popGet(AOP(left),offset));
+      }
+      if(emit_skip) {
+       if(AOP_TYPE(result) == AOP_CRY) {
+         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
+         if(rIfx.condition)
+           emitSKPNZ;
+         else
+           emitSKPZ;
+         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
        } else {
-         emitpcode(POC_MOVF,popGet(AOP(left),offset));
-       }
-       if(emit_skip) {
-         if(AOP_TYPE(result) == AOP_CRY) {
-           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
-           if(rIfx.condition)
-             emitSKPNZ;
-           else
-             emitSKPZ;
-           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
-         } else {
-           /* fix me. probably need to check result size too */
-           emitpcode(POC_CLRF,popGet(AOP(result),0));
-           if(rIfx.condition)
-             emitSKPNZ;
-           else
-             emitSKPZ;
-           emitpcode(POC_INCF,popGet(AOP(result),0));
-         }
-         if(ifx)
-           ifx->generated=1;
+         /* fix me. probably need to check result size too */
+         //emitpcode(POC_CLRF,popGet(AOP(result),0));
+         if(rIfx.condition)
+           emitSKPZ;
+         else
+           emitSKPNZ;
+         emitpcode(POC_GOTO,popGetLabel(lbl_key));
+         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
        }
-       emit_skip++;
-       offset++;
+       if(ifx)
+         ifx->generated=1;
       }
-      break;
+      emit_skip++;
+      offset++;
+      if(res_offset < res_size-1)
+       res_offset++;
     }
+/*       break; */
+/*     } */
   } else if(AOP_TYPE(right) == AOP_REG &&
            AOP_TYPE(left) != AOP_DIR){
 
@@ -4638,6 +4683,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        emitSKPZ;
       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
       offset++;
+      if(res_offset < res_size-1)
+       res_offset++;
     }
       
   }else{
@@ -4651,8 +4698,15 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
       offset++;
     }
   }
+
+  emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+  if(!rIfx.condition)
+    emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+
   emitpLabel(lbl->key);
 
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
   if(ifx)
     ifx->generated = 1;
 }
@@ -4939,6 +4993,7 @@ static void genCmpEq (iCode *ic, iCode *ifx)
         pic14_outBitC(result);
     } else {
       
+      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
       gencjne(left,right,result,ifx);
 /*
       if(ifx) 
@@ -5025,7 +5080,7 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
 static void genAndOp (iCode *ic)
 {
     operand *left,*right, *result;
-    symbol *tlbl;
+/*     symbol *tlbl; */
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     /* note here that && operations that are in an
@@ -5035,20 +5090,26 @@ static void genAndOp (iCode *ic)
     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
     aopOp((result=IC_RESULT(ic)),ic,FALSE);
 
+    DEBUGpic14_AopType(__LINE__,left,right,result);
+
+    emitpcode(POC_MOVFW,popGet(AOP(left),0));
+    emitpcode(POC_ANDFW,popGet(AOP(right),0));
+    emitpcode(POC_MOVWF,popGet(AOP(result),0));
+
     /* if both are bit variables */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        AOP_TYPE(right) == AOP_CRY ) {
-        pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-        pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
-        pic14_outBitC(result);
-    } else {
-        tlbl = newiTempLabel(NULL);
-        pic14_toBoolean(left);    
-        pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
-        pic14_toBoolean(right);
-        pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-        pic14_outBitAcc(result);
-    }
+/*     if (AOP_TYPE(left) == AOP_CRY && */
+/*         AOP_TYPE(right) == AOP_CRY ) { */
+/*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
+/*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
+/*         pic14_outBitC(result); */
+/*     } else { */
+/*         tlbl = newiTempLabel(NULL); */
+/*         pic14_toBoolean(left);     */
+/*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
+/*         pic14_toBoolean(right); */
+/*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
+/*         pic14_outBitAcc(result); */
+/*     } */
 
     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
@@ -5359,7 +5420,7 @@ static void genAnd (iCode *ic, iCode *ifx)
            } else {
              pic14_emitcode("movlw","0x%x", (lit & 0xff));
              pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
-             if(know_W != (lit&0xff))
+             if(know_W != (int)(lit&0xff))
                emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
              know_W = lit &0xff;
              emitpcode(POC_ANDWF,popGet(AOP(left),offset));
@@ -5413,22 +5474,28 @@ static void genAnd (iCode *ic, iCode *ifx)
            emitpcode(POC_CLRF,popGet(AOP(result),offset));
            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));
+           if(AOP_TYPE(left) != AOP_ACC) {
+             pic14_emitcode("movf","%s,w",
+                            aopGet(AOP(left),offset,FALSE,FALSE));
+             pic14_emitcode("movwf","%s",
+                            aopGet(AOP(result),offset,FALSE,FALSE));
+             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+           }
            emitpcode(POC_MOVWF,popGet(AOP(result),offset));
            break;
          default:
-           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));
+           if(AOP_TYPE(left) == AOP_ACC) {
+             emitpcode(POC_ANDLW, popGetLit(t));
+           } else {
+             pic14_emitcode("movlw","0x%x",t);
+             pic14_emitcode("andwf","%s,w",
+                            aopGet(AOP(left),offset,FALSE,FALSE));
+             pic14_emitcode("movwf","%s",
+                            aopGet(AOP(result),offset,FALSE,FALSE));
              
-           emitpcode(POC_MOVLW, popGetLit(t));
-           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
+             emitpcode(POC_MOVLW, popGetLit(t));
+             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
+           }
            emitpcode(POC_MOVWF,popGet(AOP(result),offset));
          }
          continue;
@@ -5660,7 +5727,7 @@ static void genOr (iCode *ic, iCode *ifx)
              emitpcode(POC_BSF,
                        newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
            } else {
-             if(know_W != (lit & 0xff))
+             if(know_W != (int)(lit & 0xff))
                emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
              know_W = lit & 0xff;
              emitpcode(POC_IORWF, popGet(AOP(left),offset));
@@ -5714,25 +5781,20 @@ static void genOr (iCode *ic, iCode *ifx)
            int t = (lit >> (offset*8)) & 0x0FFL;
            switch(t) { 
            case 0x00:
-             emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
+             if (AOP_TYPE(left) != AOP_ACC) {
+               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
+             }
              emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
 
-             pic14_emitcode("movf","%s,w",
-                      aopGet(AOP(left),offset,FALSE,FALSE));
-             pic14_emitcode("movwf","%s",
-                      aopGet(AOP(result),offset,FALSE,FALSE));
              break;
            default:
-             emitpcode(POC_MOVLW,  popGetLit(t));
-             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
-             emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
-
-             pic14_emitcode("movlw","0x%x",t);
-             pic14_emitcode("iorwf","%s,w",
-                      aopGet(AOP(left),offset,FALSE,FALSE));
-             pic14_emitcode("movwf","%s",
-                      aopGet(AOP(result),offset,FALSE,FALSE));
-             
+             if (AOP_TYPE(left) == AOP_ACC) {
+               emitpcode(POC_IORLW,  popGetLit(t));
+             } else {
+               emitpcode(POC_MOVLW,  popGetLit(t));
+               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
+             }
+             emitpcode(POC_MOVWF,  popGet(AOP(result),offset));              
            }
            continue;
          }
@@ -5949,7 +6011,9 @@ static void genXor (iCode *ic, iCode *ifx)
        int t = (lit >> (offset*8)) & 0x0FFL;
        switch(t) { 
        case 0x00:
-         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+         if (AOP_TYPE(left) != AOP_ACC) {
+           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+         }
          emitpcode(POC_MOVWF,popGet(AOP(result),offset));
          pic14_emitcode("movf","%s,w",
                         aopGet(AOP(left),offset,FALSE,FALSE));
@@ -5957,16 +6021,20 @@ static void genXor (iCode *ic, iCode *ifx)
                         aopGet(AOP(result),offset,FALSE,FALSE));
          break;
        case 0xff:
-         emitpcode(POC_COMFW,popGet(AOP(left),offset));
+         if (AOP_TYPE(left) == AOP_ACC) {
+           emitpcode(POC_XORLW, popGetLit(t));
+         } else {
+           emitpcode(POC_COMFW,popGet(AOP(left),offset));
+         }
          emitpcode(POC_MOVWF,popGet(AOP(result),offset));
-         pic14_emitcode("comf","%s,w",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-         pic14_emitcode("movwf","%s",
-                        aopGet(AOP(result),offset,FALSE,FALSE));
          break;
        default:
-         emitpcode(POC_MOVLW, popGetLit(t));
-         emitpcode(POC_XORFW,popGet(AOP(left),offset));
+         if (AOP_TYPE(left) == AOP_ACC) {
+           emitpcode(POC_XORLW, popGetLit(t));
+         } else {
+           emitpcode(POC_MOVLW, popGetLit(t));
+           emitpcode(POC_XORFW,popGet(AOP(left),offset));
+         }
          emitpcode(POC_MOVWF,popGet(AOP(result),offset));
          pic14_emitcode("movlw","0x%x",t);
          pic14_emitcode("xorwf","%s,w",
@@ -6020,8 +6088,9 @@ static void genInline (iCode *ic)
     while (*bp) {
         if (*bp == '\n') {
             *bp++ = '\0';
-            pic14_emitcode(bp1,"");
-           addpCode2pBlock(pb,newpCodeInlineP(bp1));
+
+           if(*bp1)
+             addpCode2pBlock(pb,AssembleLine(bp1));
             bp1 = bp;
         } else {
             if (*bp == ':') {
@@ -6034,11 +6103,11 @@ static void genInline (iCode *ic)
                 bp++;
         }
     }
-    if (bp1 != bp) {
-        pic14_emitcode(bp1,"");
-       addpCode2pBlock(pb,newpCodeInlineP(bp1));
-    }
-    /*     pic14_emitcode("",buffer); */
+    if ((bp1 != bp) && *bp1)
+      addpCode2pBlock(pb,AssembleLine(bp1));
+
+    Safe_free(buffer);
+
     _G.inLine -= (!options.asmpeep);
 }
 
@@ -6709,10 +6778,12 @@ static void shiftR2Left2Result (operand *left, int offl,
     /* don't crash result[offr] */
     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-  } else {
+  }
+/* else {
     movLeft2Result(left,offl, result, offr);
     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
   }
+*/
   /* a:x >> shCount (x = lsb(result))*/
 /*
   if(sign)
@@ -6812,15 +6883,17 @@ static void shiftR2Left2Result (operand *left, int offl,
       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
-      emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
+      emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
+      emitpcode(POC_RLF,  popGet(AOP(result),offr));
+      emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
       emitpcode(POC_ANDLW,popGetLit(0x03));
       if(sign) {
        emitpcode(POC_BTFSC, 
                  newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
        emitpcode(POC_IORLW,popGetLit(0xfc));
       }
-      emitpcode(POC_MOVWF,popGet(AOP(result),offr));
-      emitpcode(POC_RLF,  popGet(AOP(result),offr));
+      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+      //emitpcode(POC_RLF,  popGet(AOP(result),offr));
 
        
     }
@@ -7885,7 +7958,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype)
     return ;
 }
 
-
+#if 0
 /*-----------------------------------------------------------------*/
 /* genDataPointerGet - generates code when ptr offset is known     */
 /*-----------------------------------------------------------------*/
@@ -7920,7 +7993,7 @@ static void genDataPointerGet (operand *left,
   freeAsmop(left,NULL,ic,TRUE);
   freeAsmop(result,NULL,ic,TRUE);
 }
-
+#endif
 /*-----------------------------------------------------------------*/
 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
 /*-----------------------------------------------------------------*/
@@ -7929,11 +8002,11 @@ static void genNearPointerGet (operand *left,
                               iCode *ic)
 {
     asmop *aop = NULL;
-    regs *preg = NULL ;
+    //regs *preg = NULL ;
     char *rname ;
     sym_link *rtype, *retype;
     sym_link *ltype = operandType(left);    
-    char buffer[80];
+    //char buffer[80];
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -8293,6 +8366,7 @@ static void genConstPointerGet (operand *left,
   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
 
   emitpcode(POC_CALL,popGetLabel(albl->key));
+  emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
   emitpcode(POC_GOTO,popGetLabel(blbl->key));
   emitpLabel(albl->key);
 
@@ -8331,7 +8405,11 @@ static void genPointerGet (iCode *ic)
     type = operandType(left);
     etype = getSpec(type);
 
+#if 0
     if (IS_PTR_CONST(type))
+#else
+    if (IS_CODEPTR(type))
+#endif
       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
 
     /* if left is of type of pointer then it is simple */
@@ -8387,9 +8465,11 @@ static void genPointerGet (iCode *ic)
        break;
 
     case GPOINTER:
+#if 0
       if (IS_PTR_CONST(type))
        genConstPointerGet (left,result,ic);
       else
+#endif
        genGenPointerGet (left,result,ic);
       break;
     }
@@ -8908,9 +8988,17 @@ static void genGenPointerSet (operand *right,
       /* hack hack! see if this the FSR. If so don't load W */
       if(AOP_TYPE(right) != AOP_ACC) {
 
+
        emitpcode(POC_MOVFW,popGet(AOP(result),0));
        emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
 
+       if(AOP_SIZE(result) > 1) {
+         emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
+         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
+         emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
+
+       }
+
        //if(size==2)
        //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
        //if(size==4) {
@@ -9243,7 +9331,7 @@ static void genAssign (iCode *ic)
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if(AOP_TYPE(right) == AOP_LIT) {
       if(lit&0xff) {
-       if(know_W != (lit&0xff))
+       if(know_W != (int)(lit&0xff))
          emitpcode(POC_MOVLW,popGetLit(lit&0xff));
        know_W = lit&0xff;
        emitpcode(POC_MOVWF, popGet(AOP(result),offset));
@@ -9259,8 +9347,7 @@ static void genAssign (iCode *ic)
        emitpcode(POC_INCF, popGet(AOP(result),0));
       }
     } else {
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-      emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+      mov2w (AOP(right), offset);
       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
     }
            
@@ -9296,6 +9383,8 @@ static void genJumpTab (iCode *ic)
     pic14_emitcode("jmp","@a+dptr");
     pic14_emitcode("","%05d_DS_:",jtab->key+100);
 
+    emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
+    emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
     emitSKPNC;
@@ -9538,9 +9627,17 @@ static void genCast (iCode *ic)
        goto release;
 
       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+#if 0
       if (IS_PTR_CONST(rtype))
+#else
+      if (IS_CODEPTR(rtype))
+#endif
        DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
+#if 0
       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+#else
+      if (IS_CODEPTR(operandType(IC_RESULT(ic))))
+#endif
        DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
 
       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
@@ -9787,10 +9884,10 @@ static int genDjnz (iCode *ic, iCode *ifx)
 /* genReceive - generate code for a receive iCode                  */
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode *ic)
-{    
+{
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-  if (isOperandInFarSpace(IC_RESULT(ic)) && 
+  if (isOperandInFarSpace(IC_RESULT(ic)) &&
       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
        IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
 
@@ -9801,24 +9898,36 @@ static void genReceive (iCode *ic)
                                    fReturn[fReturnSizePic - offset - 1] : "acc"));
       offset++;
     }
-    aopOp(IC_RESULT(ic),ic,FALSE);  
+    aopOp(IC_RESULT(ic),ic,FALSE);
     size = AOP_SIZE(IC_RESULT(ic));
     offset = 0;
     while (size--) {
       pic14_emitcode ("pop","acc");
       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
     }
-       
+
   } else {
     _G.accInUse++;
-    aopOp(IC_RESULT(ic),ic,FALSE);  
+    aopOp(IC_RESULT(ic),ic,FALSE);
     _G.accInUse--;
-    assignResultValue(IC_RESULT(ic));  
+    assignResultValue(IC_RESULT(ic));
   }
 
   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  pic14_emitcode ("; genDummyRead","");
+  pic14_emitcode ("; not implemented","");
+
+  ic = ic;
+}
+
 /*-----------------------------------------------------------------*/
 /* genpic14Code - generate code for pic14 based controllers        */
 /*-----------------------------------------------------------------*/
@@ -9844,7 +9953,7 @@ void genpic14Code (iCode *lic)
     /* if debug information required */
     if (options.debug && currFunc) { 
       if (currFunc) {
-       cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
+       debugFile->writeFunction(currFunc);
        _G.debugLine = 1;
        if (IS_STATIC(currFunc->etype)) {
          pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
@@ -9874,13 +9983,18 @@ void genpic14Code (iCode *lic)
              pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
              printCLine(ic->filename, ic->lineno));
            */
-           addpCode2pBlock(pb,
-                           newpCodeCSource(ic->lineno, 
-                                           ic->filename, 
-                                           printCLine(ic->filename, ic->lineno)));
+           if (!options.noCcodeInAsm) {
+             addpCode2pBlock(pb,
+                             newpCodeCSource(ic->lineno, 
+                                             ic->filename, 
+                                             printCLine(ic->filename, ic->lineno)));
+           }
 
            cln = ic->lineno ;
        }
+
+       // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
+
        /* if the result is marked as
           spilt and rematerializable or code for
           this has already been generated then
@@ -10071,13 +10185,17 @@ void genpic14Code (iCode *lic)
            addSet(&_G.sendSet,ic);
            break;
 
+       case DUMMY_READ_VOLATILE:
+         genDummyRead (ic);
+         break;
+
        default :
            ic = ic;
         }
     }
-    
 
-    /* now we are ready to call the 
+
+    /* now we are ready to call the
        peep hole optimizer */
     if (!options.nopeep) {
       peepHole (&lineHead);