Applied patch #2762516
[fw/sdcc] / src / pic16 / genarith.c
index 904961bcf61f8c6fb49d7518faa1f84ded7df19b..1e06e7b911d71762f34a9bef7aec569fea0a3a17 100644 (file)
@@ -62,14 +62,7 @@ const char *pic16_AopType(short type)
   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";
@@ -211,9 +204,6 @@ bool pic16_genPlusIncr (iCode *ic)
         (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
 
       pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
-      pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
-               AOP(IC_RESULT(ic))->aopu.aop_dir,
-               AOP(IC_RESULT(ic))->aopu.aop_dir);
       if(icount)
         pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
       //pic16_emitcode("xorlw","1");
@@ -223,9 +213,6 @@ bool pic16_genPlusIncr (iCode *ic)
 
       emitSKPZ;
       pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
-      pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
-               AOP(IC_RESULT(ic))->aopu.aop_dir,
-               AOP(IC_RESULT(ic))->aopu.aop_dir);
 
       return TRUE;
     }
@@ -301,16 +288,6 @@ void pic16_genPlusBits (iCode *ic)
     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
     pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
-
-    pic16_emitcode("clrw","");
-    pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                   AOP(IC_RIGHT(ic))->aopu.aop_dir,
-                   AOP(IC_RIGHT(ic))->aopu.aop_dir);
-    pic16_emitcode("xorlw","1");
-    pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                   AOP(IC_LEFT(ic))->aopu.aop_dir,
-                   AOP(IC_LEFT(ic))->aopu.aop_dir);
-    pic16_emitcode("xorlw","1");
     break;
   case AOP_REG:
     pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
@@ -327,23 +304,6 @@ void pic16_genPlusBits (iCode *ic)
     pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
     pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
     pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
-
-    pic16_emitcode("movlw","(1 << (%s & 7))",
-                   AOP(IC_RESULT(ic))->aopu.aop_dir,
-                   AOP(IC_RESULT(ic))->aopu.aop_dir);
-    pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
-                   AOP(IC_RESULT(ic))->aopu.aop_dir,
-                   AOP(IC_RESULT(ic))->aopu.aop_dir);
-    pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                   AOP(IC_RIGHT(ic))->aopu.aop_dir,
-                   AOP(IC_RIGHT(ic))->aopu.aop_dir);
-    pic16_emitcode("xorwf","(%s >>3),f",
-                   AOP(IC_RESULT(ic))->aopu.aop_dir);
-    pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                   AOP(IC_LEFT(ic))->aopu.aop_dir,
-                   AOP(IC_LEFT(ic))->aopu.aop_dir);
-    pic16_emitcode("xorwf","(%s>>3),f",
-                   AOP(IC_RESULT(ic))->aopu.aop_dir);
     break;
   }
 
@@ -464,19 +424,30 @@ static void genAddLit (iCode *ic, int lit)
 {
 
   int size,same;
-  int lo;
+  int lo, offset;
 
   operand *result;
   operand *left;
 
-    FENTRY;
-
+  FENTRY;
 
   left = IC_LEFT(ic);
   result = IC_RESULT(ic);
   same = pic16_sameRegs(AOP(left), AOP(result));
   size = pic16_getDataSize(result);
 
+  if ((AOP_PCODE == AOP_TYPE(left))
+          && (PO_IMMEDIATE == AOP(left)->aopu.pcop->type))
+  {
+      /* see #1888004 for an example case for this */
+      for (offset = 0; offset < size; offset++) {
+          pic16_emitpcode(POC_MOVLW, pic16_newpCodeOpImmd(AOP(left)->aopu.pcop->name,
+                  offset, PCOI(AOP(left)->aopu.pcop)->index + lit, 0));
+          pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+      } // for
+      return;
+  } // if
+
   if(same) {
 
     /* Handle special cases first */
@@ -702,13 +673,16 @@ static void genAddLit (iCode *ic, int lit)
         }
       }
 
+//    } else if (pic16_isLitAop(AOP(left))) {
+//      // adding two literals
+//      assert ( !"adding two literals is not yet supported" );
     } else {
       int clear_carry=0;
 
       /* left is not the accumulator */
       if(lit & 0xff) {
-        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
-        pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+        pic16_mov2w(AOP(left),0);
+        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
       } else {
         pic16_mov2w(AOP(left),0);
         /* We don't know the state of the carry bit at this point */
@@ -1175,31 +1149,15 @@ void pic16_genPlus (iCode *ic)
 
                                 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
                                 pic16_emitpcode(POC_INCF ,  pic16_popGet(AOP(result),0));
-
-                                pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                                                AOP(right)->aopu.aop_dir,
-                                                AOP(right)->aopu.aop_dir);
-                                pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
                         } else { // not same
 
                                 if(AOP_TYPE(left) == AOP_ACC) {
                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
                                         pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
-
-                                        pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                                        AOP(right)->aopu.aop_dir,
-                                        AOP(right)->aopu.aop_dir);
-                                        pic16_emitcode(" xorlw","1");
                                 } else {
                                         pic16_mov2w(AOP(left),0);
                                         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
                                         pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
-
-                                        pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
-                                        pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                                        AOP(right)->aopu.aop_dir,
-                                        AOP(right)->aopu.aop_dir);
-                                        pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
                                 }
 
                                 if(AOP_TYPE(result) != AOP_ACC) {
@@ -1211,7 +1169,6 @@ void pic16_genPlus (iCode *ic)
                                                 pic16_emitpcode(POC_BSF ,   pic16_popGet(AOP(result),0));
                                         } else {
                                                 pic16_emitpcode(POC_MOVWF ,   pic16_popGet(AOP(result),0));
-                                                pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
                                         }
                                 }
                         }
@@ -1223,35 +1180,17 @@ void pic16_genPlus (iCode *ic)
                                 emitCLRZ;
                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(result),0));
-
-                                pic16_emitcode("clrz","");
-
-                                pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                                                AOP(right)->aopu.aop_dir,
-                                                AOP(right)->aopu.aop_dir);
-                                pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
                         } else {
                                 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
                                 pic16_mov2w(AOP(left),0);
                                 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
                                 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
-                                //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
                                 emitMOVWF(right,0);
-
-                                pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
-                                pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                                                AOP(right)->aopu.aop_dir,
-                                                AOP(right)->aopu.aop_dir);
-                                pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
-                                pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
                         }
 
                         while(--size){
                                 emitSKPZ;
                                 pic16_emitpcode(POC_INCF,  pic16_popGet(AOP(result),offset++));
-                                //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
                         }
 
                 }
@@ -1336,6 +1275,13 @@ void pic16_genPlus (iCode *ic)
                 } else {
                         // add regs
 
+                       if (pic16_sameRegs(AOP(left), AOP(result))
+                           && (AOP_SIZE(left) < AOP_SIZE(result)))
+                       {
+                           // extend left operand, sign-bit still intact
+                           pic16_addSign (result, AOP_SIZE(left), !SPEC_USIGN(getSpec(operandType(left))));
+                       }
+
                         // add first bytes
                         for(i=0; i<size; i++) {
                                 if (AOP_TYPE(right) != AOP_ACC)
@@ -1363,26 +1309,27 @@ void pic16_genPlus (iCode *ic)
                           // get right operand into WREG
                           if (i < AOP_SIZE(right)) {
                             pic16_mov2w (AOP(right), i);
-                          } else {
-                            // right is too short
+                         } else {
+                            // right is too short, not overwritten with result
                             pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
                             if (!SPEC_USIGN(getSpec(operandType(right)))) {
                               // right operand is signed
+                             // Make sure that right's sign is not yet overwritten
+                             assert (!pic16_sameRegs (AOP(right), AOP(result)));
                               pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
                               pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
                             }
                           }
 
                           // get left+WREG+CARRY into result
-                          if (i < AOP_SIZE(left)) {
-                            if (pic16_sameRegs (AOP(left), AOP(result))) {
-                              pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
-                            } else {
-                              pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
-                              pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
-                            }
+                         if (pic16_sameRegs (AOP(left), AOP(result))) {
+                           // left might have been extended in result above
+                           pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
+                         } else if (i < AOP_SIZE(left)) {
+                            pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
+                            pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
                           } else {
-                            // left is too short
+                            // left is too short, not overwritten with result
                             pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
                             if (!SPEC_USIGN(getSpec(operandType(left)))) {
                               // left operand is signed
@@ -1536,32 +1483,6 @@ void pic16_addSign(operand *result, int offset, int sign)
   }
 }
 
-/*-----------------------------------------------------------------*/
-/* pic16_genMinusBits - generates code for subtraction  of two bits      */
-/*-----------------------------------------------------------------*/
-void pic16_genMinusBits (iCode *ic)
-{
-    symbol *lbl = newiTempLabel(NULL);
-
-    FENTRY;
-    if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
-        pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
-        pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
-        pic16_emitcode("cpl","c");
-        pic16_emitcode("","%05d_DS_:",(lbl->key+100));
-        pic16_outBitC(IC_RESULT(ic));
-    }
-    else{
-        pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
-        pic16_emitcode("subb","a,acc");
-        pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
-        pic16_emitcode("inc","a");
-        pic16_emitcode("","%05d_DS_:",(lbl->key+100));
-        pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
-        pic16_addSign(IC_RESULT(ic), MSB16, !IS_UNSIGNED(operandType(IC_RESULT(ic))));
-    }
-}
-
 /*-----------------------------------------------------------------*/
 /* pic16_genMinus - generates code for subtraction                       */
 /*-----------------------------------------------------------------*/
@@ -1610,44 +1531,6 @@ void pic16_genMinus (iCode *ic)
     lit = - (long)lit;
 
     genAddLit ( ic,  lit);
-
-#if 0
-    /* add the first byte: */
-    pic16_emitcode("movlw","0x%x", lit & 0xff);
-    pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
-    pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
-    pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),0));
-
-
-    offset = 1;
-    size--;
-
-    while(size-- > 0) {
-
-      lit >>= 8;
-
-      if(lit & 0xff) {
-
-        if((lit & 0xff) == 0xff) {
-          pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(0xff));
-          emitSKPC;
-          pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
-        } else {
-          pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(lit & 0xff));
-          emitSKPNC;
-          pic16_emitpcode(POC_MOVLW,  pic16_popGetLit((lit+1) & 0xff));
-          pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
-        }
-
-      } else {
-        /* do the rlf known zero trick here */
-        pic16_emitpcode(POC_MOVLW,  pic16_popGetLit(1));
-        emitSKPNC;
-        pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
-      }
-      offset++;
-    }
-#endif
   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
     // bit subtraction
 
@@ -1661,18 +1544,12 @@ void pic16_genMinus (iCode *ic)
 
         pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
         pic16_emitpcode(POC_DECF ,  pic16_popGet(AOP(IC_RESULT(ic)),0));
-
-        pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                 AOP(IC_RIGHT(ic))->aopu.aop_dir,
-                 AOP(IC_RIGHT(ic))->aopu.aop_dir);
-        pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
       } else {
 
         if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
           pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
           pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
-        }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
-              (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
+        }else  if( (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
 
           lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
 
@@ -1721,8 +1598,7 @@ void pic16_genMinus (iCode *ic)
       }
 
     }
-  } else   if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
-              (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
+  } else   if((AOP(IC_LEFT(ic))->type == AOP_LIT) &&
               (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
 
     lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
@@ -1772,6 +1648,19 @@ void pic16_genMinus (iCode *ic)
                    pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
                    pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
 
+    if ((AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RESULT(ic)))
+           && pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+       // extend left in result
+       pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_LEFT(ic)), !SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))));
+    }
+
+    if ((AOP_SIZE(IC_RIGHT(ic)) < AOP_SIZE(IC_RESULT(ic)))
+           && pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+       // extend right in result---fails if left resides in result as well...
+       assert ((IC_LEFT(ic) == IC_RIGHT(ic)) || !pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
+       pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_RIGHT(ic)), !SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))));
+    }
+
     if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
@@ -1787,8 +1676,7 @@ void pic16_genMinus (iCode *ic)
         if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
           pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
         else {
-          if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
-              (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
+          if( (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
             pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
           } else {
             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
@@ -1817,10 +1705,13 @@ void pic16_genMinus (iCode *ic)
     offset = 1;
     size--;
 
-    while(size--){
-      if (offset < AOP_SIZE(IC_RIGHT(ic)))
+    while (size--) {
+      if (pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+        pic16_mov2w (AOP(IC_RESULT(ic)), offset);
+      } else if (offset < AOP_SIZE(IC_RIGHT(ic)))
         pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
       else {
+       // right operand is too short, not overwritten with result
         pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
         if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
           // signed -- sign extend the right operand
@@ -1830,27 +1721,23 @@ void pic16_genMinus (iCode *ic)
       }
       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
         pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+      } else if (offset < AOP_SIZE(IC_LEFT(ic))) {
+        pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
+        pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
       } else {
-        if (offset < AOP_SIZE(IC_LEFT(ic))) {
-          pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
-          pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-        } else {
-          // zero extend the left operand
-          pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
-          if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
-            // signed -- sign extend the left operand
-            pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-            pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
-          }
-          pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+        // left operand is too short, not overwritten with result
+        pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
+        if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
+          // signed -- sign extend the left operand
+          pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+          pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
         }
+        pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
       }
       offset++;
     }
-
   }
 
-
   //    adjustArithmeticResult(ic);
 
  release: