* device/lib/printf_large.c: 6 bytes less __data mem (6 more __idata)
[fw/sdcc] / src / pic / genarith.c
index 8bb0747804671a5767aaf656198901baf32dd98c..1f5515ed69b0c64bf642d225c55fcce2895f05de 100644 (file)
@@ -25,8 +25,8 @@
   what you give them.   Help stamp out software-hoarding!
   
   Notes:
-  000123 mlh   Moved aopLiteral to SDCCglue.c to help the split
-               Made everything static
+  000123 mlh  Moved aopLiteral to SDCCglue.c to help the split
+      Made everything static
 -------------------------------------------------------------------------*/
 
 #include <stdio.h>
@@ -37,7 +37,7 @@
 #include "newalloc.h"
 
 #if defined(_MSC_VER) && (_MSC_VER < 1300)
-#define __FUNCTION__           __FILE__
+#define __FUNCTION__    __FILE__
 #endif
 
 #include "common.h"
@@ -97,6 +97,47 @@ const char *AopType(short type)
        return "BAD TYPE";
 }
 
+void DebugAop(asmop *aop)
+{
+       if(!aop)
+               return;
+       printf("%s\n",AopType(aop->type));
+       printf(" current offset: %d\n",aop->coff);
+       printf("           size: %d\n",aop->size);
+       
+       switch(aop->type) {
+       case AOP_LIT:
+               printf("          name: %s\n",aop->aopu.aop_lit->name);
+               break;
+       case AOP_REG:
+               printf("          name: %s\n",aop->aopu.aop_reg[0]->name);
+               break;
+       case AOP_CRY:
+       case AOP_DIR:
+               printf("          name: %s\n",aop->aopu.aop_dir);
+               break;
+       case AOP_DPTR:
+       case AOP_DPTR2:
+       case AOP_R0:
+       case AOP_R1:
+       case AOP_ACC:
+               printf("not supported\n");
+               break;
+       case AOP_STK:
+               printf("   Stack offset: %d\n",aop->aopu.aop_stk);
+               break;
+       case AOP_IMMD:
+               printf("     immediate: %s\n",aop->aopu.aop_immd);
+               break;
+       case AOP_STR:
+               printf("    aop_str[0]: %s\n",aop->aopu.aop_str[0]);
+               break;
+       case AOP_PCODE:
+               //printpCode(stdout,aop->aopu.pcop);
+               break;
+       }
+}
+
 const char *pCodeOpType(  pCodeOp *pcop)
 {
        
@@ -159,6 +200,7 @@ bool genPlusIncr (iCode *ic)
 {
        unsigned int icount ;
        unsigned int size = pic14_getDataSize(IC_RESULT(ic));
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
@@ -251,6 +293,7 @@ void pic14_outBitAcc(operand *result)
 {
        symbol *tlbl = newiTempLabel(NULL);
        /* if the result is a bit */
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        if (AOP_TYPE(result) == AOP_CRY){
@@ -264,82 +307,6 @@ void pic14_outBitAcc(operand *result)
        }
 }
 
-/*-----------------------------------------------------------------*/
-/* genPlusBits - generates code for addition of two bits           */
-/*-----------------------------------------------------------------*/
-void genPlusBits (iCode *ic)
-{
-       
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       
-       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))));
-               /*
-               The following block of code will add two bits. 
-               Note that it'll even work if the destination is
-               the carry (C in the status register).
-               It won't work if the 'Z' bit is a source or destination.
-       */
-       
-       /* If the result is stored in the accumulator (w) */
-       //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
-       switch(AOP_TYPE(IC_RESULT(ic))) {
-       case AOP_ACC:
-               emitpcode(POC_CLRW, NULL);
-               emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
-               emitpcode(POC_XORLW, popGetLit(1));
-               emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
-               emitpcode(POC_XORLW, popGetLit(1));
-               
-               pic14_emitcode("clrw","");
-               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                       AOP(IC_RIGHT(ic))->aopu.aop_dir,
-                       AOP(IC_RIGHT(ic))->aopu.aop_dir);
-               pic14_emitcode("xorlw","1");
-               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                       AOP(IC_LEFT(ic))->aopu.aop_dir,
-                       AOP(IC_LEFT(ic))->aopu.aop_dir);
-               pic14_emitcode("xorlw","1");
-               break;
-       case AOP_REG:
-               emitpcode(POC_MOVLW, popGetLit(0));
-               emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
-               emitpcode(POC_XORLW, popGetLit(1));
-               emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
-               emitpcode(POC_XORLW, popGetLit(1));
-               emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
-               break;
-       default:
-               emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
-               emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
-               emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
-               emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
-               emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
-               emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
-               
-               pic14_emitcode("movlw","(1 << (%s & 7))",
-                       AOP(IC_RESULT(ic))->aopu.aop_dir,
-                       AOP(IC_RESULT(ic))->aopu.aop_dir);
-               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
-                       AOP(IC_RESULT(ic))->aopu.aop_dir,
-                       AOP(IC_RESULT(ic))->aopu.aop_dir);
-               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                       AOP(IC_RIGHT(ic))->aopu.aop_dir,
-                       AOP(IC_RIGHT(ic))->aopu.aop_dir);
-               pic14_emitcode("xorwf","(%s >>3),f",
-                       AOP(IC_RESULT(ic))->aopu.aop_dir);
-               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                       AOP(IC_LEFT(ic))->aopu.aop_dir,
-                       AOP(IC_LEFT(ic))->aopu.aop_dir);
-               pic14_emitcode("xorwf","(%s>>3),f",
-                       AOP(IC_RESULT(ic))->aopu.aop_dir);
-               break;
-       }
-       
-}
-
 #if 0
 /* This is the original version of this code.
 *
@@ -397,7 +364,7 @@ static void adjustArithmeticResult(iCode *ic)
                        GPTRSIZE - 1);
        }
        
-       if (opIsGptr(IC_RESULT(ic))        &&
+       if (opIsGptr(IC_RESULT(ic))      &&
                AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE   &&
                AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE  &&
                !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
@@ -414,6 +381,7 @@ static void adjustArithmeticResult(iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genAddLit2byte (operand *result, int offr, int lit)
 {
+       FENTRY;
        
        switch(lit & 0xff) {
        case 0:
@@ -433,6 +401,7 @@ static void genAddLit2byte (operand *result, int offr, int lit)
 
 static void emitMOVWF(operand *reg, int offset)
 {
+       FENTRY;
        if(!reg)
                return;
        
@@ -454,6 +423,7 @@ static void genAddLit (iCode *ic, int lit)
        operand *result;
        operand *left;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        
        
@@ -461,6 +431,8 @@ static void genAddLit (iCode *ic, int lit)
        result = IC_RESULT(ic);
        same = pic14_sameRegs(AOP(left), AOP(result));
        size = pic14_getDataSize(result);
+       if (size > pic14_getDataSize(left))
+               size = pic14_getDataSize(left);
        
        if(same) {
                
@@ -519,7 +491,7 @@ static void genAddLit (iCode *ic, int lit)
                                                emitpcode(POC_INCFSZW, popGet(AOP(result),0));
                                                emitpcode(POC_INCF, popGet(AOP(result),MSB16));
                                                emitpcode(POC_INCF, popGet(AOP(result),MSB16));
-                                       }         
+                                       }   
                                        break;
                                        
                                        case 0xff:
@@ -533,7 +505,7 @@ static void genAddLit (iCode *ic, int lit)
                                                        emitpcode(POC_INCFSZ, popGet(AOP(result),0));
                                                        emitpcode(POC_DECF, popGet(AOP(result),MSB16));
                                                        break;
-                                                       /*      case 0xff: * 0xffff *
+                                                       /*  case 0xff: * 0xffff *
                                                        emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
                                                        emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
                                                        emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
@@ -563,13 +535,13 @@ static void genAddLit (iCode *ic, int lit)
                                                                emitpcode(POC_MOVLW,popGetLit(hi));
                                                                emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
                                                                break;
-                                                               /*      case 0xff: * 0xHHff *
+                                                               /*  case 0xff: * 0xHHff *
                                                                emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
                                                                emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
                                                                emitpcode(POC_MOVLW,popGetLit(hi));
                                                                emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
                                                                break;
-                                                               */      default:  /* 0xHHLL */
+                                                               */  default:  /* 0xHHLL */
                                                                emitpcode(POC_MOVLW,popGetLit(lo));
                                                                emitpcode(POC_ADDWF, popGet(AOP(result),0));
                                                                emitpcode(POC_MOVLW,popGetLit(hi));
@@ -579,197 +551,201 @@ static void genAddLit (iCode *ic, int lit)
                                                                break;
                                                        }
                                                        
-         }
-       } else {
-               int carry_info = 0;
-               int offset = 0;
-               /* size > 2 */
-               DEBUGpic14_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
-               
-               while(size--) {
-                       lo = BYTEofLONG(lit,0);
+                       }
+               } else {
+                       int carry_info = 0;
+                       int offset = 0;
+                       /* size > 2 */
+                       DEBUGpic14_emitcode (";  add lit to long","%s  %d",__FUNCTION__,__LINE__);
                        
-                       if(carry_info) {
-                               switch(lo) {
-                               case 0:
-                                       switch(carry_info) {
-                                       case 1:
-                                               emitSKPNZ;
-                                               emitpcode(POC_INCF, popGet(AOP(result),offset));
+                       while(size--) {
+                               lo = BYTEofLONG(lit,0);
+                               
+                               if(carry_info) {
+                                       switch(lo) {
+                                       case 0:
+                                               switch(carry_info) {
+                                               case 1:
+                                                       emitSKPNZ;
+                                                       emitpcode(POC_INCF, popGet(AOP(result),offset));
+                                                       break;
+                                               case 2:
+                                                       emitpcode(POC_RLFW, popGet(AOP(result),offset));
+                                                       emitpcode(POC_ANDLW,popGetLit(1));
+                                                       emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+                                                       break;
+                                               default: /* carry_info = 3  */
+                                                       emitSKPNC;
+                                                       emitpcode(POC_INCF, popGet(AOP(result),offset));
+                                                       carry_info = 1;
+                                                       break;
+                                               }
                                                break;
-                                       case 2:
-                                               emitpcode(POC_RLFW, popGet(AOP(result),offset));
-                                               emitpcode(POC_ANDLW,popGetLit(1));
-                                               emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+                                               case 0xff:
+                                                       emitpcode(POC_MOVLW,popGetLit(lo));
+                                                       if(carry_info==1) 
+                                                               emitSKPZ;
+                                                       else
+                                                               emitSKPC;
+                                                       emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+                                                       break;
+                                               default:
+                                                       emitpcode(POC_MOVLW,popGetLit(lo));
+                                                       if(carry_info==1) 
+                                                               emitSKPNZ;
+                                                       else
+                                                               emitSKPNC;
+                                                       emitpcode(POC_MOVLW,popGetLit(lo+1));
+                                                       emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+                                                       carry_info=2;
+                                                       break;
+                                       }
+                               }else {
+                                       /* no carry info from previous step */
+                                       /* this means this is the first time to add */
+                                       switch(lo) {
+                                       case 0:
                                                break;
-                                       default: /* carry_info = 3  */
-                                               emitSKPNC;
+                                       case 1:
                                                emitpcode(POC_INCF, popGet(AOP(result),offset));
-                                               carry_info = 1;
+                                               carry_info=1;
                                                break;
-                                       }
-                                       break;
-                                       case 0xff:
+                                       default:
                                                emitpcode(POC_MOVLW,popGetLit(lo));
-                                               if(carry_info==1) 
-                                                       emitSKPZ;
-                                               else
-                                                       emitSKPC;
                                                emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+                                               if(lit <0x100) 
+                                                       carry_info = 3;  /* Were adding only one byte and propogating the carry */
+                                               else
+                                                       carry_info = 2;
                                                break;
-                                       default:
-                                               emitpcode(POC_MOVLW,popGetLit(lo));
-                                               if(carry_info==1) 
+                                       }
+                               }
+                               offset++;
+                               lit >>= 8;
+                       }
+                       
+                       /*
+                               lo = BYTEofLONG(lit,0);
+                       
+                               if(lit < 0x100) {
+                                       if(lo) {
+                                               if(lo == 1) {
+                                                       emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
                                                        emitSKPNZ;
-                                               else
+                                               } else {
+                                                       emitpcode(POC_MOVLW,popGetLit(lo));
+                                                       emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
                                                        emitSKPNC;
-                                               emitpcode(POC_MOVLW,popGetLit(lo+1));
-                                               emitpcode(POC_ADDWF, popGet(AOP(result),offset));
-                                               carry_info=2;
-                                               break;
+                                               }
+                                               emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
+                                               emitSKPNZ;
+                                               emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
+                                               emitSKPNZ;
+                                               emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
+                                               
+                                       } 
+                               } 
+                               
+                       */
+               }
+       } else {
+               int offset = 1;
+               DEBUGpic14_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
+               
+               if(size == 1) {
+                       
+                       if(AOP_TYPE(left) == AOP_ACC) {
+                               /* left addend is already in accumulator */
+                               switch(lit & 0xff) {
+                               case 0:
+                                       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+                                       emitMOVWF(result,0);
+                                       break;
+                               default:
+                                       emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
+                                       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+                                       emitMOVWF(result,0);
                                }
-                       }else {
-                               /* no carry info from previous step */
-                               /* this means this is the first time to add */
-                               switch(lo) {
+                       } else {
+                               /* left addend is in a register */
+                               switch(lit & 0xff) {
                                case 0:
+                                       emitpcode(POC_MOVFW, popGet(AOP(left),0));
+                                       emitMOVWF(result, 0);
+                                       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+                                       emitMOVWF(result,0);
                                        break;
                                case 1:
-                                       emitpcode(POC_INCF, popGet(AOP(result),offset));
-                                       carry_info=1;
+                                       emitpcode(POC_INCFW, popGet(AOP(left),0));
+                                       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+                                       emitMOVWF(result,0);
                                        break;
-                               default:
-                                       emitpcode(POC_MOVLW,popGetLit(lo));
-                                       emitpcode(POC_ADDWF, popGet(AOP(result),offset));
-                                       if(lit <0x100) 
-                                               carry_info = 3;  /* Were adding only one byte and propogating the carry */
-                                       else
-                                               carry_info = 2;
+                               case 0xff:
+                                       emitpcode(POC_DECFW, popGet(AOP(left),0));
+                                       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+                                       emitMOVWF(result,0);
                                        break;
+                               default:
+                                       emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+                                       emitpcode(POC_ADDFW, popGet(AOP(left),0));
+                                       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+                                       emitMOVWF(result,0);
                                }
                        }
-                       offset++;
-                       lit >>= 8;
-               }
-               
-               /*
-               lo = BYTEofLONG(lit,0);
-
-               if(lit < 0x100) {
-                       if(lo) {
-                               if(lo == 1) {
-                                       emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
-                                       emitSKPNZ;
+                       
+               } else {
+                       int clear_carry=0;
+                       
+                       /* left is not the accumulator */
+                       if(lit & 0xff) {
+                               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+                               emitpcode(POC_ADDFW, popGet(AOP(left),0));
+                       } else {
+                               emitpcode(POC_MOVFW, popGet(AOP(left),0));
+                               /* We don't know the state of the carry bit at this point */
+                               clear_carry = 1;
+                       }
+                       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+                       emitMOVWF(result,0);
+                       while(--size) {
+                               
+                               lit >>= 8;
+                               if(lit & 0xff) {
+                                       if(clear_carry) {
+                                       /* The ls byte of the lit must've been zero - that 
+                                               means we don't have to deal with carry */
+                                               
+                                               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+                                               emitpcode(POC_ADDFW,  popGet(AOP(left),offset));
+                                               emitpcode(POC_MOVWF, popGet(AOP(left),offset));
+                                               
+                                               clear_carry = 0;
+                                               
+                                       } else {
+                                               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+                                               //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
+                                               emitMOVWF(result,offset);
+                                               emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+                                               emitSKPNC;
+                                               emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
+                                               emitpcode(POC_ADDWF,  popGet(AOP(result),offset));
+                                       }
+                                       
                                } else {
-                                       emitpcode(POC_MOVLW,popGetLit(lo));
-                                       emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
-                                       emitSKPNC;
+                                       emitpcode(POC_CLRF,  popGet(AOP(result),offset));
+                                       emitpcode(POC_RLF,   popGet(AOP(result),offset));
+                                       emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+                                       emitpcode(POC_ADDWF, popGet(AOP(result),offset));
                                }
-                               emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
-                               emitSKPNZ;
-                               emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
-                               emitSKPNZ;
-                               emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
-
-                               } 
-                       } 
+                               offset++;
+                       }
                }
-                       
-               */
        }
-  } else {
-         int offset = 1;
-         DEBUGpic14_emitcode (";  left and result aren't same","%s  %d",__FUNCTION__,__LINE__);
-         
-         if(size == 1) {
-                 
-                 if(AOP_TYPE(left) == AOP_ACC) {
-                         /* left addend is already in accumulator */
-                         switch(lit & 0xff) {
-                         case 0:
-                                 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
-                                 emitMOVWF(result,0);
-                                 break;
-                         default:
-                                 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
-                                 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
-                                 emitMOVWF(result,0);
-                         }
-                 } else {
-                         /* left addend is in a register */
-                         switch(lit & 0xff) {
-                         case 0:
-                                 emitpcode(POC_MOVFW, popGet(AOP(left),0));
-                                 emitMOVWF(result, 0);
-                                 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
-                                 emitMOVWF(result,0);
-                                 break;
-                         case 1:
-                                 emitpcode(POC_INCFW, popGet(AOP(left),0));
-                                 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
-                                 emitMOVWF(result,0);
-                                 break;
-                         case 0xff:
-                                 emitpcode(POC_DECFW, popGet(AOP(left),0));
-                                 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
-                                 emitMOVWF(result,0);
-                                 break;
-                         default:
-                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-                                 emitpcode(POC_ADDFW, popGet(AOP(left),0));
-                                 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
-                                 emitMOVWF(result,0);
-                         }
-                 }
-                 
-         } else {
-                 int clear_carry=0;
-                 
-                 /* left is not the accumulator */
-                 if(lit & 0xff) {
-                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
-                 } else {
-                         emitpcode(POC_MOVFW, popGet(AOP(left),0));
-                         /* We don't know the state of the carry bit at this point */
-                         clear_carry = 1;
-                 }
-                 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
-                 emitMOVWF(result,0);
-                 while(--size) {
-                         
-                         lit >>= 8;
-                         if(lit & 0xff) {
-                                 if(clear_carry) {
-                                 /* The ls byte of the lit must've been zero - that 
-                                         means we don't have to deal with carry */
-                                         
-                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-                                         emitpcode(POC_ADDFW,  popGet(AOP(left),offset));
-                                         emitpcode(POC_MOVWF, popGet(AOP(left),offset));
-                                         
-                                         clear_carry = 0;
-                                         
-                                 } else {
-                                         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-                                         //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
-                                         emitMOVWF(result,offset);
-                                         emitpcode(POC_MOVFW, popGet(AOP(left),offset));
-                                         emitSKPNC;
-                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
-                                         emitpcode(POC_ADDWF,  popGet(AOP(result),offset));
-                                 }
-                                 
-                         } else {
-                                 emitpcode(POC_CLRF,  popGet(AOP(result),offset));
-                                 emitpcode(POC_RLF,   popGet(AOP(result),offset));
-                                 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
-                                 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
-                         }
-                         offset++;
-                 }
-         }
-  }
+
+       size = pic14_getDataSize(result);
+       if (size > pic14_getDataSize(left))
+               size = pic14_getDataSize(left);
+       addSign(result, size, 0);
 }
 
 /*-----------------------------------------------------------------*/
@@ -781,6 +757,7 @@ void genPlus (iCode *ic)
        
        /* special cases :- */
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       FENTRY;
        
        aopOp (IC_LEFT(ic),ic,FALSE);
        aopOp (IC_RIGHT(ic),ic,FALSE);
@@ -798,13 +775,6 @@ void genPlus (iCode *ic)
                IC_LEFT(ic) = t;
        }
        
-       /* if both left & right are in bit space */
-       if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
-               AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
-               genPlusBits (ic);
-               goto release ;
-       }
-       
        /* if left in bit space & right literal */
        if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
                AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
@@ -962,11 +932,9 @@ void genPlus (iCode *ic)
                                else {
                                        PIC_OPCODE poc = POC_ADDFW;
                                        
-                                       if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                                       if (op_isLitLike (IC_LEFT (ic)))
                                                poc = POC_ADDLW;
-                                       emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
+                                       emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
                                        if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
                                                emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
                                }
@@ -979,14 +947,13 @@ void genPlus (iCode *ic)
                
                if(size){
                        if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
+                               if (op_isLitLike (IC_LEFT(ic)))
+                               {
                                        while(size--){
                                                emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
                                                emitSKPNC;
                                                emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
-                                               emitpcode(POC_ADDLW,   popGet(AOP(IC_LEFT(ic)),offset));
+                                               emitpcode(POC_ADDLW,   popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                                emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
                                                offset++;
                                        }
@@ -1001,13 +968,11 @@ void genPlus (iCode *ic)
                                }
                        } else {
                                PIC_OPCODE poc = POC_MOVFW;
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                               if (op_isLitLike (IC_LEFT(ic)))
                                        poc = POC_MOVLW;
                                while(size--){
                                        if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-                                               emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
+                                               emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                                emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
                                        }
                                        emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
@@ -1032,15 +997,15 @@ void genPlus (iCode *ic)
                if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { 
                        int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
                        PIC_OPCODE poc = POC_MOVFW;
-                       if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                       if (op_isLitLike (IC_LEFT(ic)))
                                poc = POC_MOVLW;
                        while(leftsize-- > 0) {
-                               emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
-                               emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+                               emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                emitSKPNC;
-                               emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
+                               emitpcode(POC_ADDLW, popGetLit(0x01));
+                               emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+                               //emitSKPNC;
+                               //emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); /* INCF does not update Carry! */
                                offset++;
                                if (size)
                                        size--;
@@ -1053,7 +1018,7 @@ void genPlus (iCode *ic)
                }
                
                
-               if(sign) {
+               if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
                /* Now this is really horrid. Gotta check the sign of the addends and propogate
                        * to the result */
                        
@@ -1098,6 +1063,7 @@ bool genMinusDec (iCode *ic)
 {
        unsigned int icount ;
        unsigned int size = pic14_getDataSize(IC_RESULT(ic));
+       FENTRY;
        
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        /* will try to generate an increment */
@@ -1166,8 +1132,8 @@ bool genMinusDec (iCode *ic)
                AOP_SIZE(IC_LEFT(ic)) > 1   )
                return FALSE ;
        
-               /* we can if the aops of the left & result match or
-               if they are in registers and the registers are the
+       /* we can if the aops of the left & result match or
+       if they are in registers and the registers are the
        same */
        if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
                
@@ -1203,6 +1169,7 @@ void addSign(operand *result, int offset, int sign)
 {
        int size = (pic14_getDataSize(result) - offset);
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       FENTRY;
        
        if(size > 0){
                if(sign && offset) {
@@ -1217,8 +1184,7 @@ void addSign(operand *result, int offset, int sign)
                                emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
                                emitpcode(POC_MOVLW, popGetLit(0xff));
                                while(size--)
-                                       emitpcode(POC_MOVWF, popGet(AOP(result),size));
-                               
+                                       emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
                        }
                } else
                        while(size--)
@@ -1226,31 +1192,6 @@ void addSign(operand *result, int offset, int sign)
        }
 }
 
-/*-----------------------------------------------------------------*/
-/* genMinusBits - generates code for subtraction  of two bits      */
-/*-----------------------------------------------------------------*/
-void genMinusBits (iCode *ic)
-{
-       symbol *lbl = newiTempLabel(NULL);
-       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
-               pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
-               pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
-               pic14_emitcode("cpl","c");
-               pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-               pic14_outBitC(IC_RESULT(ic));
-       }
-       else{
-               pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
-               pic14_emitcode("subb","a,acc");
-               pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
-               pic14_emitcode("inc","a");
-               pic14_emitcode("","%05d_DS_:",(lbl->key+100));
-               aopPut(AOP(IC_RESULT(ic)),"a",0);
-               addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
-       }
-}
-
 /*-----------------------------------------------------------------*/
 /* genMinus - generates code for subtraction                       */
 /*-----------------------------------------------------------------*/
@@ -1259,6 +1200,7 @@ void genMinus (iCode *ic)
        int size, offset = 0, same=0;
        unsigned long lit = 0L;
        
+       FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        aopOp (IC_LEFT(ic),ic,FALSE);
        aopOp (IC_RIGHT(ic),ic,FALSE);
@@ -1276,14 +1218,6 @@ void genMinus (iCode *ic)
                AopType(AOP_TYPE(IC_LEFT(ic))),
                AopType(AOP_TYPE(IC_RIGHT(ic))));
        
-       /* special cases :- */
-       /* if both left & right are in bit space */
-       if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
-               AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
-               genPlusBits (ic);
-               goto release ;
-       }
-       
        /* if I can do an decrement instead
        of subtract then GOOD for ME */
        //  if (genMinusDec (ic) == TRUE)
@@ -1549,36 +1483,24 @@ void genMinus (iCode *ic)
                
                if(size){
                        if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
-                                       while(size--){
-                                               emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
-                                               emitSKPC;
-                                               emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
-                                               emitpcode(POC_SUBLW,   popGet(AOP(IC_LEFT(ic)),offset));
-                                               emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
-                                               offset++;
-                                       }
-                               } else {
-                                       while(size--){
-                                               emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
-                                               emitSKPC;
-                                               emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
-                                               emitpcode(POC_SUBFW,   popGet(AOP(IC_LEFT(ic)),offset));
-                                               emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
-                                               offset++;
-                                       }
+                               int lit = 0;
+                               if (op_isLitLike (IC_LEFT(ic)))
+                                       lit = 1;
+                               while(size--){
+                                       emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
+                                       emitSKPC;
+                                       emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
+                                       emitpcode(lit?POC_SUBLW:POC_SUBFW,   popGetAddr(AOP(IC_LEFT(ic)),offset,0));
+                                       emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
+                                       offset++;
                                }
                        } else {
                                PIC_OPCODE poc = POC_MOVFW;
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                               if (op_isLitLike (IC_LEFT(ic)))
                                        poc = POC_MOVLW;
                                while(size--){
                                        if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-                                               emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
+                                               emitpcode(poc,  popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                                emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
                                        }
                                        emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
@@ -1615,9 +1537,10 @@ void genUMult8XLit_16 (operand *left,
        int same;
        pCodeOp *temp;
        
+       FENTRY;
        if (AOP_TYPE(right) != AOP_LIT){
                fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
-               exit(1);
+               exit(EXIT_FAILURE);
        }
        
        
@@ -1732,7 +1655,7 @@ void genUMult8XLit_16 (operand *left,
                        temp = popGetTempReg();
                        if(!temp) {
                                fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
-                               exit(1);
+                               exit(EXIT_FAILURE);
                        }
                        emitpcode(POC_SWAPFW, popGet(AOP(left),0));
                        emitpcode(POC_MOVWF,  temp);
@@ -1771,45 +1694,62 @@ void genUMult8XLit_16 (operand *left,
                        emitpcode(POC_RRF,    popGet(AOP(left),0));
                        return;
                        
+               }
+       } else {
+               
+               switch(lit) {
+               case 0:
+                       emitpcode(POC_CLRF,  popGet(AOP(result),0));
+                       emitpcode(POC_CLRF,  popCopyReg(result_hi));
+                       return;
+               case 2:
+                       if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
+                               emitpcode(POC_MOVFW, popGet(AOP(left),0));
+                       emitpcode(POC_MOVWF, popGet(AOP(result),0));
+                       emitpcode(POC_ADDWF, popGet(AOP(result),0));
+                       emitpcode(POC_CLRF,  popCopyReg(result_hi));
+                       emitpcode(POC_RLF,   popCopyReg(result_hi));
+                       return;
+               case 4:
+               case 8:
+                       if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
+                               emitpcode(POC_MOVFW, popGet(AOP(left),0));
+                       emitpcode(POC_MOVWF, popGet(AOP(result),0));
+                       emitpcode(POC_CLRF,  popCopyReg(result_hi));
+                       emitpcode(POC_BCF,   popCopyReg(&pc_status));
+                       emitpcode(POC_RLF,   popGet(AOP(result),0));
+                       emitpcode(POC_RLF,   popCopyReg(result_hi));
+                       emitpcode(POC_RLF,   popGet(AOP(result),0));
+                       emitpcode(POC_RLF,   popCopyReg(result_hi));
+                       if (lit >= 8) {
+                               emitpcode(POC_RLF,   popGet(AOP(result),0));
+                               emitpcode(POC_RLF,   popCopyReg(result_hi));
+                       }
+                       return;
+               }
+               
+       }
+       
+       if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
+               emitpcode(POC_MOVFW, popGet(AOP(left),0));
+       emitpcode(POC_CLRF,  popGet(AOP(result),0));
+       emitpcode(POC_CLRF,  popCopyReg(result_hi));
+
+       have_first_bit = 0;
+       for(i=0; i<8; i++) {
+               
+               if(lit & 1) {
+                       emitpcode(POC_ADDWF, popCopyReg(result_hi));
+                       have_first_bit = 1;
+               }
+               
+               if(have_first_bit) {
+                       emitpcode(POC_RRF,   popCopyReg(result_hi));
+                       emitpcode(POC_RRF,   popGet(AOP(result),0));
+               }
+               
+               lit >>= 1;
        }
-  } else {
-         
-         switch(lit) {
-         case 0:
-                 emitpcode(POC_CLRF,  popGet(AOP(result),0));
-                 emitpcode(POC_CLRF,  popCopyReg(result_hi));
-                 return;
-         case 2:
-                 emitpcode(POC_MOVFW, popGet(AOP(left),0));
-                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
-                 emitpcode(POC_ADDWF, popGet(AOP(result),0));
-                 emitpcode(POC_CLRF,  popCopyReg(result_hi));
-                 emitpcode(POC_RLF,   popCopyReg(result_hi));
-                 return;
-         }
-         
-  }
-  
-  emitpcode(POC_MOVFW, popGet(AOP(left),0));
-  emitpcode(POC_CLRF,  popGet(AOP(result),0));
-  emitpcode(POC_CLRF,  popCopyReg(result_hi));
-  
-  have_first_bit = 0;
-  for(i=0; i<8; i++) {
-         
-         if(lit & 1) {
-                 emitpcode(POC_ADDWF, popCopyReg(result_hi));
-                 have_first_bit = 1;
-         }
-         
-         if(have_first_bit) {
-                 emitpcode(POC_RRF,   popCopyReg(result_hi));
-                 emitpcode(POC_RRF,   popGet(AOP(result),0));
-         }
-         
-         lit >>= 1;
-  }
-  
 }
 
 /*-----------------------------------------------------------------*
@@ -1827,6 +1767,7 @@ void genUMult8X8_16 (operand *left,
        int i;
        int looped = 1;
        
+       FENTRY;
        if(!result_hi) {
                result_hi = PCOR(popGet(AOP(result),1));
        }
@@ -1920,6 +1861,7 @@ void genSMult8X8_16 (operand *left,
                                         pCodeOpReg *result_hi)
 {
        
+       FENTRY;
        if(!result_hi) {
                result_hi = PCOR(popGet(AOP(result),1));
        }
@@ -1945,7 +1887,12 @@ void genMult8X8_8 (operand *left,
                                   operand *right,
                                   operand *result)
 {
-       pCodeOp *result_hi = popGetTempReg();
+       pCodeOp *result_hi;
+       FENTRY;
+       if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
+               result->aop->aopu.aop_reg[0]->isFree = 0; /* Sometimes (ie part of last instruction in a blk) the result reg is pre marked as free, which mean on the next line popGetTempReg() will return this reg instead of allocating a new one. */
+       }
+       result_hi = popGetTempReg();
        
        if (AOP_TYPE(right) == AOP_LIT)
                genUMult8XLit_16(left,right,result,PCOR(result_hi));