* as/mcs51/lkarea.c: removed old K&R style,
[fw/sdcc] / src / pic16 / genarith.c
index 2015eb59ceccf527ff61af8d749146a7a3d2512e..ad1a172b0e77947fc004f5233b2c04b9e94b4383 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");
+           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");
            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));
@@ -979,11 +966,20 @@ void pic16_genPlus (iCode *ic)
                DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
 
                size = min( AOP_SIZE(result), AOP_SIZE(right) );
+               size = min( size, AOP_SIZE(left) );
                offset = 0;
 
+               if(pic16_debug_verbose) {
+//                     fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
+//                             AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
+//                     fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
+               }
+
+
+
                if ((AOP_TYPE(left) == AOP_PCODE) && (
                                (AOP(left)->aopu.pcop->type == PO_LITERAL) || 
-                               (AOP(left)->aopu.pcop->type == PO_DIR) || 
+//                             (AOP(left)->aopu.pcop->type == PO_DIR) ||   // patch 9
                                (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
                {
                        // add to literal operand
@@ -1002,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)))) {
@@ -1016,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));
@@ -1058,22 +1058,30 @@ 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 {
                                // right is signed
                                for(i=size; i< AOP_SIZE(result); i++) {
-                                       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_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
-                                       if (pic16_sameRegs(AOP(left), AOP(result)))
-                                       {
-                                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
-                                       } else { // not same
-                                               pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
-                                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(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, PO_GPR_REGISTER));
+                                               pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
+                                               if (pic16_sameRegs(AOP(left), AOP(result)))
+                                               {
+                                                       pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
+                                               } else { // not same
+                                                       pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
+                                                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+                                               }
+                                       } else {
+                                               pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+                                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
                                        }
                                }
                        }
@@ -1082,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
 
@@ -1102,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));
                        }
                }
@@ -1254,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));
@@ -1331,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)));
@@ -1413,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{
@@ -1429,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));
 
          }
 
@@ -1469,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));
@@ -1484,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");
     }
   
 
@@ -1554,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));
@@ -1586,7 +1551,6 @@ void pic16_genMinus (iCode *ic)
              pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
          }
        }
-      }
     }
 
     /*
@@ -1603,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++;
     }
 
@@ -1626,220 +1592,6 @@ void pic16_genMinus (iCode *ic)
   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
-/*-----------------------------------------------------------------*
- * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
- * 
- * 
- *-----------------------------------------------------------------*/
-void pic16_genUMult8XLit_16 (operand *left,
-                            operand *right,
-                            operand *result,
-                            pCodeOpReg *result_hi)
-
-{
-
-  unsigned int lit;
-  unsigned int i,have_first_bit;
-  int same;
-  pCodeOp *temp;
-
-  if (AOP_TYPE(right) != AOP_LIT){
-    fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
-    exit(1);
-  }
-
-
-  if(!result_hi) {
-    result_hi = PCOR(pic16_popGet(AOP(result),1));
-  }
-
-  lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
-  lit &= 0xff;
-  pic16_emitcode(";","Unrolled 8 X 8 multiplication");
-
-  same = pic16_sameRegs(AOP(left), AOP(result));
-
-  if(same) {
-    switch(lit) {
-    case 0:
-      pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(left),0));
-      return;
-    case 2:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 3:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 4:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 5:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
-      return;
-    case 6:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 7:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 7*F
-      return;
-    case 8:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 8*F
-      return;
-    case 9:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 10:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 11:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 8*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 11*F
-      return;
-    case 12:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 13:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 8*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 13*F
-      return;
-    case 14:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 8*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 11*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 14*F
-      return;
-    case 15:
-      temp = pic16_popGetTempReg();
-      if(!temp) {
-       fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
-       exit(1);
-      }
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF,  temp);
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_SWAPFW, temp);
-      pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(left),0));
-      pic16_popReleaseTempReg(temp);
-      return;
-    case 16:
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 17:
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 32:
-      pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xe0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 64:
-      pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xc0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 128:
-      pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(left),0));
-      return;
-
-    }
-  } else {
-
-    switch(lit) {
-    case 0:
-      pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-      return;
-    case 2:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RLCF,  pic16_popCopyReg(result_hi));
-      return;
-    }
-
-  }
-
-  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-  pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-  pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-
-  have_first_bit = 0;
-  for(i=0; i<8; i++) {
-
-    if(lit & 1) {
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
-      have_first_bit = 1;
-    }
-
-    if(have_first_bit) {
-      pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
-    }
-
-    lit >>= 1;
-  }
-
-}
-
 
 /*-----------------------------------------------------------------*
  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
@@ -1853,6 +1605,10 @@ void pic16_genUMult8XLit_8 (operand *left,
   unsigned int lit;
   int same;
 
+
+       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__);
                exit(1);
@@ -1871,11 +1627,13 @@ void pic16_genUMult8XLit_8 (operand *left,
                                return;
                        case 2:
                                // its faster to left shift
-                               pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(left),0));
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
                                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)));
@@ -1888,11 +1646,13 @@ void pic16_genUMult8XLit_8 (operand *left,
                                pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
                                return;
                        case 2:
-                               pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), 0));
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
                                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)));
@@ -1901,99 +1661,120 @@ void pic16_genUMult8XLit_8 (operand *left,
        }
 }
 
-/*-----------------------------------------------------------------*
- * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
- * 
- * 
- *-----------------------------------------------------------------*/
-void pic16_genUMult8X8_16 (operand *left,
-                          operand *right,
-                          operand *result,
-                          pCodeOpReg *result_hi)
-
+/*-----------------------------------------------------------------------*
+ * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
+ *-----------------------------------------------------------------------*/
+void pic16_genUMult16XLit_16 (operand *left,
+                            operand *right,
+                            operand *result)
 {
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+  unsigned int lit;
+  int same;
 
-  int i;
-  int looped = 1;
-
-  if(!result_hi) {
-    result_hi = PCOR(pic16_popGet(AOP(result),1));
-  }
-
-  if (AOP_TYPE(right) == AOP_LIT) {
-    pic16_genUMult8XLit_16(left,right,result,result_hi);
-    return;
-  }
-
-  if(!looped) {
-    pic16_emitcode(";","Unrolled 8 X 8 multiplication");
-
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-    pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-    pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-    emitCLRC;
-
-    for(i=0; i<8; i++) {
-      pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
-    }
-
-
-    /*
-      Here's another version that does the same thing and takes the 
-      same number of instructions. The one above is slightly better
-      because the entry instructions have a higher probability of
-      being optimized out.
-    */
-    /*
-      pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
-      for(i=0; i<8; i++) {
-      emitSKPNC;
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
-      }
-    */
-
-  } else {
-    symbol  *tlbl = newiTempLabel(NULL);
-    pCodeOp *temp;
-
-    pic16_emitpcomment("; Looped 8 X 8 multiplication");
-    pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-    pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-
-    pic16_emitpcode(POC_BSF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
-
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
-    temp = pic16_popGetTempReg();
-    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
-
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
 
-    pic16_emitpLabel(tlbl->key);
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(PCOR(temp)));
-    emitSKPNC;
-    pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
+       if (AOP_TYPE(right) != AOP_LIT){
+               fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+               exit(1);
+       }
 
-    pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-    pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
+       lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+       lit &= 0xffff;
 
-    emitSKPC;
-    pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl->key));
+       same = pic16_sameRegs(AOP(left), AOP(result));
+       if(same) {
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+                               return;
+                       case 2:
+                               // its faster to left shift
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+                               return;
 
-    pic16_popReleaseTempReg(temp);
-  }
+                       default: {
+                               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+                               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));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+                               /* load result */
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pct1, pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+                               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+                               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+                               pic16_popReleaseTempReg(pct4,1);
+                               pic16_popReleaseTempReg(pct3,1);
+                               pic16_popReleaseTempReg(pct2,1);
+                               pic16_popReleaseTempReg(pct1,1);
+                       }; return;
+               }
+       } else {
+               // operands different
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+                               return;
+                       case 2:
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+                               return;
+                       default: {
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+                       }; return;
+               }
+       }
 }
 
+
 /*-----------------------------------------------------------------*
  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
  * 
@@ -2004,12 +1785,14 @@ void pic16_genUMult8X8_8 (operand *left,
                           operand *result)
 
 {
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+
        if (AOP_TYPE(right) == AOP_LIT) {
                pic16_genUMult8XLit_8(left,right,result);
          return;
        }
 
-       pic16_emitpcomment("; Looped 8 X 8 multiplication");
        /* cases:
                A = A x B       B = A x B
                A = B x C
@@ -2041,53 +1824,413 @@ void pic16_genUMult8X8_8 (operand *left,
        if(AOP_TYPE(result) != AOP_ACC) {
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
                        pic16_popGet(AOP(result), 0)));
+
+
+               if(AOP_SIZE(result)>1) {
+                 int i;
+
+                       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
+                       pic16_popGet(AOP(result), 1)));
+                       
+                       for(i=2;i<AOP_SIZE(result);i++)
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
+               }
        } else {
                pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
        }
 }
 
+/*------------------------------------------------------------------*
+ * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
+ *------------------------------------------------------------------*/
+void pic16_genUMult16X16_16 (operand *left,
+                          operand *right,
+                          operand *result)
+
+{
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+
+       if (AOP_TYPE(right) == AOP_LIT) {
+               pic16_genUMult8XLit_8(left,right,result);
+         return;
+       }
+
+       /* cases:
+               A = A x B       B = A x B
+               A = B x C
+       */
+       /* if result == right then exchange left and right */
+       if(pic16_sameRegs(AOP(result), AOP(right))) {
+         operand *tmp;
+               tmp = left;
+               left = right;
+               right = tmp;
+       }
+
+
+       if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+               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));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+               /* load result */
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+               pic16_popReleaseTempReg( pct4, 1 );
+               pic16_popReleaseTempReg( pct3, 1 );
+               pic16_popReleaseTempReg( pct2, 1 );
+               pic16_popReleaseTempReg( pct1, 1 );
+
+       } else {
+
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+       }       
+}
+
+
+void pic16_genSMult16X16_16(operand *left,
+                       operand *right,
+                       operand *result)
+{
+
+}
+
+#if 0
 /*-----------------------------------------------------------------*
  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
  *
  *  this routine will call the unsigned multiply routine and then
  * post-fix the sign bit.
  *-----------------------------------------------------------------*/
-void pic16_genSMult8X8_16 (operand *left,
+void pic16_genSMult8X8_8 (operand *left,
                           operand *right,
                           operand *result,
                           pCodeOpReg *result_hi)
 {
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
 
   if(!result_hi) {
     result_hi = PCOR(pic16_popGet(AOP(result),1));
   }
 
-  pic16_genUMult8X8_16(left,right,result,result_hi);
 
-  pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
+  pic16_genUMult8X8_8(left,right,result);
+
+  
+#if 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
 }
+#endif
 
 /*-----------------------------------------------------------------*
- * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
- *
- *  this routine will call the unsigned multiply 8X8=>16 routine and
- * then throw away the high byte of the result.
- *
+ * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
  *-----------------------------------------------------------------*/
 void pic16_genMult8X8_8 (operand *left,
                         operand *right,
                         operand *result)
 {
-  if (AOP_TYPE(right) == AOP_LIT)
-    pic16_genUMult8XLit_8(left,right,result);
-  else
-    pic16_genUMult8X8_8(left,right,result);
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if(AOP_TYPE(right) == AOP_LIT)
+               pic16_genUMult8XLit_8(left,right,result);
+       else
+               pic16_genUMult8X8_8(left,right,result);
+}
+
+
+/*-----------------------------------------------------------------*
+ * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
+ *-----------------------------------------------------------------*/
+void pic16_genMult16X16_16 (operand *left,
+                        operand *right,
+                        operand *result)
+{
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if (AOP_TYPE(right) == AOP_LIT)
+               pic16_genUMult16XLit_16(left,right,result);
+       else
+               pic16_genUMult16X16_16(left,right,result);
+
+}
+
+
+
+
+/*-----------------------------------------------------------------------*
+ * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
+ *-----------------------------------------------------------------------*/
+void pic16_genUMult32XLit_32 (operand *left,
+                            operand *right,
+                            operand *result)
+{
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+  unsigned int lit;
+  int same;
+
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if (AOP_TYPE(right) != AOP_LIT){
+               fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+               exit(1);
+       }
+
+       lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+       lit &= 0xffff;
+
+       same = pic16_sameRegs(AOP(left), AOP(result));
+       if(same) {
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+                               return;
+                       case 2:
+                               // its faster to left shift
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+                               return;
+
+                       default: {
+                               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+                               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));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+                               /* load result */
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pct1, pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+                               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+                               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+                               pic16_popReleaseTempReg( pct4, 1 );
+                               pic16_popReleaseTempReg( pct3, 1 );
+                               pic16_popReleaseTempReg( pct2, 1 );
+                               pic16_popReleaseTempReg( pct1, 1 );
+                       }; return;
+               }
+       } else {
+               // operands different
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+                               return;
+                       case 2:
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+                               return;
+                       default: {
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+                       }; return;
+               }
+       }
+}
+
+
+/*------------------------------------------------------------------*
+ * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
+ *------------------------------------------------------------------*/
+void pic16_genUMult32X32_32 (operand *left,
+                          operand *right,
+                          operand *result)
+
+{
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+
+       if (AOP_TYPE(right) == AOP_LIT) {
+               pic16_genUMult8XLit_8(left,right,result);
+         return;
+       }
+
+       /* cases:
+               A = A x B       B = A x B
+               A = B x C
+       */
+       /* if result == right then exchange left and right */
+       if(pic16_sameRegs(AOP(result), AOP(right))) {
+         operand *tmp;
+               tmp = left;
+               left = right;
+               right = tmp;
+       }
+
+
+       if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+               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));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+               /* load result */
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+               pic16_popReleaseTempReg( pct4, 1 );
+               pic16_popReleaseTempReg( pct3, 1 );
+               pic16_popReleaseTempReg( pct2, 1 );
+               pic16_popReleaseTempReg( pct1, 1 );
+
+       } else {
+
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+       }       
+}
+
+
+/*-----------------------------------------------------------------*
+ * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
+ *-----------------------------------------------------------------*/
+void pic16_genMult32X32_32 (operand *left,
+                        operand *right,
+                        operand *result)
+{
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if (AOP_TYPE(right) == AOP_LIT)
+               pic16_genUMult32XLit_32(left,right,result);
+       else
+               pic16_genUMult32X32_32(left,right,result);
+
 }
+
+
+
+
+
+
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* constMult - generates code for multiplication by a constant     */