* src/configure.in: check for endianess (even while cross-compiling)
[fw/sdcc] / src / pic / genarith.c
index d6e5d7968b29617e066bb14461c9799ea969c073..f998a7c4af8a20e65ca715572b1c03cc4a88b13c 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"
@@ -738,34 +721,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++;
       }
     }
   }
@@ -1557,6 +1556,7 @@ void genUMult8XLit_16 (operand *left,
   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__);
@@ -1592,6 +1592,98 @@ void genUMult8XLit_16 (operand *left,
       emitpcode(POC_MOVFW, popGet(AOP(left),0));
       emitpcode(POC_ADDWF, popGet(AOP(left),0));
       emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 5:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
+      return;
+    case 6:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 7:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 7*F
+      return;
+    case 8:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
+      return;
+    case 9:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 10:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 11:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 11*F
+      return;
+    case 12:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 13:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 13*F
+      return;
+    case 14:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 11*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 14*F
+      return;
+    case 15:
+      temp = popGetTempReg();
+      if(!temp) {
+       fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
+       exit(1);
+      }
+      emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+      emitpcode(POC_MOVWF,  temp);
+      emitpcode(POC_ANDLW,  popGetLit(0xf0));
+      emitpcode(POC_MOVWF,  popGet(AOP(left),0));
+      emitpcode(POC_SWAPFW, temp);
+      emitpcode(POC_SUBWF,  popGet(AOP(left),0));
+      popReleaseTempReg(temp);
       return;
     case 16:
       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
@@ -1603,6 +1695,24 @@ void genUMult8XLit_16 (operand *left,
       emitpcode(POC_ANDLW,  popGetLit(0xf0));
       emitpcode(POC_ADDWF,  popGet(AOP(left),0));
       return;
+    case 32:
+      emitpcode(POC_SWAPF,  popGet(AOP(left),0));
+      emitpcode(POC_RLFW,   popGet(AOP(left),0));
+      emitpcode(POC_ANDLW,  popGetLit(0xe0));
+      emitpcode(POC_MOVWF,  popGet(AOP(left),0));
+      return;
+    case 64:
+      emitpcode(POC_SWAPF,  popGet(AOP(left),0));
+      emitpcode(POC_RLF,    popGet(AOP(left),0));
+      emitpcode(POC_RLFW,   popGet(AOP(left),0));
+      emitpcode(POC_ANDLW,  popGetLit(0xc0));
+      emitpcode(POC_MOVWF,  popGet(AOP(left),0));
+      return;
+    case 128:
+      emitpcode(POC_RRFW,   popGet(AOP(left),0));
+      emitpcode(POC_CLRF,   popGet(AOP(left),0));
+      emitpcode(POC_RRF,    popGet(AOP(left),0));
+      return;
 
     }
   } else {