started fixing bug #737001 (SDCC not clearing uninitialized variables) for the mcs51...
[fw/sdcc] / src / pic / genarith.c
index 797c7dfc981e6bf6721953ce9fc3307622836209..3809c711201f92bf0e9baaa9633f6dbdf6fa006a 100644 (file)
 #include "SDCCglobl.h"
 #include "newalloc.h"
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
 #define __FUNCTION__           __FILE__
 #endif
 
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
-#else
-#ifdef HAVE_MACHINE_ENDIAN_H
-#include <machine/endian.h>
-#else
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#else
-#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
-#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
-#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
-#endif
-#endif
-#endif
-#endif
-
 #include "common.h"
 #include "SDCCpeeph.h"
 #include "ralloc.h"
@@ -135,6 +118,8 @@ const char *pCodeOpType(  pCodeOp *pcop)
       return  "PO_INTCON";
     case  PO_GPR_REGISTER:
       return  "PO_GPR_REGISTER";
+    case  PO_GPR_POINTER:
+      return  "PO_GPR_POINTER";
     case  PO_GPR_BIT:
       return  "PO_GPR_BIT";
     case  PO_GPR_TEMP:
@@ -738,34 +723,50 @@ static void genAddLit (iCode *ic, int lit)
       }
 
     } else {
+      int clear_carry=0;
 
       /* left is not the accumulator */
       if(lit & 0xff) {
        emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
        emitpcode(POC_ADDFW, popGet(AOP(left),0));
-      } else
+      } else {
        emitpcode(POC_MOVFW, popGet(AOP(left),0));
-
+       /* We don't know the state of the carry bit at this point */
+       clear_carry = 1;
+      }
       //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
       emitMOVWF(result,0);
-      lit >>= 8;
       while(--size) {
       
+       lit >>= 8;
        if(lit & 0xff) {
-         emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
-         //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
-         emitMOVWF(result,offset);
-         emitpcode(POC_MOVFW, popGet(AOP(left),offset));
-         emitSKPNC;
-         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
-         emitpcode(POC_ADDWF,  popGet(AOP(result),offset));
+         if(clear_carry) {
+           /* The ls byte of the lit must've been zero - that 
+              means we don't have to deal with carry */
+
+           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+           emitpcode(POC_ADDFW,  popGet(AOP(left),offset));
+           emitpcode(POC_MOVWF, popGet(AOP(left),offset));
+
+           clear_carry = 0;
+
+         } else {
+           emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+           //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
+           emitMOVWF(result,offset);
+           emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+           emitSKPNC;
+           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
+           emitpcode(POC_ADDWF,  popGet(AOP(result),offset));
+         }
+
        } else {
          emitpcode(POC_CLRF,  popGet(AOP(result),offset));
          emitpcode(POC_RLF,   popGet(AOP(result),offset));
          emitpcode(POC_MOVFW, popGet(AOP(left),offset));
          emitpcode(POC_ADDWF, popGet(AOP(result),offset));
        }
-      offset++;
+       offset++;
       }
     }
   }
@@ -976,30 +977,47 @@ void genPlus (iCode *ic)
     offset = 1;
 
 
-    while(size--){
-      if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-       emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
-       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
-
-       pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
-       pic14_emitcode("movwf","%s",  aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
+    if(size){
+      if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+        if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
+          while(size--){
+            emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
+            emitSKPNC;
+            emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+            emitpcode(POC_ADDLW,   popGet(AOP(IC_LEFT(ic)),offset));
+            emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
+            offset++;
+          }
+        } else {
+          while(size--){
+            emitpcode(POC_MOVFW,   popGet(AOP(IC_LEFT(ic)),offset));
+            emitSKPNC;
+            emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
+            emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
+            offset++;
+          }
+        }
+      } else {
+        PIC_OPCODE poc = POC_MOVFW;
+        if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+          poc = POC_MOVLW;
+        while(size--){
+          if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+            emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
+            emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+          }
+          emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
+          emitSKPNC;
+          emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+          emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
+          offset++;
+        }
       }
-
-      emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
-      emitSKPNC;
-      emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
-      emitpcode(POC_ADDWF,   popGet(AOP(IC_RESULT(ic)),offset));
-
-      /*
-       pic14_emitcode("movf","%s,w",  aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
-       emitSKPNC;
-       pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
-       pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
-      */
-
-      offset++;
     }
-
   }
 
   if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
@@ -1011,8 +1029,28 @@ void genPlus (iCode *ic)
     size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
 
     /* First grab the carry from the lower bytes */
-    emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
-    emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
+    if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { 
+      int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
+      PIC_OPCODE poc = POC_MOVFW;
+      if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
+       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
+       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+        poc = POC_MOVLW;
+      while(leftsize-- > 0) {
+        emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
+        emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+        emitSKPNC;
+        emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
+        offset++;
+        if (size)
+          size--;
+        else
+          break;
+      }
+    } else {
+      emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
+      emitpcode(POC_RLF,  popGet(AOP(IC_RESULT(ic)),offset));
+    }
 
 
     if(sign) {
@@ -1506,35 +1544,53 @@ void genMinus (iCode *ic)
       }
     }
 
-    /*
-      emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
-
-      if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-      emitpcode(POC_SUBFW,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-      } else {
-      emitpcode(POC_SUBFW,  popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
-      emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-      }
-    */
+    size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
     offset = 1;
-    size--;
 
-    while(size--){
-      if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-       emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
-       emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
+    if(size){
+      if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+        if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
+          while(size--){
+            emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
+            emitSKPC;
+            emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+            emitpcode(POC_SUBLW,   popGet(AOP(IC_LEFT(ic)),offset));
+            emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
+            offset++;
+          }
+        } else {
+          while(size--){
+            emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
+            emitSKPC;
+            emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+            emitpcode(POC_SUBFW,   popGet(AOP(IC_LEFT(ic)),offset));
+            emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
+            offset++;
+          }
+        }
+      } else {
+        PIC_OPCODE poc = POC_MOVFW;
+        if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
+          (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+          poc = POC_MOVLW;
+      while(size--){
+          if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+            emitpcode(POC_MOVFW,  popGet(AOP(IC_LEFT(ic)),offset));
+            emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
+          }
+          emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
+          emitSKPC;
+          emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
+          emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
+          offset++;
+        }
       }
-      emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
-      emitSKPC;
-      emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
-      emitpcode(POC_SUBWF,  popGet(AOP(IC_RESULT(ic)),offset));
-
-      offset++;
     }
-
   }
 
-
   //    adjustArithmeticResult(ic);
         
  release: