]> git.gag.com Git - fw/sdcc/commitdiff
*** empty log message ***
authorsdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 11 Dec 2001 15:20:51 +0000 (15:20 +0000)
committersdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 11 Dec 2001 15:20:51 +0000 (15:20 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1673 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/pic/gen.c
src/pic/genarith.c
src/pic/pcode.c
src/pic/pcode.h
src/pic/ralloc.c
src/pic/ralloc.h
src/regression/compare7.c [new file with mode: 0644]
src/regression/compare8.c [new file with mode: 0644]

index 50f5c8672fc29f6011af585e1c68bbe49a73a8fd..f34f62775c8ff6944dd567e879fbd5f3c7ebca39 100644 (file)
@@ -3481,6 +3481,34 @@ static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
   rifx->generated = 1;
 }
+
+/*-----------------------------------------------------------------*/
+/* genChkZeroes :- greater or less than comparison                 */
+/*     For each byte in a literal that is zero, inclusive or the   */
+/*     the corresponding byte in the operand with W                */
+/*     returns true if any of the bytes are zero                   */
+/*-----------------------------------------------------------------*/
+static int genChkZeroes(operand *op, int lit,  int size)
+{
+
+  int i;
+  int flag =1;
+
+  while(size--) {
+    i = (lit >> (size*8)) & 0xff;
+
+    if(i==0) {
+      if(flag) 
+       emitpcode(POC_MOVFW, popGet(AOP(op),size));
+      else
+       emitpcode(POC_IORFW, popGet(AOP(op),size));
+      flag = 0;
+    }
+  }
+
+  return (flag==0);
+}
+
 /*-----------------------------------------------------------------*/
 /* genCmp :- greater or less than comparison                       */
 /*-----------------------------------------------------------------*/
@@ -3523,6 +3551,7 @@ static void genCmp (operand *left,operand *right,
 
       symbol *lbl  = newiTempLabel(NULL);
       int flag;
+      int emitFinalCheck=1;
       symbol *truelbl  = newiTempLabel(NULL);
 
 
@@ -3532,10 +3561,18 @@ static void genCmp (operand *left,operand *right,
 
        DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
 
+       /* special cases */
 
+       if(lit == 0) {
+
+         if(sign != 0) 
+           genSkipCond(&rIfx,left,size-1,7);
+         else 
+           /* no need to compare to 0...*/
+           /* NOTE: this is a de-generate compare that most certainly 
+            *       creates some dead code. */
+           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
 
-       if(lit == 0 && sign == 0) {
-         /* no need to compare to 0...*/
          if(ifx) ifx->generated = 1;
          return;
 
@@ -3543,63 +3580,215 @@ static void genCmp (operand *left,operand *right,
        size--;
 
        if(size == 0) {
-         i = (lit >> (size*8)) & 0xff;
+         //i = (lit >> (size*8)) & 0xff;
          DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
        
-         switch(i) {
-         case 0:
-           if(sign) 
-             genSkipCond(&rIfx,left,0,7);
-           break;
-         default:
-           emitpcode(POC_MOVFW, popGet(AOP(left),size));
+         emitpcode(POC_MOVFW, popGet(AOP(left),size));
 
-           i = ((0-i) & 0xff);
-           if(sign) {
+         i = ((0-lit) & 0xff);
+         if(sign) {
+           if( i == 0x81) { 
+             /* lit is 0x7f, all signed chars are less than
+              * this except for 0x7f itself */
+             emitpcode(POC_XORLW, popGetLit(0x7f));
+             genSkipz2(&rIfx);
+           } else {
              emitpcode(POC_ADDLW, popGetLit(0x80));
              emitpcode(POC_ADDLW, popGetLit(i^0x80));
-           } else {
-             emitpcode(POC_ADDLW, popGetLit(i));
+             genSkipc(&rIfx);
            }
+
+         } else {
+           emitpcode(POC_ADDLW, popGetLit(i));
            genSkipc(&rIfx);
+
          }
 
          if(ifx) ifx->generated = 1;
          return;
        }
 
-
+       /* chars are out of the way. now do ints and longs */
 
 
        DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
        
-       flag=1;
-       size++;
-       while(size--) {
-         i = (lit >> (size*8)) & 0xff;
-         if(sign && flag) {
-           /* handle the first byte differently in signed compares */
+       /* special cases */
+
+       if(sign) {
+         unsigned int mlit = -lit;
+
+         if(lit == 0) {
+           genSkipCond(&rIfx,left,size,7);
+           if(ifx) ifx->generated = 1;
+           return;
+         }
 
+         if(lit <0x100) {
+           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
+           emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
+           emitpcode(POC_ADDFW, popGet(AOP(left),0));
+           emitpcode(POC_MOVFW, popGet(AOP(left),1));
+
+           while(size > 1)
+             emitpcode(POC_IORFW, popGet(AOP(left),size--));
+
+           emitSKPNZ;
+
+           genSkipc(&rIfx);
+           emitpLabel(truelbl->key);
+           if(ifx) ifx->generated = 1;
+           return;
+
+         }
+
+         if(size == 1) {
+
+           if( (lit & 0xff) == 0) {
+             /* lower byte is zero */
+             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+             i = ((lit >> 8) & 0xff) ^0x80;
              emitpcode(POC_MOVFW, popGet(AOP(left),size));
-             emitpcode(POC_ADDLW, popGetLit(0x80));
-             emitpcode(POC_ADDLW, popGetLit(((-i)&0xff) ^ 0x80));
+             emitpcode(POC_ADDLW, popGetLit( 0x80));
+             emitpcode(POC_ADDLW, popGetLit(0x100-i));
              genSkipc(&rIfx);
-             emitSKPZ;
+
+
+             if(ifx) ifx->generated = 1;
+             return;
+
+           }
+         } else {
+           /* Special cases for signed longs */
+           if( (lit & 0xffffff) == 0) {
+             /* lower byte is zero */
+             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+             i = ((lit >> 8*3) & 0xff) ^0x80;
+             emitpcode(POC_MOVFW, popGet(AOP(left),size));
+             emitpcode(POC_ADDLW, popGetLit( 0x80));
+             emitpcode(POC_ADDLW, popGetLit(0x100-i));
+             genSkipc(&rIfx);
+
+
+             if(ifx) ifx->generated = 1;
+             return;
+
+           }
+
+#if 0
+           if( lit < 0x10000) {
+             /* upper word is zero */
+             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
              emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
 
-           flag=0;
+             emitpcode(POC_MOVLW, popGetLit((lit >> (1*8)) & 0xff));
+             emitpcode(POC_SUBFW, popGet(AOP(left),1));
+             emitpcode(POC_MOVLW, popGetLit((lit & 0xff));
+             emitSKPNZ;
+             emitpcode(POC_SUBFW, popGet(AOP(left),0));
+
+             emitpcode(POC_IORFW, popGet(AOP(left),2));
+             emitpcode(POC_IORFW, popGet(AOP(left),3));
+
+             emitSKPNZ;
+
+             genSkipc(&rIfx);
+             emitpLabel(truelbl->key);
+             if(ifx) ifx->generated = 1;
+             return;
+
+           }
+#endif
+
+         }
+
+
+         if(lit & (0x80 << (size*8))) {
+           /* lit is negative */
+           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+           genSkipCond(&rIfx,left,size,7);
          } else {
+           /* lit is positive */
+           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
+           emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
+
+         }
+
+         /*
+           This works, but is only good for ints.
+           It also requires a "known zero" register.
+           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
+           emitpcode(POC_ADDFW, popGet(AOP(left),0));
+           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
+           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
+           emitpcode(POC_ADDFW, popGet(AOP(left),1));
+           genSkipc(&rIfx);
+
+           emitpLabel(truelbl->key);
+           if(ifx) ifx->generated = 1;
+           return;
+         **/
+         
+         /* There are no more special cases, so perform a general compare */
+  
+         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
+         emitpcode(POC_SUBFW, popGet(AOP(left),size));
+
+         while(size--) {
+
+           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
+           emitSKPNZ;
+           emitpcode(POC_SUBFW, popGet(AOP(left),size));
+         }
+
+         genSkipc(&rIfx);
+
+         emitpLabel(truelbl->key);
+
+         if(ifx) ifx->generated = 1;
+         return;
+
+
+       }
+
+
+       /* sign is out of the way. So now do an unsigned compare */
+       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
+
+
+       //genChkZeroes(left)
+
+       /* General case - compare to an unsigned literal on the right.*/
+
+       i = (lit >> (size*8)) & 0xff;
+       emitpcode(POC_MOVLW, popGetLit(i));
+       emitpcode(POC_SUBFW, popGet(AOP(left),size));
+       while(size--) {
+         i = (lit >> (size*8)) & 0xff;
 
+         if(i) {
            emitpcode(POC_MOVLW, popGetLit(i));
+           emitSKPNZ;
            emitpcode(POC_SUBFW, popGet(AOP(left),size));
-           if(size) {
-             emitSKPZ;
-             emitpcode(POC_GOTO,  popGetLabel(lbl->key));
-           }
+         } else {
+           /* this byte of the lit is zero, 
+            *if it's not the last then OR in the variable */
+           if(size)
+             emitpcode(POC_IORFW, popGet(AOP(left),size));
          }
        }
+
+
        emitpLabel(lbl->key);
-       genSkipc(&rIfx);
+       if(emitFinalCheck)
+         genSkipc(&rIfx);
        if(sign)
          emitpLabel(truelbl->key);
 
@@ -3611,24 +3800,36 @@ static void genCmp (operand *left,operand *right,
 
       if(AOP_TYPE(left) == AOP_LIT) {
        //symbol *lbl = newiTempLabel(NULL);
-
+       unsigned long mlit;
        lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
+       mlit = -lit;
 
        DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
 
        /* Special cases */
-       if((lit == 0)&& (sign==0)) {
+       if((lit == 0) && (sign == 0)){
 
          size--;
          emitpcode(POC_MOVFW, popGet(AOP(right),size));
          while(size) 
            emitpcode(POC_IORFW, popGet(AOP(right),--size));
+
+         //rIfx.condition ^= 1;
          genSkipz2(&rIfx);
          if(ifx) ifx->generated = 1;
          return;
        }
 
        if(size==1) {
+         /* Special cases */
+         lit &= 0xff;
+         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
+           /* degenerate compare can never be true */
+           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+           if(ifx) ifx->generated = 1;
+           return;
+         }
+
          if(sign) {
            if((lit+1)&0xff) {
              emitpcode(POC_MOVFW, popGet(AOP(right),0));
@@ -3637,6 +3838,7 @@ static void genCmp (operand *left,operand *right,
              rIfx.condition ^= 1;
              genSkipc(&rIfx);
            } else {
+             rIfx.condition ^= 1;
              genSkipCond(&rIfx,right,0,7);
            }
            
@@ -3652,33 +3854,84 @@ static void genCmp (operand *left,operand *right,
              genSkipz2(&rIfx);
            }
          }
+
+         if(ifx) ifx->generated = 1;
+         return;
+
        } else {
 
-         flag = 1;
-         while(size--) {
-           i = (lit >> (size*8)) & 0xff;
+         /* Size is greater than 1 */
 
-           if(flag && sign) {
-             /* Handle first byte of compare differently */
 
-             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-             if(i) {
-               emitpcode(POC_MOVFW, popGet(AOP(right),size));
-               emitpcode(POC_ADDLW, popGetLit(0x80));
-               emitpcode(POC_SUBLW, popGetLit( (i & 0xff) ^ 0x80));
-               //rIfx.condition ^= 1;
-               genSkipc(&rIfx);
-               emitSKPZ;
-               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
-             } else {
-               rIfx.condition ^= 1;
-               genSkipCond(&rIfx,right,size,7);
-               rIfx.condition ^= 1;
-             }
+         if(sign) {
+           int mlit = -lit;
+           int lp1 = lit+1;
+
+           size--;
+
+           if(lp1 == 0) {
+             /* this means lit = 0xffffffff, or -1 */
+
+
+             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
+             rIfx.condition ^= 1;
+             genSkipCond(&rIfx,right,size,7);
+             if(ifx) ifx->generated = 1;
+             return;
+           }
+
+           if(lit == 0) {
+             int s = size;
+             emitpcode(POC_MOVFW, popGet(AOP(right),size));
+             while(size--)
+               emitpcode(POC_IORFW, popGet(AOP(right),size));
+
+             emitSKPZ;
+             rIfx.condition ^= 1;
+             genSkipCond(&rIfx,right,s,7);
+             if(ifx) ifx->generated = 1;
+             return;
+           }
+
+
+           if(lit & (0x80 << (size*8))) {
+             /* Lit is less than zero */
+             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
+             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
 
-             flag = 0;
            } else {
+             /* Lit is greater than or equal to zero */
+             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
+             rIfx.condition ^= 1;
+             genSkipCond(&rIfx,right,size,7);
+             rIfx.condition ^= 1;
+
+           }
+           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
+           emitpcode(POC_SUBFW, popGet(AOP(right),size));
+
+           while(size--) {
+
+             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
+             emitSKPNZ;
+             emitpcode(POC_SUBFW, popGet(AOP(right),size));
+           }
+           rIfx.condition ^= 1;
+           genSkipc(&rIfx);
+
+           emitpLabel(truelbl->key);
+
+           if(ifx) ifx->generated = 1;
+           return;
+
+         } else {
+           /* Unsigned compare for sizes greater than 1 */
+
+           while(size--) {
+             i = (lit >> (size*8)) & 0xff;
+
 
              if(size) {
                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -3687,28 +3940,27 @@ static void genCmp (operand *left,operand *right,
                emitSKPZ;
                emitpcode(POC_GOTO,  popGetLabel(lbl->key));
              } else {
-             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+               DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
                emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
                emitpcode(POC_SUBFW, popGet(AOP(right),size));
 
              }
            }
-         }
 
-         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-         emitpLabel(lbl->key);
+           emitpLabel(lbl->key);
 
-         rIfx.condition ^= 1;
-         genSkipc(&rIfx);
+           rIfx.condition ^= 1;
+           genSkipc(&rIfx);
 
-       }
+         }
        if(sign)
          emitpLabel(truelbl->key);
        if(ifx) ifx->generated = 1;
        return;
+       }
       }
-
       /* Compare two variables */
 
       DEBUGpic14_emitcode(";sign","%d",sign);
@@ -4108,18 +4360,19 @@ static void genCmpEq (iCode *ic, iCode *ifx)
     is not */
     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
-        operand *t = IC_RIGHT(ic);
-        IC_RIGHT(ic) = IC_LEFT(ic);
-        IC_LEFT(ic) = t;
+      operand *tmp = right ;
+      right = left;
+      left = tmp;
     }
 
+
     if(ifx && !AOP_SIZE(result)){
         symbol *tlbl;
         /* if they are both bit variables */
         if (AOP_TYPE(left) == AOP_CRY &&
             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
             if(AOP_TYPE(right) == AOP_LIT){
-                unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+                unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
                 if(lit == 0L){
                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
                     pic14_emitcode("cpl","c");
@@ -4153,7 +4406,6 @@ static void genCmpEq (iCode *ic, iCode *ifx)
          if(AOP_TYPE(right) == AOP_LIT) {
            lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
            
-
            switch(size) {
 
            case 1:
@@ -4294,7 +4546,7 @@ static void genCmpEq (iCode *ic, iCode *ifx)
     if (AOP_TYPE(left) == AOP_CRY &&
         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
         if(AOP_TYPE(right) == AOP_LIT){
-            unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+            unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
             if(lit == 0L){
                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
                 pic14_emitcode("cpl","c");
@@ -8715,10 +8967,6 @@ static void genCast (iCode *ic)
     size = AOP_SIZE(right);
     offset = 0 ;
     while (size--) {
-      pic14_emitcode(";","%d",__LINE__);
-      /* aopPut(AOP(result),
-            aopGet(AOP(right),offset,FALSE,FALSE),
-            offset); */
       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
       offset++;
@@ -8728,39 +8976,31 @@ static void genCast (iCode *ic)
     size = AOP_SIZE(result) - AOP_SIZE(right);
     /* if unsigned or not an integral type */
     if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
-      while (size--) {
-         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
-         pic14_emitcode("clrf","%s  ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
-         offset++;
-      }
+      while (size--)
+       emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
     } else {
       /* we need to extend the sign :{ */
 
-      emitpcodeNULLop(POC_CLRW);
-
-      if(offset)
-       emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
-      else
-       emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
-
-      emitpcode(POC_MOVLW,   popGetLit(0xff));
+      if(size == 1) {
+       /* Save one instruction of casting char to int */
+       emitpcode(POC_CLRF,   popGet(AOP(result),offset));
+       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
+       emitpcode(POC_DECF,   popGet(AOP(result),offset));
+      } else {
+       emitpcodeNULLop(POC_CLRW);
 
-        pic14_emitcode("clrw","");
-       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                AOP(right)->aopu.aop_dir,
-                AOP(right)->aopu.aop_dir);
-        pic14_emitcode("movlw","0xff");
-        while (size--) {
-         emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
-         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
-         offset++;
-         // aopPut(AOP(result),"a",offset++);
-       }
+       if(offset)
+         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
+       else
+         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
+       
+       emitpcode(POC_MOVLW,   popGetLit(0xff));
 
+        while (size--)
+         emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
+      }
     }
 
-    /* we are done hurray !!!! */
-
 release:
     freeAsmop(right,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
index a35f558983201b034eaa47aa7e91a625854f70a8..a4e501bb7489af652e8d55a78d236be5c94a036c 100644 (file)
@@ -65,6 +65,7 @@
 
 
 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
+void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
 
 const char *AopType(short type)
 {
@@ -727,6 +728,8 @@ void genPlus (iCode *ic)
   aopOp (IC_RIGHT(ic),ic,FALSE);
   aopOp (IC_RESULT(ic),ic,TRUE);
 
+  DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
+
   /* if literal, literal on the right or
      if left requires ACC or right is already
      in ACC */
@@ -879,6 +882,9 @@ void genPlus (iCode *ic)
       
   } else {
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);    
+
+    /* Add the first bytes */
+
     if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
       emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
       emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
@@ -907,8 +913,9 @@ void genPlus (iCode *ic)
       }
     }
 
+    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))) ) {
@@ -936,6 +943,49 @@ void genPlus (iCode *ic)
 
   }
 
+  if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
+    int sign =  !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
+                 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
+
+
+    /* Need to extend result to higher bytes */
+    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(sign) {
+      /* Now this is really horrid. Gotta check the sign of the addends and propogate
+       * to the result */
+
+      emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
+      emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
+      emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
+      emitpcode(POC_DECF,  popGet(AOP(IC_RESULT(ic)),offset));
+
+      /* if chars or ints or being signed extended to longs: */
+      if(size) {
+       emitpcode(POC_MOVLW, popGetLit(0));
+       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
+       emitpcode(POC_MOVLW, popGetLit(0xff));
+      }
+    }
+
+    offset++;
+    while(size--) {
+      
+      if(sign)
+       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+      else
+       emitpcode(POC_CLRF,  popGet(AOP(IC_RESULT(ic)),offset));
+
+      offset++;
+    }
+  }
+
+
   //adjustArithmeticResult(ic);
 
  release:
index 04744116156dab934da3623bd6db45f88ebaf28c..884ff12e515430e569c706e97f28c3ed6be51ee4 100644 (file)
@@ -40,6 +40,8 @@ pCodeOpReg pc_fsr       = {{PO_FSR,     "FSR"}, -1, NULL,NULL};
 pCodeOpReg pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,NULL};
 pCodeOpReg pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,NULL};
 
+pCodeOpReg pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,NULL};
+
 static int mnemonics_initialized = 0;
 
 
@@ -773,11 +775,14 @@ void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
 void  pCodeInitRegisters(void)
 {
 
-  pc_fsr.rIdx = 4;
-  pc_fsr.r = pic14_regWithIdx(4);
+  pc_fsr.rIdx = IDX_FSR;
+  pc_fsr.r = pic14_regWithIdx(IDX_FSR);
+
+  pc_indf.rIdx = IDX_INDF;
+  pc_indf.r = pic14_regWithIdx(IDX_INDF);
 
-  pc_indf.rIdx = 0;
-  pc_indf.r = pic14_regWithIdx(0);
+  pc_kzero.rIdx = IDX_KZ;
+  pc_kzero.r = pic14_regWithIdx(IDX_KZ);
 
 }
 
@@ -2076,8 +2081,8 @@ void AnalyzepBlock(pBlock *pb)
 
   /* Find all of the registers used in this pBlock */
   for(pc = pb->pcHead; pc; pc = pc->next) {
-    if(pc->type == PC_OPCODE) {
-      if(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_TEMP) {
+    if(pc->type == PC_OPCODE && PCI(pc)->pcop) {
+      if(PCI(pc)->pcop->type == PO_GPR_TEMP) {
 
        /* Loop through all of the registers declared so far in
           this block and see if we find this one there */
@@ -2102,7 +2107,20 @@ void AnalyzepBlock(pBlock *pb)
        } else 
          fprintf(stderr,"found register in pblock: reg %d\n",r->rIdx);
       }
+      if(PCI(pc)->pcop->type == PO_GPR_REGISTER) {
+       if(PCOR(PCI(pc)->pcop)->r) {
+         pic14_allocWithIdx (PCOR(PCI(pc)->pcop)->r->rIdx);
+         fprintf(stderr,"found register in pblock: reg 0x%x\n",PCOR(PCI(pc)->pcop)->r->rIdx);
+       } else {
+         if(PCI(pc)->pcop->name)
+           fprintf(stderr,"ERROR: %s is a NULL register\n",PCI(pc)->pcop->name );
+         else
+           fprintf(stderr,"ERROR: NULL register\n");
+       }
+      }
     }
+
+
   }
 }
 
index 1d5961ebc5c219abcc9cdb9233e8c223e3478e9a..ed230e7431379184256baa5f3cea941b53db1366 100644 (file)
@@ -607,6 +607,7 @@ extern pCodeOpReg pc_indf;
 extern pCodeOpReg pc_fsr;
 extern pCodeOpReg pc_pcl;
 extern pCodeOpReg pc_pclath;
+extern pCodeOpReg pc_kzero;
 
 
 ////////////////////   DELETE THIS ///////////////////
index 5135db54c7ac7c1c56dfcf0b56251b1d1d3de1c6..08b72f929a38ded88573195b48cf01bd2b43583e 100644 (file)
@@ -134,8 +134,12 @@ regs regspic14[] =
   {REG_STK, PO_GPR_TEMP, 0x46, "r0x46", "r0x46", 0x46, 1, 0},
   {REG_STK, PO_GPR_TEMP, 0x47, "r0x47", "r0x47", 0x47, 1, 0},
 
-  {REG_STK, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
-  {REG_STK, PO_INDF, 0, "INDF", "INDF", 0, 1, 0},
+  {REG_SFR, PO_GPR_REGISTER, IDX_KZ,    "KZ",  "KZ",   IDX_KZ,   1, 0}, /* Known zero */
+
+
+  {REG_STK, PO_FSR,      IDX_FSR,  "FSR",  "FSR",  IDX_FSR,  1, 0},
+  {REG_STK, PO_INDF,     IDX_INDF, "INDF", "INDF", IDX_INDF, 1, 0},
+
 
 };
 
@@ -532,6 +536,29 @@ pic14_regWithIdx (int idx)
   exit (1);
 }
 
+/*-----------------------------------------------------------------*/
+/* pic14_regWithIdx - returns pointer to register wit index number       */
+/*-----------------------------------------------------------------*/
+regs *
+pic14_allocWithIdx (int idx)
+{
+  int i;
+
+  debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
+
+  for (i = 0; i < pic14_nRegs; i++)
+    if (regspic14[i].rIdx == idx){
+      debugLog ("%s - alloc fount index = 0x%x\n", __FUNCTION__,idx);
+      regspic14[i].wasUsed = 1;
+      regspic14[i].isFree = 0;
+      return &regspic14[i];
+    }
+  //return &regspic14[0];
+  fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
+  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+         "regWithIdx not found");
+  exit (1);
+}
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 regs *
@@ -2001,8 +2028,10 @@ pic14_deallocateAllRegs ()
 
   debugLog ("%s\n", __FUNCTION__);
   for (i = 0; i < pic14_nRegs; i++) {
-    regspic14[i].isFree = 1;
-    regspic14[i].wasUsed = 0;
+    if(regspic14[i].pc_type == PO_GPR_TEMP) {
+      regspic14[i].isFree = 1;
+      regspic14[i].wasUsed = 0;
+    }
   }
 }
 
index c0801c2865d26784bfef82d7a15f4b6465169764..b99341b8504e18b7c0ffcf4d96dfdd70905e1cd1 100644 (file)
@@ -71,5 +71,11 @@ regs *pic14_regWithIdx (int);
 void  pic14_freeAllRegs ();
 void  pic14_deallocateAllRegs ();
 regs *pic14_findFreeReg(short type);
+regs *pic14_allocWithIdx (int idx);
+
+/* Define register address that are constant across PIC family */
+#define IDX_INDF    0
+#define IDX_FSR     4
+#define IDX_KZ      0x7fff   /* Known zero - actually just a general purpose reg. */
 
 #endif
diff --git a/src/regression/compare7.c b/src/regression/compare7.c
new file mode 100644 (file)
index 0000000..3ea4bd6
--- /dev/null
@@ -0,0 +1,298 @@
+// Signed comparisons of the form:  (variable<LIT)
+//
+// This regression test exercises all of the boundary
+// conditions in literal less than comparisons. There
+// are numerous opportunities to optimize these comparison
+// and each one has an astonishing capability of failing
+// a boundary condition.
+
+unsigned char success = 0;
+unsigned char failures = 0;
+unsigned char dummy = 0;
+unsigned char result = 0;
+
+//bit bit0 = 0;
+long int0 = 0;
+long int1 = 0;
+signed char char0 = 0;
+signed char char1 = 0;
+char long0 = 0;
+char long1 = 0;
+
+void
+done ()
+{
+  dummy++;
+}
+
+
+void c_char_lt_lit1(unsigned char expected_result)
+{
+  result = 0;
+
+  if(char0 < -0x7f)
+    result |= 1;
+
+
+  if(char0 < -1)
+    result |= 2;
+
+  if(char0 < 0)
+    result |= 4;
+
+  if(char0 < 1)
+    result |= 8;
+
+  if(char0 < 0x7f)
+    result |= 0x10;
+  
+  if(result != expected_result)
+    failures++;
+}
+
+
+void char_compare(void)
+{
+  char0 = 0x7f;
+  c_char_lt_lit1(0);
+
+  char0 = 0x7e;
+  c_char_lt_lit1(0x10);
+
+  char0 = 0x40;
+  c_char_lt_lit1(0x10);
+
+  char0 = 0x2;
+  c_char_lt_lit1(0x10);
+
+  char0 = 0x1;
+  c_char_lt_lit1(0x10);
+
+  char0 = 0;
+  c_char_lt_lit1(0x18);
+
+  char0 = -1;
+  c_char_lt_lit1(0x1c);
+
+  char0 = -2;
+  c_char_lt_lit1(0x1e);
+
+  char0 = -0x40;
+  c_char_lt_lit1(0x1e);
+
+  char0 = -0x7e;
+  c_char_lt_lit1(0x1e);
+
+  char0 = -0x7f;
+  c_char_lt_lit1(0x1e);
+
+  char0 = 0x80;
+  c_char_lt_lit1(0x1f);
+
+
+  /* Now test entire range */
+
+  for(char0=1; char0 != 0x7f; char0++)
+    c_char_lt_lit1(0x10);
+
+
+  for(char0=-0x7f; char0 != -1; char0++)
+    c_char_lt_lit1(0x1e);
+
+
+}
+
+void c_int_lt_lit1(unsigned char expected_result)
+{
+  result = 0;
+
+  if(int0 < 0)
+    result |= 1;
+
+  if(int0 < 1)
+    result |= 2;
+
+
+  if(int0 < 0xff)
+    result |= 4;
+
+  if(int0 < 0x100)
+    result |= 8;
+
+  if(int0 < 0x0101)
+    result |= 0x10;
+  
+  if(int0 < 0x01ff)
+    result |= 0x20;
+  
+  if(int0 < 0x0200)
+    result |= 0x40;
+
+  if(int0 < 0x0201)
+    result |= 0x80;
+
+  if(result != expected_result)
+    failures=1;
+
+}
+
+
+void int_compare1(void)
+{
+  int0 = -1;
+  c_int_lt_lit1(0xff);
+
+  int0 = 0;
+  c_int_lt_lit1(0xfe);
+
+  int0 = 1;
+  c_int_lt_lit1(0xfc);
+
+  int0 = 2;
+  c_int_lt_lit1(0xfc);
+
+  int0 = 0xfe;
+  c_int_lt_lit1(0xfc);
+
+  int0 = 0xff;
+  c_int_lt_lit1(0xf8);
+
+  int0 = 0x100;
+  c_int_lt_lit1(0xf0);
+
+  int0 = 0x101;
+  c_int_lt_lit1(0xe0);
+
+  int0 = 0x1fe;
+  c_int_lt_lit1(0xe0);
+
+  int0 = 0x1ff;
+  c_int_lt_lit1(0xc0);
+
+  int0 = 0x200;
+  c_int_lt_lit1(0x80);
+
+  int0 = 0x201;
+  c_int_lt_lit1(0x0);
+
+  int0 = 0x7f00;
+  c_int_lt_lit1(0x0);
+
+  /* now check contiguous ranges */
+
+  for(int0 = -0x7fff; int0 != -1; int0++)
+    c_int_lt_lit1(0xff);
+
+  for(int0 = 1; int0 != 0xff; int0++)
+    c_int_lt_lit1(0xfc);
+
+  for(int0 = 0x201; int0 != 0x7fff; int0++)
+    c_int_lt_lit1(0);
+}
+
+
+
+void c_int_lt_lit2(unsigned char expected_result)
+{
+  result = 0;
+
+  if(int0 < -0x7fff)
+    result |= 1;
+
+  if(int0 < -0x7f00)
+    result |= 2;
+
+  if(int0 < -0x7eff)
+    result |= 4;
+
+  if(int0 < -0x7e00)
+    result |= 8;
+
+  if(int0 < -0x0101)
+    result |= 0x10;
+  
+  if(int0 < -0x0100)
+    result |= 0x20;
+  
+  if(int0 < -0xff)
+    result |= 0x40;
+
+  if(int0 < -1)
+    result |= 0x80;
+
+  if(result != expected_result)
+    failures=1;
+}
+
+void int_compare2(void)
+{
+  int0 = -0x7fff;
+  c_int_lt_lit2(0xfe);
+
+  int0 = -0x7f00;
+  c_int_lt_lit2(0xfc);
+
+  int0 = -0x7eff;
+  c_int_lt_lit2(0xf8);
+
+  int0 = -0x7e00;
+  c_int_lt_lit2(0xf0);
+
+  int0 = -0x4567;
+  c_int_lt_lit2(0xf0);
+
+  int0 = -0x200;
+  c_int_lt_lit2(0xf0);
+
+  int0 = -0x102;
+  c_int_lt_lit2(0xf0);
+
+  int0 = -0x101;
+  c_int_lt_lit2(0xe0);
+
+  int0 = -0x100;
+  c_int_lt_lit2(0xc0);
+
+  int0 = -0xff;
+  c_int_lt_lit2(0x80);
+
+  int0 = -0x02;
+  c_int_lt_lit2(0x80);
+
+  int0 = -0x01;
+  c_int_lt_lit2(0x00);
+
+  int0 = 0;
+  c_int_lt_lit2(0x00);
+
+  int0 = 1;
+  c_int_lt_lit2(0x00);
+
+  int0 = 0x7fff;
+  c_int_lt_lit2(0x00);
+
+  /* now check contiguous ranges */
+  int0 = -0x7f01;
+  c_int_lt_lit2(0xfe);
+
+  for(int0 = -0x7ffe; int0 != -0x7f01; int0++)
+    c_int_lt_lit2(0xfe);
+
+  for(int0 = -0x7e00; int0 != -0x101; int0++)
+    c_int_lt_lit2(0xf0);
+
+  for(int0 = -1; int0 != 0x7fff; int0++)
+    c_int_lt_lit2(0);
+}
+
+
+void
+main (void)
+{
+  char_compare();
+  int_compare1();
+  int_compare2();
+
+  success = failures;
+  done ();
+}
diff --git a/src/regression/compare8.c b/src/regression/compare8.c
new file mode 100644 (file)
index 0000000..eab3ffd
--- /dev/null
@@ -0,0 +1,311 @@
+// Signed comparisons of the form:  (variable>LIT)
+//
+// This regression test exercises all of the boundary
+// conditions in literal less than comparisons. There
+// are numerous opportunities to optimize these comparison
+// and each one has an astonishing capability of failing
+// a boundary condition.
+
+unsigned char success = 0;
+unsigned char failures = 0;
+unsigned char dummy = 0;
+unsigned char result = 0;
+
+//bit bit0 = 0;
+long int0 = 0;
+long int1 = 0;
+unsigned char uchar0 = 0;
+unsigned char uchar1 = 0;
+signed char char0 = 0;
+signed char char1 = 0;
+char long0 = 0;
+char long1 = 0;
+
+void
+done ()
+{
+  dummy++;
+}
+
+
+void c_char_gt_lit1(unsigned char expected_result)
+{
+  result = 0;
+
+  if(char0 > -0x7f)
+    result |= 1;
+
+
+  if(char0 > -1)
+    result |= 2;
+
+  if(char0 > 0)
+    result |= 4;
+
+  if(char0 > 1)
+    result |= 8;
+
+  if(char0 > 0x7e)
+    result |= 0x10;
+  
+  if(char0 > 0x7f)
+    result |= 0x20;
+  
+  if(result != expected_result)
+    failures++;
+}
+
+
+void char_compare(void)
+{
+  char0 = 0x7f;
+  c_char_gt_lit1(0x1f);
+
+  char0 = 0x7e;
+  c_char_gt_lit1(0x0f);
+
+  char0 = 0x40;
+  c_char_gt_lit1(0x0f);
+
+  char0 = 0x2;
+  c_char_gt_lit1(0x0f);
+
+  char0 = 0x1;
+  c_char_gt_lit1(0x07);
+
+  char0 = 0;
+  c_char_gt_lit1(0x03);
+
+  char0 = -1;
+  c_char_gt_lit1(0x01);
+
+  char0 = -2;
+  c_char_gt_lit1(0x01);
+
+  char0 = -0x40;
+  c_char_gt_lit1(0x01);
+
+  char0 = -0x7e;
+  c_char_gt_lit1(0x01);
+
+  char0 = -0x7f;
+  c_char_gt_lit1(0x00);
+
+  char0 = 0x80;
+  c_char_gt_lit1(0x00);
+
+
+  /* Now test entire range */
+
+  for(char0=2; char0 != 0x7f; char0++)
+    c_char_gt_lit1(0x0f);
+
+
+  for(char0=-0x7e; char0 != -1; char0++)
+    c_char_gt_lit1(0x01);
+
+
+}
+
+
+void c_int_gt_lit1(unsigned char expected_result)
+{
+  result = 0;
+
+  if(int0 > 0)
+    result |= 1;
+
+  if(int0 > 1)
+    result |= 2;
+
+
+  if(int0 > 0xff)
+    result |= 4;
+
+  if(int0 > 0x100)
+    result |= 8;
+
+  if(int0 > 0x0101)
+    result |= 0x10;
+  
+  if(int0 > 0x01ff)
+    result |= 0x20;
+  
+  if(int0 > 0x0200)
+    result |= 0x40;
+
+  if(int0 > 0x0201)
+    result |= 0x80;
+
+  if(result != expected_result)
+    failures=1;
+
+}
+
+
+void int_compare1(void)
+{
+  int0 = -1;
+  c_int_gt_lit1(0x00);
+
+  int0 = 0;
+  c_int_gt_lit1(0x00);
+
+  int0 = 1;
+  c_int_gt_lit1(0x01);
+
+  int0 = 2;
+  c_int_gt_lit1(0x03);
+
+  int0 = 0xfe;
+  c_int_gt_lit1(0x03);
+
+  int0 = 0xff;
+  c_int_gt_lit1(0x03);
+
+  int0 = 0x100;
+  c_int_gt_lit1(0x07);
+
+  int0 = 0x101;
+  c_int_gt_lit1(0x0f);
+
+  int0 = 0x102;
+  c_int_gt_lit1(0x1f);
+
+  int0 = 0x1fe;
+  c_int_gt_lit1(0x1f);
+
+  int0 = 0x1ff;
+  c_int_gt_lit1(0x1f);
+
+  int0 = 0x200;
+  c_int_gt_lit1(0x3f);
+
+  int0 = 0x201;
+  c_int_gt_lit1(0x7f);
+
+  int0 = 0x7f00;
+  c_int_gt_lit1(0xff);
+
+  /* now check contiguous ranges */
+
+  for(int0 = -0x7fff; int0 != -1; int0++)
+    c_int_gt_lit1(0x00);
+
+  for(int0 = 2; int0 != 0xff; int0++)
+    c_int_gt_lit1(0x03);
+
+  for(int0 = 0x202; int0 != 0x7fff; int0++)
+    c_int_gt_lit1(0xff);
+
+}
+
+
+void c_int_gt_lit2(unsigned char expected_result)
+{
+  result = 0;
+
+  if(int0 > -0x7fff)
+    result |= 1;
+
+  if(int0 > -0x7f00)
+    result |= 2;
+
+  if(int0 > -0x7eff)
+    result |= 4;
+
+  if(int0 > -0x7e00)
+    result |= 8;
+
+  if(int0 > -0x0101)
+    result |= 0x10;
+  
+  if(int0 > -0x0100)
+    result |= 0x20;
+  
+  if(int0 > -0xff)
+    result |= 0x40;
+
+  if(int0 > -1)
+    result |= 0x80;
+
+  if(result != expected_result)
+    failures=1;
+}
+
+void int_compare2(void)
+{
+  int0 = -0x7fff;
+  c_int_gt_lit2(0x00);
+
+  int0 = -0x7f00;
+  c_int_gt_lit2(0x01);
+
+  int0 = -0x7eff;
+  c_int_gt_lit2(0x03);
+
+  int0 = -0x7e00;
+  c_int_gt_lit2(0x07);
+
+  int0 = -0x7dff;
+  c_int_gt_lit2(0x0f);
+
+  int0 = -0x4567;
+  c_int_gt_lit2(0x0f);
+
+  int0 = -0x200;
+  c_int_gt_lit2(0x0f);
+
+  int0 = -0x102;
+  c_int_gt_lit2(0x0f);
+
+  int0 = -0x101;
+  c_int_gt_lit2(0x0f);
+
+  int0 = -0x100;
+  c_int_gt_lit2(0x1f);
+
+  int0 = -0xff;
+  c_int_gt_lit2(0x3f);
+
+  int0 = -0x02;
+  c_int_gt_lit2(0x7f);
+
+  int0 = -0x01;
+  c_int_gt_lit2(0x7f);
+
+  int0 = 0;
+  c_int_gt_lit2(0xff);
+
+  int0 = 1;
+  c_int_gt_lit2(0xff);
+
+  int0 = 0x7fff;
+  c_int_gt_lit2(0xff);
+
+  /* now check contiguous ranges */
+
+  for(int0 = -0x7ffe; int0 != -0x7f01; int0++)
+    c_int_gt_lit2(0x01);
+
+  for(int0 = -0x7dff; int0 != -0x101; int0++)
+    c_int_gt_lit2(0x0f);
+
+  for(int0 = 0; int0 != 0x7fff; int0++)
+    c_int_gt_lit2(0xff);
+
+}
+
+
+
+
+void
+main (void)
+{
+  char_compare();
+  int_compare1();
+  int_compare2();
+
+  success = failures;
+  done ();
+}