]> git.gag.com Git - fw/sdcc/commitdiff
* Now can use acc for short lived varibles.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 13 Feb 2000 01:12:59 +0000 (01:12 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 13 Feb 2000 01:12:59 +0000 (01:12 +0000)
* Added a few peephole rules
* At 98 d/s - so close to 100... :)

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@103 4a8a32a2-be11-0410-ad9d-d568d2c75423

device/lib/z80/Makefile
device/lib/z80/string.c
src/z80/Makefile
src/z80/gen.c
src/z80/peeph.def
src/z80/ralloc.c

index 0ecb909eaca5672078373eede043574a48b59bf8..e70eee3872ffc2c6af31d7a9b7eea3867c7270ee 100644 (file)
@@ -5,7 +5,7 @@ TOPDIR = ../../..
 SCC = $(TOPDIR)/bin/sdcc -mz80 -v
 SAS = as-z80
 
-OBJ = div.o mul.o putchar.o string.o printf.o asm_strings.o
+OBJ = div.o mul.o putchar.o string.o printf.o asm_strings.o
 LIB = z80.lib
 CC = $(SCC)
 AS = $(SAS)
index 0ba6f75364801069990df762be39b7900e2d1889..53ee9b2c10f765b97f03c26af741ec0be064f647 100644 (file)
@@ -1,7 +1,7 @@
 /* Dumb strings stub.
    Wanted a quick hack for now - will use the libc version later.
 */
-char *_strcpy(char *dest, const char *source)
+char *strcpy(char *dest, const char *source)
 {
     char *d = dest;
     const char *s = source;
@@ -9,7 +9,7 @@ char *_strcpy(char *dest, const char *source)
     return dest;
 }
 
-void *_memcpy(void *dest, const void *source, int count)
+void *memcpy(void *dest, const void *source, int count)
 {
     char *d = dest;
     const char *s = source;
@@ -19,7 +19,7 @@ void *_memcpy(void *dest, const void *source, int count)
     return dest;
 }
 
-int _strcmp(const char *s1, const char *s2)
+int strcmp(const char *s1, const char *s2)
 {
     char ret = 0;
 
index a248555c8f80fa13bd9f8d17ba25d2f9d7327e46..2f6ef6e31d8491b41d05824fd21a158cb167e2f4 100644 (file)
@@ -18,4 +18,6 @@ $(LIB): peeph.rul $(OBJ)
 peeph.rul: peeph.def
        $(AWK) -f ../SDCCpeeph.awk peeph.def > peeph.rul
 
+main.o: main.c peeph.rul
+
 include clean.mk
index 926012163818ee1d4d6b83e7b233a5c584f415f0..50154dd37d24a95040269d4bbeb7db19265efc1c 100644 (file)
@@ -859,8 +859,10 @@ void toBoolean(operand *oper)
            emitcode("or","a,%s",aopGet(AOP(oper),offset++,FALSE));
     }
     else {
-       CLRC;
-       emitcode("or","a,%s",aopGet(AOP(oper),0,FALSE));
+       if (AOP(oper)->type != AOP_ACC) {
+           CLRC;
+           emitcode("or","a,%s",aopGet(AOP(oper),0,FALSE));
+       }
     }
 }
 
@@ -1407,7 +1409,7 @@ static bool genPlusIncr (iCode *ic)
     if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
        isPair(AOP(IC_RESULT(ic)))) {
        while (icount--) {
-           emitcode("inc", "%s ; 1", getPairName(AOP(IC_RESULT(ic))));
+           emitcode("inc", "%s", getPairName(AOP(IC_RESULT(ic))));
        }
        return TRUE;
     }
@@ -1596,6 +1598,25 @@ static bool genMinusDec (iCode *ic)
         return FALSE;
 
     size = getDataSize(IC_RESULT(ic));
+
+#if 0
+    /* if increment 16 bits in register */
+    if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
+        (size > 1) &&
+        (icount == 1)) {
+        symbol *tlbl = newiTempLabel(NULL);
+       emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE));
+       emitcode("jp", "np," LABEL_STR ,tlbl->key+100);
+    
+       emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE));
+       if(size == 4) {
+           assert(0);
+       }
+       emitcode("", LABEL_STR ":",tlbl->key+100);
+        return TRUE;
+    }
+#endif
+
     /* if decrement 16 bits in register */
     if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
         (size > 1) && isPair(AOP(IC_RESULT(ic)))) {
@@ -1804,7 +1825,7 @@ static void genCmp (operand *left,operand *right,
                emitcode("cp", "%s^0x80", aopGet(AOP(right), offset, FALSE));
            }
            else 
-               emitcode("cp", "%s", aopGet(AOP(right), offset, FALSE));
+               emitcode("cp", "%s ; 7", aopGet(AOP(right), offset, FALSE));
         } 
        else {
             if(AOP_TYPE(right) == AOP_LIT) {
@@ -1972,8 +1993,11 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl)
     if (AOP_TYPE(right) == AOP_LIT &&
         AOP_TYPE(left) != AOP_DIR ) {
         while (size--) {
-           emitcode("ld", "a,%s", aopGet(AOP(left),offset,FALSE));
-           emitcode("cp", "a,%s", aopGet(AOP(right),offset,FALSE));
+           emitcode("ld", "a,%s ; 2", aopGet(AOP(left),offset,FALSE));
+           if ((AOP_TYPE(right) == AOP_LIT) && lit == 0)
+               emitcode("or", "a,a");
+           else 
+               emitcode("cp", "a,%s", aopGet(AOP(right),offset,FALSE));
             emitcode("jp", "nz," LABEL_STR , lbl->key+100);
             offset++;
         }
@@ -1990,7 +2014,7 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl)
                /* PENDING */
                 emitcode("jp","nz," LABEL_STR ,lbl->key+100);
             else {
-               emitcode("cp", "%s", aopGet(AOP(right),offset,FALSE));
+               emitcode("cp", "%s ; 4", aopGet(AOP(right),offset,FALSE));
                emitcode("jp", "nz," LABEL_STR , lbl->key+100);
            }
             offset++;
@@ -2001,7 +2025,7 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl)
         while(size--) {
             char *l = aopGet(AOP(left),offset,FALSE);
             MOVA(aopGet(AOP(right),offset,FALSE));
-           emitcode("cp", "%s", l);
+           emitcode("cp", "%s ; 5", l);
            emitcode("jr", "nz," LABEL_STR, lbl->key+100);
             offset++;
         }
index 9fd073d688f13fdb31038f39d1442acba74e4943..63f57e357cd76a1e34285e8cab01aff747d8d40c 100644 (file)
@@ -3,3 +3,62 @@ replace restart {
 } by {
        ; Removed redundent load
 }
+replace restart {
+       xor a,a
+       or a,%1
+       or a,a
+       jp %2,%3
+} by {
+       ; Removed redundent or a,a
+       xor     a,a
+       or      a,%1
+       jp      %2,%3
+}
+replace restart {
+       cp a,#0x00
+       jp nz,%1
+} by {
+       ; Rule 3
+       or      a,a
+       jp      nz,%1
+}
+replace restart {
+       jp nz,%1
+       jp      %2
+%1:
+       jp      %3
+%2:
+} by {
+       ; Rule 4
+       jp      z,%2
+%1:
+       jp      %3
+%2:
+}
+replace restart {
+       jp      nz,%1
+       jp      %2
+%1:
+} by {
+       ; Rule 5
+       jp      z,%2
+%1:
+}
+replace restart {
+       jp      z,%1
+       jp      %2
+%1:
+} by {
+       ; Rule 6
+       jp      nz,%2
+%1:
+}
+replace restart {
+%1:
+       jp      %2
+       jp      %3
+} by {
+       ; Weird Rule 7
+%1:
+       jp      %2
+}
index dd75f56be86a6589dad090efcbd84e6bec05ce14..1e651850cf0cd6a62d0b81e40e026dfbf5b42e86 100644 (file)
@@ -1755,6 +1755,216 @@ static void packRegsForAccUse (iCode *ic)
     OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
 }
 
+bool opPreservesA(iCode *ic, iCode *uic)
+{
+    /* if the usage has only one operand then we can */
+    if (IC_LEFT(ic) == NULL ||
+       IC_RIGHT(ic) == NULL) 
+       return TRUE;
+
+    if (uic->op != '=' && 
+       !IS_ARITHMETIC_OP(uic) &&
+       !IS_BITWISE_OP(uic)    &&
+       uic->op != EQ_OP &&
+       uic->op != LEFT_OP &&
+       uic->op != RIGHT_OP ) {
+       return FALSE;
+    }
+
+    /* PENDING */
+    if (!IC_LEFT(uic) || !IC_RESULT(ic))
+       return FALSE;
+
+    /** This is confusing :)  Guess for now */
+    if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
+       (IS_ITEMP(IC_RIGHT(uic)) ||
+        (IS_TRUE_SYMOP(IC_RIGHT(uic)))))
+       return TRUE;
+    
+    if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
+       (IS_ITEMP(IC_LEFT(uic)) ||
+        (IS_TRUE_SYMOP(IC_LEFT(uic)))))
+       return TRUE;
+
+    return FALSE;
+}
+
+/** Pack registers for acc use.
+    When the result of this operation is small and short lived it may
+    be able to be stored in the accumelator.
+ */
+static void packRegsForAccUse2(iCode *ic)
+{
+    iCode *uic;
+    
+    /* if + or - then it has to be one byte result.
+       MLH: Ok.
+     */
+    if ((ic->op == '+' || ic->op == '-')
+       && getSize(operandType(IC_RESULT(ic))) > 1)
+       return ;
+    
+    /* if shift operation make sure right side is not a literal.
+       MLH: depends.
+     */
+#if 0
+    if (ic->op == RIGHT_OP  &&
+       (isOperandLiteral(IC_RIGHT(ic)) ||
+         getSize(operandType(IC_RESULT(ic))) > 1))
+       return ;
+       
+    if (ic->op == LEFT_OP &&        
+       ( isOperandLiteral(IC_RIGHT(ic)) ||
+         getSize(operandType(IC_RESULT(ic))) > 1))
+       return ;
+#endif
+       
+    /* has only one definition */
+    if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1) {
+       return;
+    }
+
+    /* Right.  We may be able to propagate it through if:
+       For each in the chain of uses the intermediate is OK.
+    */
+    /* Get next with 'uses result' bit on
+       If this->next == next
+         Validate use of next
+        If OK, increase count
+    */
+    /* and the usage immediately follows this iCode */
+    if (!(uic = hTabItemWithKey(iCodehTab,
+                               bitVectFirstBit(OP_USES(IC_RESULT(ic)))))) {
+       return;
+    }
+
+    {
+       /* Create a copy of the OP_USES bit vect */
+       bitVect *uses = bitVectCopy(OP_USES(IC_RESULT(ic)));
+       int setBit;
+       iCode *scan = ic, *next;
+
+       do {
+           setBit = bitVectFirstBit(uses);
+           next = hTabItemWithKey(iCodehTab, setBit);
+           if (scan->next == next) {
+               bitVectUnSetBit(uses, setBit);
+               /* Still contigous. */
+               if (!opPreservesA(ic, next)) {
+                   return;
+               }
+               scan = next;
+           }
+           else {
+               return;
+           }
+       } while (!bitVectIsZero(uses));
+       OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
+       return;
+    }
+
+    /* OLD CODE FOLLOWS */
+    /* if it is a conditional branch then we definitely can
+       MLH: Depends.
+     */
+#if 0    
+    if (uic->op == IFX ) 
+       goto accuse;
+
+    /* MLH: Depends. */
+    if ( uic->op == JUMPTABLE )
+       return ;
+#endif
+
+    /* if the usage is not is an assignment or an 
+       arithmetic / bitwise / shift operation then not.
+       MLH: Pending:  Invalid.  Our pointer sets are always peechy.
+ */
+#if 0
+    if (POINTER_SET(uic) && 
+       getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1) {
+       printf("e5 %u\n", getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)));
+       return;
+    }
+#endif
+
+    printf("1\n");
+    if (uic->op != '=' && 
+       !IS_ARITHMETIC_OP(uic) &&
+       !IS_BITWISE_OP(uic)    &&
+       uic->op != LEFT_OP &&
+       uic->op != RIGHT_OP ) {
+       printf("e6\n");
+       return;
+    }
+
+    /* if used in ^ operation then make sure right is not a 
+       literl */
+    if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
+       return ;
+
+    /* if shift operation make sure right side is not a literal */
+    if (uic->op == RIGHT_OP  &&
+       ( isOperandLiteral(IC_RIGHT(uic)) ||
+         getSize(operandType(IC_RESULT(uic))) > 1))
+       return ;
+
+    if (uic->op == LEFT_OP &&        
+       ( isOperandLiteral(IC_RIGHT(uic)) ||
+         getSize(operandType(IC_RESULT(uic))) > 1))
+       return ;
+           
+#if 0
+    /* make sure that the result of this icode is not on the
+       stack, since acc is used to compute stack offset */
+    if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
+       OP_SYMBOL(IC_RESULT(uic))->onStack)
+       return ;
+#endif
+
+#if 0
+    /* if either one of them in far space then we cannot */
+    if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
+        isOperandInFarSpace(IC_LEFT(uic))) ||
+       (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
+        isOperandInFarSpace(IC_RIGHT(uic))))
+       return ;
+#endif
+
+    /* if the usage has only one operand then we can */
+    if (IC_LEFT(uic) == NULL ||
+       IC_RIGHT(uic) == NULL) 
+       goto accuse;
+
+    /* make sure this is on the left side if not
+       a '+' since '+' is commutative */
+    if (ic->op != '+' &&
+       IC_LEFT(uic)->key != IC_RESULT(ic)->key)
+       return;
+
+    /* if one of them is a literal then we can */
+    if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
+       (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
+       OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
+       return ;
+    }
+
+    /** This is confusing :)  Guess for now */
+    if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
+       (IS_ITEMP(IC_RIGHT(uic)) ||
+        (IS_TRUE_SYMOP(IC_RIGHT(uic)))))
+       goto accuse;
+    
+    if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
+       (IS_ITEMP(IC_LEFT(uic)) ||
+        (IS_TRUE_SYMOP(IC_LEFT(uic)))))
+       goto accuse ;
+    return ;
+ accuse:
+    printf("acc ok!\n");
+    OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
+}
+
 /** Does some transformations to reduce register pressure.
  */
 static void packRegisters (eBBlock *ebp)
@@ -1863,6 +2073,7 @@ static void packRegisters (eBBlock *ebp)
           only one operand or has two operands but one is literal & the
           result of that operation is not on stack then we can leave the
           result of this operation in acc:b combination */
+#if 0
        if ((IS_ARITHMETIC_OP(ic) 
             || IS_BITWISE_OP(ic)
             || ic->op == LEFT_OP || ic->op == RIGHT_OP
@@ -1870,6 +2081,17 @@ static void packRegisters (eBBlock *ebp)
            IS_ITEMP(IC_RESULT(ic)) &&
            getSize(operandType(IC_RESULT(ic))) <= 2)
            packRegsForAccUse (ic);
+#else
+       if ((POINTER_GET(ic) ||
+            IS_ARITHMETIC_OP(ic) ||
+            IS_BITWISE_OP(ic) ||
+            ic->op == LEFT_OP ||
+            ic->op == RIGHT_OP
+            ) &&
+           IS_ITEMP(IC_RESULT(ic)) &&
+           getSize(operandType(IC_RESULT(ic))) == 1)
+           packRegsForAccUse2(ic);
+#endif
     }
 }