* src/pic16/device.h,
[fw/sdcc] / src / pic16 / genarith.c
index ae71c24a3173c7cbff812e47c89330864f354f15..a543487350e450115839f46d8d98fd97800fd95e 100644 (file)
 #include "pcode.h"
 #include "gen.h"
 
+//#define D_POS(txt) DEBUGpic16_emitcode ("; TECODEV::: " txt, " (%s:%d (%s))", __FILE__, __LINE__, __FUNCTION__)
+
+#define D_POS(msg)     DEBUGpic16_emitcode("; ", msg, "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__)
+
 #if 1
 #define pic16_emitcode DEBUGpic16_emitcode
 #endif
@@ -59,109 +63,99 @@ pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
 const char *pic16_AopType(short type)
 {
   switch(type) {
-  case AOP_LIT:
-    return "AOP_LIT";
-    break;
-  case AOP_REG:
-    return "AOP_REG";
-    break;
-  case AOP_DIR:
-    return "AOP_DIR";
-    break;
-  case AOP_DPTR:
-    return "AOP_DPTR";
-    break;
-  case AOP_DPTR2:
-    return "AOP_DPTR2";
-    break;
-  case AOP_R0:
-    return "AOP_R0";
-    break;
-  case AOP_R1:
-    return "AOP_R1";
-    break;
-  case AOP_STK:
-    return "AOP_STK";
-    break;
-  case AOP_IMMD:
-    return "AOP_IMMD";
-    break;
-  case AOP_STR:
-    return "AOP_STR";
-    break;
-  case AOP_CRY:
-    return "AOP_CRY";
-    break;
-  case AOP_ACC:
-    return "AOP_ACC";
-    break;
-  case AOP_PCODE:
-    return "AOP_PCODE";
-    break;
+  case AOP_LIT:                return "AOP_LIT";
+  case AOP_REG:        return "AOP_REG";
+  case AOP_DIR:        return "AOP_DIR";
+  case AOP_DPTR:       return "AOP_DPTR";
+  case AOP_DPTR2:      return "AOP_DPTR2";
+  case AOP_FSR0:       return "AOP_FSR0";
+  case AOP_FSR2:       return "AOP_FSR2";
+  case AOP_R0:         return "AOP_R0";
+  case AOP_R1:         return "AOP_R1";
+  case AOP_STK:                return "AOP_STK";
+  case AOP_IMMD:       return "AOP_IMMD";
+  case AOP_STR:                return "AOP_STR";
+  case AOP_CRY:                return "AOP_CRY";
+  case AOP_ACC:                return "AOP_ACC";
+  case AOP_PCODE:      return "AOP_PCODE";
+  case AOP_STA:                return "AOP_STA";
   }
 
   return "BAD TYPE";
 }
 
-const char *pic16_pCodeOpType(  pCodeOp *pcop)
+const char *pic16_pCodeOpType(pCodeOp *pcop)
 {
 
   if(pcop) {
 
     switch(pcop->type) {
 
-    case  PO_NONE:
-      return "PO_NONE";
-    case  PO_W:
-      return  "PO_W";
-    case  PO_WREG:
-      return  "PO_WREG";
-    case  PO_STATUS:
-      return  "PO_STATUS";
-    case  PO_BSR:
-      return  "PO_BSR";
-    case  PO_FSR0:
-      return  "PO_FSR0";
-    case  PO_INDF0:
-      return  "PO_INDF0";
-    case  PO_INTCON:
-      return  "PO_INTCON";
-    case  PO_GPR_REGISTER:
-      return  "PO_GPR_REGISTER";
-    case  PO_GPR_BIT:
-      return  "PO_GPR_BIT";
-    case  PO_GPR_TEMP:
-      return  "PO_GPR_TEMP";
-    case  PO_SFR_REGISTER:
-      return  "PO_SFR_REGISTER";
-    case  PO_PCL:
-      return  "PO_PCL";
-    case  PO_PCLATH:
-      return  "PO_PCLATH";
-    case  PO_PCLATU:
-      return  "PO_PCLATU";
-    case  PO_PRODL:
-      return  "PO_PRODL";
-    case  PO_PRODH:
-      return  "PO_PRODH";
-    case PO_LITERAL:
-      return  "PO_LITERAL";
-    case PO_REL_ADDR:
-      return "PO_REL_ADDR";
-    case  PO_IMMEDIATE:
-      return  "PO_IMMEDIATE";
-    case  PO_DIR:
-      return  "PO_DIR";
-    case  PO_CRY:
-      return  "PO_CRY";
-    case  PO_BIT:
-      return  "PO_BIT";
-    case  PO_STR:
-      return  "PO_STR";
-    case  PO_LABEL:
-      return  "PO_LABEL";
-    case  PO_WILD:
-      return  "PO_WILD";
+    case PO_NONE:              return "PO_NONE";
+    case PO_W:                 return  "PO_W";
+    case PO_WREG:              return  "PO_WREG";
+    case PO_STATUS:            return  "PO_STATUS";
+    case PO_BSR:               return  "PO_BSR";
+    case PO_FSR0:              return  "PO_FSR0";
+    case PO_INDF0:             return  "PO_INDF0";
+    case PO_INTCON:            return  "PO_INTCON";
+    case PO_GPR_REGISTER:      return  "PO_GPR_REGISTER";
+    case PO_GPR_BIT:           return  "PO_GPR_BIT";
+    case PO_GPR_TEMP:          return  "PO_GPR_TEMP";
+    case PO_SFR_REGISTER:      return  "PO_SFR_REGISTER";
+    case PO_PCL:               return  "PO_PCL";
+    case PO_PCLATH:            return  "PO_PCLATH";
+    case PO_PCLATU:            return  "PO_PCLATU";
+    case PO_PRODL:             return  "PO_PRODL";
+    case PO_PRODH:             return  "PO_PRODH";
+    case PO_LITERAL:           return  "PO_LITERAL";
+    case PO_REL_ADDR:          return "PO_REL_ADDR";
+    case PO_IMMEDIATE:         return  "PO_IMMEDIATE";
+    case PO_DIR:               return  "PO_DIR";
+    case PO_CRY:               return  "PO_CRY";
+    case PO_BIT:               return  "PO_BIT";
+    case PO_STR:               return  "PO_STR";
+    case PO_LABEL:             return  "PO_LABEL";
+    case PO_WILD:              return  "PO_WILD";
+    }
+  }
+
+  return "BAD PO_TYPE";
+}
+
+const char *pic16_pCodeOpSubType(pCodeOp *pcop)
+{
+
+  if(pcop && (pcop->type == PO_GPR_BIT)) {
+
+    switch(PCORB(pcop)->subtype) {
+
+    case PO_NONE:              return "PO_NONE";
+    case PO_W:                 return  "PO_W";
+    case PO_WREG:              return  "PO_WREG";
+    case PO_STATUS:            return  "PO_STATUS";
+    case PO_BSR:               return  "PO_BSR";
+    case PO_FSR0:              return  "PO_FSR0";
+    case PO_INDF0:             return  "PO_INDF0";
+    case PO_INTCON:            return  "PO_INTCON";
+    case PO_GPR_REGISTER:      return  "PO_GPR_REGISTER";
+    case PO_GPR_BIT:           return  "PO_GPR_BIT";
+    case PO_GPR_TEMP:          return  "PO_GPR_TEMP";
+    case PO_SFR_REGISTER:      return  "PO_SFR_REGISTER";
+    case PO_PCL:               return  "PO_PCL";
+    case PO_PCLATH:            return  "PO_PCLATH";
+    case PO_PCLATU:            return  "PO_PCLATU";
+    case PO_PRODL:             return  "PO_PRODL";
+    case PO_PRODH:             return  "PO_PRODH";
+    case PO_LITERAL:           return  "PO_LITERAL";
+    case PO_REL_ADDR:          return "PO_REL_ADDR";
+    case PO_IMMEDIATE:         return  "PO_IMMEDIATE";
+    case PO_DIR:               return  "PO_DIR";
+    case PO_CRY:               return  "PO_CRY";
+    case PO_BIT:               return  "PO_BIT";
+    case PO_STR:               return  "PO_STR";
+    case PO_LABEL:             return  "PO_LABEL";
+    case PO_WILD:              return  "PO_WILD";
     }
   }
 
@@ -204,7 +198,7 @@ bool pic16_genPlusIncr (iCode *ic)
       //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
 
       while(--size) {
-       emitSKPNZ;
+       emitSKPNC;
        pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
        //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
       }
@@ -268,6 +262,8 @@ void pic16_outBitAcc(operand *result)
     /* if the result is a bit */
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
+    assert(0); // not implemented for PIC16?
+
     if (AOP_TYPE(result) == AOP_CRY){
         pic16_aopPut(AOP(result),"a",0);
     }
@@ -534,6 +530,14 @@ static void genAddLit (iCode *ic, int lit)
          pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
          pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
          pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+         break;
+       default: /* 0x01LL */
+         D_POS("FIXED: added default case for adding 0x01??");
+         pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+         pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+         emitSKPNC;
+         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
        }         
        break;
 
@@ -573,10 +577,11 @@ static void genAddLit (iCode *ic, int lit)
          genAddLit2byte (result, MSB16, hi);
          break;
        case 1:  /* 0xHH01 */
-         pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
-         pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
+         D_POS(">>> IMPROVED");
+         pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
          pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
-         pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
+         pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
+         D_POS("<<< IMPROVED");
          break;
 /*     case 0xff: * 0xHHff *
          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
@@ -588,9 +593,9 @@ static void genAddLit (iCode *ic, int lit)
          pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
          pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
          pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
-         emitSKPNC;
-         pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
-         pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
+         D_POS(">>> IMPROVED");
+         pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
+         D_POS("<<< IMPROVED");
          break;
        }
 
@@ -607,40 +612,22 @@ static void genAddLit (iCode *ic, int lit)
        if(carry_info) {
          switch(lo) {
          case 0:
-           switch(carry_info) {
-           case 1:
-             emitSKPNZ;
-             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
-             break;
-           case 2:
-             pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
-             pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
-             pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
-             break;
-           default: /* carry_info = 3  */
-             emitSKPNC;
-             pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
-             carry_info = 1;
-             break;
-           }
+           D_POS(">>> IMPROVED and compacted 0");
+           emitSKPNC;
+           pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
+           D_POS("<<< IMPROVED and compacted");
            break;
          case 0xff:
            pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
-           if(carry_info==1) 
-             emitSKPZ;
-           else
-             emitSKPC;
+           D_POS(">>> Changed from SKPZ/SKPC to always SKPC");
+           emitSKPC;
            pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
            break;
          default:
+           D_POS(">>> IMPROVED and compacted - default");
            pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
-           if(carry_info==1) 
-             emitSKPNZ;
-           else
-             emitSKPNC;
-           pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
-           pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
-           carry_info=2;
+           pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
+           D_POS("<<< IMPROVED and compacted");
            break;
          }
        }else {
@@ -716,8 +703,7 @@ static void genAddLit (iCode *ic, int lit)
        case 0:
          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
          emitMOVWF(result, 0);
-         //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
-         emitMOVWF(result,0);
+         D_POS(">>> REMOVED double assignment");
          break;
        case 1:
          pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
@@ -761,25 +747,26 @@ static void genAddLit (iCode *ic, int lit)
 
            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
            pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(left),offset));
-           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
+           D_POS(">>> FIXED from left to result");
+           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+           D_POS("<<< FIXED from left to result");
 
            clear_carry = 0;
 
          } else {
+           D_POS(">>> FIXED");
            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
-           //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
-           emitMOVWF(result,offset);
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
-           emitSKPNC;
-           pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
-           pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(result),offset));
+           pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
+           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+           D_POS("<<< FIXED");
          }
 
        } else {
+         D_POS(">>> IMPROVED");
          pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offset));
-         pic16_emitpcode(POC_RLCF,  pic16_popGet(AOP(result),offset));
          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
-         pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
+         pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
+         D_POS("<<< IMPROVED");
        }
        offset++;
       }
@@ -935,7 +922,7 @@ void pic16_genPlus (iCode *ic)
                                pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
 
                        } else {
-
+                               emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
                                pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
                                pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
                                pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
@@ -1011,6 +998,8 @@ void pic16_genPlus (iCode *ic)
                                }
                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
                        }
+                       
+                       DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
 
                        // add leftover bytes
                        if (SPEC_USIGN(getSpec(operandType(right)))) {
@@ -1025,7 +1014,9 @@ void pic16_genPlus (iCode *ic)
                                // right is signed, oh dear ...
                                for(i=size; i< AOP_SIZE(result); i++) {
                                        pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
-                                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0));
+                                       D_POS(">>> FIXED sign test from result to right");
+                                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+                                       D_POS("<<< FIXED sign test from result to right");
                                        pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
                                        pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
                                        pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
@@ -1067,8 +1058,11 @@ void pic16_genPlus (iCode *ic)
                                                pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
                                                pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
                                        } else { // not same
-                                               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
-                                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
+                                               D_POS (">>> FIXED added to uninitialized result");
+                                               pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+                                               pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
+                                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+                                               D_POS ("<<< FIXED");
                                        }
                                }
                        } else {
@@ -1076,7 +1070,7 @@ void pic16_genPlus (iCode *ic)
                                for(i=size; i< AOP_SIZE(result); i++) {
                                        if(size < AOP_SIZE(left)) {
                                                pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
-                                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0));
+                                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
                                                pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
                                                if (pic16_sameRegs(AOP(left), AOP(result)))
                                                {
@@ -1096,6 +1090,7 @@ void pic16_genPlus (iCode *ic)
 
        }
 
+       assert( 0 );
        // TODO:        anything from here to before "release:" is probably obsolete and should be removed
        //              when the regression tests are stable
 
@@ -1116,15 +1111,15 @@ void pic16_genPlus (iCode *ic)
                        /* Now this is really horrid. Gotta check the sign of the addends and propogate
                        * to the result */
 
-                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
+                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
                        pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
+                       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
                        pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
 
                        /* if chars or ints or being signed extended to longs: */
                        if(size) {
                                pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
-                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
+                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
                                pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
                        }
                }
@@ -1268,12 +1263,12 @@ void pic16_addSign(operand *result, int offset, int sign)
 
       if(size == 1) {
        pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
-       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
+       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
        pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
       } else {
 
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
-       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
+       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
        while(size--)
          pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
@@ -1345,8 +1340,8 @@ void pic16_genMinus (iCode *ic)
 
   /* if I can do an decrement instead
      of subtract then GOOD for ME */
-  //  if (pic16_genMinusDec (ic) == TRUE)
-  //    goto release;   
+//  if (pic16_genMinusDec (ic) == TRUE)
+//    goto release;   
 
   size = pic16_getDataSize(IC_RESULT(ic));   
   same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
@@ -1427,7 +1422,8 @@ void pic16_genMinus (iCode *ic)
          if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
            if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
              if(lit & 1) {
-               pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+               D_POS(">>> FIXED from MOVLW right(=result) to MOVLW left(=literal,left&1==1)");
+               pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
                pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
              }
            }else{
@@ -1443,7 +1439,8 @@ void pic16_genMinus (iCode *ic)
            pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
            pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
            pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
-           pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+           D_POS(">>> IMPROVED removed following assignment W-->result");
+           //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
 
          }
 
@@ -1483,8 +1480,9 @@ void pic16_genMinus (iCode *ic)
     if( (size == 1) && ((lit & 0xff) == 0) ) {
       /* res = 0 - right */
       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
-       pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
-       pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
+       D_POS(">>> IMPROVED changed comf,incf to negf");
+       pic16_emitpcode(POC_NEGF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
+       D_POS("<<< IMPROVED changed comf,incf to negf");
       } else { 
        pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
        pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
@@ -1498,62 +1496,21 @@ void pic16_genMinus (iCode *ic)
     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
 
 
-    offset = 1;
+    offset = 0;
     while(--size) {
       lit >>= 8;
-
-      if(size == 1) {
-       /* This is the last byte in a multibyte subtraction 
-        * There are a couple of tricks we can do by not worrying about 
-        * propogating the carry */
-       if(lit == 0xff) {
-         /* 0xff - x == ~x */
-         if(same) {
-           pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-           emitSKPC;
-           pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-         } else {
-           pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-           emitSKPC;
-           pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-         }
-       } else {
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-           emitSKPC;
-           pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-           pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
-           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-       }
-
-       goto release;
-      }
-
+      offset++;
+      D_POS(">>> FIXED and compacted");
       if(same) {
-
-       if(lit & 0xff) {
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
-         emitSKPC;
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
-         pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-       } else {
-         emitSKPNC;
-         pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-
-       }
+       // here we have x = lit - x   for sizeof(x)>1
+       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+       pic16_emitpcode(POC_SUBFWB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
       } else {
-
-       if(lit & 0xff) {
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
-         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-       } else
-         pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
-
-       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-       emitSKPC;
-       pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-       pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
+       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+       pic16_emitpcode(POC_SUBFWB_D0,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
+       pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
       }
+      D_POS("<<< FIXED and compacted");
     }
   
 
@@ -1568,16 +1525,10 @@ void pic16_genMinus (iCode *ic)
       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
-      pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+      if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
+       pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
     } else {
 
-      if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
-       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
-       pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
-       if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
-         pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
-      } else {
-
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
          pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
@@ -1600,7 +1551,6 @@ void pic16_genMinus (iCode *ic)
              pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
          }
        }
-      }
     }
 
     /*
@@ -1617,15 +1567,17 @@ void pic16_genMinus (iCode *ic)
     size--;
 
     while(size--){
-      if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
+      if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
+       D_POS(">>> IMPROVED by replacing emitSKPC, incfszw by subwfb");
+       pic16_emitpcode(POC_SUBWFB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
+       D_POS("<<< IMPROVED by replacing emitSKPC, incfszw by subwfb");
+      } else {
+       D_POS(">>> FIXED for same regs right and result");
+       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
+       pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
        pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-      }
-      pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-      emitSKPC;
-      pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-      pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-
+      }        
       offset++;
     }
 
@@ -1652,9 +1604,11 @@ void pic16_genUMult8XLit_8 (operand *left,
 {
   unsigned int lit;
   int same;
-
+  int size = AOP_SIZE(result);
+  int i;
 
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
 
        if (AOP_TYPE(right) != AOP_LIT){
                fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
@@ -1670,37 +1624,68 @@ void pic16_genUMult8XLit_8 (operand *left,
        if(same) {
                switch(lit) {
                        case 0:
-                               pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
+                               while (size--) {
+                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
+                               } // while
                                return;
                        case 2:
                                // its faster to left shift
+                               for (i=1; i < size; i++) {
+                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
+                               } // for
                                emitCLRC;
                                pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+                               if (size > 1)
+                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
                                return;
 
                        default:
-                               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+                               if(AOP_TYPE(left) != AOP_ACC)
+                                       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
                                pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
                                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
                                        pic16_popGet(AOP(result), 0)));
+                               if (size > 1) {
+                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
+                                                                           pic16_popGet(AOP(result), 1)));
+                                 for (i=2; i < size; i++) {
+                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
+                                 } // for
+                               } // if
                                return;
                }
        } else {
                // operands different
                switch(lit) {
                        case 0:
-                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+                               while (size--) {
+                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),size));
+                               } // while
                                return;
                        case 2:
+                               for (i=1; i < size; i++) {
+                                 pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
+                               } // for
                                emitCLRC;
                                pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+                               if (size > 1)
+                                 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
                                return;
                        default:
-                               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+                               if(AOP_TYPE(left) != AOP_ACC)
+                                       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
                                pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
                                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
                                        pic16_popGet(AOP(result), 0)));
+
+                               if (size > 1) {
+                                 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
+                                                                           pic16_popGet(AOP(result), 1)));
+                                 for (i=2; i < size; i++) {
+                                   pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),i));
+                                 } // for
+                               } // if
                                return;
                }
        }
@@ -1745,10 +1730,10 @@ void pic16_genUMult16XLit_16 (operand *left,
                        default: {
                                DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-                               pct1 = pic16_popGetTempReg();
-                               pct2 = pic16_popGetTempReg();
-                               pct3 = pic16_popGetTempReg();
-                               pct4 = pic16_popGetTempReg();
+                               pct1 = pic16_popGetTempReg(1);
+                               pct2 = pic16_popGetTempReg(1);
+                               pct3 = pic16_popGetTempReg(1);
+                               pct4 = pic16_popGetTempReg(1);
 
                                pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
                                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
@@ -1775,10 +1760,10 @@ void pic16_genUMult16XLit_16 (operand *left,
                                pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
 
-                               pic16_popReleaseTempReg( pct4 );
-                               pic16_popReleaseTempReg( pct3 );
-                               pic16_popReleaseTempReg( pct2 );
-                               pic16_popReleaseTempReg( pct1 );
+                               pic16_popReleaseTempReg(pct4,1);
+                               pic16_popReleaseTempReg(pct3,1);
+                               pic16_popReleaseTempReg(pct2,1);
+                               pic16_popReleaseTempReg(pct1,1);
                        }; return;
                }
        } else {
@@ -1918,10 +1903,10 @@ void pic16_genUMult16X16_16 (operand *left,
 
        if(pic16_sameRegs(AOP(result), AOP(left))) {
 
-               pct1 = pic16_popGetTempReg();
-               pct2 = pic16_popGetTempReg();
-               pct3 = pic16_popGetTempReg();
-               pct4 = pic16_popGetTempReg();
+               pct1 = pic16_popGetTempReg(1);
+               pct2 = pic16_popGetTempReg(1);
+               pct3 = pic16_popGetTempReg(1);
+               pct4 = pic16_popGetTempReg(1);
 
                pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
@@ -1948,10 +1933,10 @@ void pic16_genUMult16X16_16 (operand *left,
                pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
 
-               pic16_popReleaseTempReg( pct4 );
-               pic16_popReleaseTempReg( pct3 );
-               pic16_popReleaseTempReg( pct2 );
-               pic16_popReleaseTempReg( pct1 );
+               pic16_popReleaseTempReg( pct4, 1 );
+               pic16_popReleaseTempReg( pct3, 1 );
+               pic16_popReleaseTempReg( pct2, 1 );
+               pic16_popReleaseTempReg( pct1, 1 );
 
        } else {
 
@@ -2006,10 +1991,10 @@ void pic16_genSMult8X8_8 (operand *left,
 
   
 #if 0
-  pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
+  pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-  pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
+  pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
 #endif
 }
@@ -2089,10 +2074,10 @@ void pic16_genUMult32XLit_32 (operand *left,
                        default: {
                                DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-                               pct1 = pic16_popGetTempReg();
-                               pct2 = pic16_popGetTempReg();
-                               pct3 = pic16_popGetTempReg();
-                               pct4 = pic16_popGetTempReg();
+                               pct1 = pic16_popGetTempReg(1);
+                               pct2 = pic16_popGetTempReg(1);
+                               pct3 = pic16_popGetTempReg(1);
+                               pct4 = pic16_popGetTempReg(1);
 
                                pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
                                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
@@ -2119,10 +2104,10 @@ void pic16_genUMult32XLit_32 (operand *left,
                                pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
 
-                               pic16_popReleaseTempReg( pct4 );
-                               pic16_popReleaseTempReg( pct3 );
-                               pic16_popReleaseTempReg( pct2 );
-                               pic16_popReleaseTempReg( pct1 );
+                               pic16_popReleaseTempReg( pct4, 1 );
+                               pic16_popReleaseTempReg( pct3, 1 );
+                               pic16_popReleaseTempReg( pct2, 1 );
+                               pic16_popReleaseTempReg( pct1, 1 );
                        }; return;
                }
        } else {
@@ -2197,10 +2182,10 @@ void pic16_genUMult32X32_32 (operand *left,
 
        if(pic16_sameRegs(AOP(result), AOP(left))) {
 
-               pct1 = pic16_popGetTempReg();
-               pct2 = pic16_popGetTempReg();
-               pct3 = pic16_popGetTempReg();
-               pct4 = pic16_popGetTempReg();
+               pct1 = pic16_popGetTempReg(1);
+               pct2 = pic16_popGetTempReg(1);
+               pct3 = pic16_popGetTempReg(1);
+               pct4 = pic16_popGetTempReg(1);
 
                pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
@@ -2227,10 +2212,10 @@ void pic16_genUMult32X32_32 (operand *left,
                pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
 
-               pic16_popReleaseTempReg( pct4 );
-               pic16_popReleaseTempReg( pct3 );
-               pic16_popReleaseTempReg( pct2 );
-               pic16_popReleaseTempReg( pct1 );
+               pic16_popReleaseTempReg( pct4, 1 );
+               pic16_popReleaseTempReg( pct3, 1 );
+               pic16_popReleaseTempReg( pct2, 1 );
+               pic16_popReleaseTempReg( pct1, 1 );
 
        } else {