]> git.sur5r.net Git - cc65/commitdiff
Working on the optimizations
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 21 Oct 2001 13:53:20 +0000 (13:53 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 21 Oct 2001 13:53:20 +0000 (13:53 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1069 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
src/cc65/codegen.c
src/cc65/codeinfo.c
src/cc65/codeopt.c
src/cc65/coptadd.c
src/cc65/coptcmp.c
src/cc65/coptind.c
src/cc65/coptneg.c
src/cc65/coptpush.c [new file with mode: 0644]
src/cc65/coptpush.h [new file with mode: 0644]
src/cc65/coptsub.c
src/cc65/make/gcc.mak
src/cc65/make/watcom.mak

index 2b61e7a2acaba3fbf65c5c87f5ea795b52b86d45..9627f39cd14377acc9d68159e5086ccc8118772b 100644 (file)
@@ -742,16 +742,8 @@ void g_getlocal (unsigned flags, int offs)
                AddCodeLine ("dey");
                AddCodeLine ("ora (sp),y");
            } else {
-               if (CodeSizeFactor > 180) {
-                   ldyconst (offs + 1);
-                   AddCodeLine ("lda (sp),y");
-                   AddCodeLine ("tax");
-                   AddCodeLine ("dey");
-                   AddCodeLine ("lda (sp),y");
-               } else {
-                   ldyconst (offs+1);
-                   AddCodeLine ("jsr ldaxysp");
-               }
+               ldyconst (offs+1);
+               AddCodeLine ("jsr ldaxysp");
            }
            break;
 
index 896baaf2112bb3ee46e057ff09095e335b01fb1e..179d6c757cf1561e45334448dcd22e6a042ae8c9 100644 (file)
@@ -120,7 +120,7 @@ static const FuncInfo FuncInfoTable[] = {
     { "ldax0sp",               REG_Y,                REG_AX                         },
     { "ldaxi",          REG_AX,               REG_AXY | REG_PTR1            },
     { "ldaxidx",        REG_AXY,              REG_AXY | REG_PTR1                    },
-    { "ldaxysp",               REG_Y,                REG_AX                         },
+    { "ldaxysp",               REG_Y,                REG_AXY                        },
     { "leaasp",         REG_A,                REG_AX                        },
     { "negax",          REG_AX,               REG_AX                        },
     { "pusha",                 REG_A,                REG_Y                          },
index 4797e8b518668079942a3e13b94182a977a8a7de..739644bd9c21e24170bd693dc52ee1448e543006 100644 (file)
@@ -52,6 +52,7 @@
 #include "coptcmp.h"
 #include "coptind.h"
 #include "coptneg.h"
+#include "coptpush.h"
 #include "coptstop.h"
 #include "coptsub.h"
 #include "copttest.h"
@@ -1352,8 +1353,8 @@ struct OptFunc {
 
 /* A list of all the function descriptions */
 static OptFunc DOpt65C02Ind            = { Opt65C02Ind,     "Opt65C02Ind",     100, 0, 0, 0, 0, 0 };
-static OptFunc DOptAdd1                = { OptAdd1,         "OptAdd1",         100, 0, 0, 0, 0, 0 };
-static OptFunc DOptAdd2                = { OptAdd2,         "OptAdd2",         100, 0, 0, 0, 0, 0 };
+static OptFunc DOptAdd1                = { OptAdd1,         "OptAdd1",          60, 0, 0, 0, 0, 0 };
+static OptFunc DOptAdd2                = { OptAdd2,         "OptAdd2",         200, 0, 0, 0, 0, 0 };
 static OptFunc DOptAdd3                = { OptAdd3,         "OptAdd3",         100, 0, 0, 0, 0, 0 };
 static OptFunc DOptBoolTrans    = { OptBoolTrans,    "OptBoolTrans",    100, 0, 0, 0, 0, 0 };
 static OptFunc DOptBranchDist          = { OptBranchDist,   "OptBranchDist",   100, 0, 0, 0, 0, 0 };
@@ -1388,6 +1389,7 @@ static OptFunc DOptPtrLoad5       = { OptPtrLoad5,     "OptPtrLoad5",     100, 0,
 static OptFunc DOptPtrLoad6            = { OptPtrLoad6,     "OptPtrLoad6",     100, 0, 0, 0, 0, 0 };
 static OptFunc DOptPtrStore1           = { OptPtrStore1,    "OptPtrStore1",    100, 0, 0, 0, 0, 0 };
 static OptFunc DOptPtrStore2           = { OptPtrStore2,    "OptPtrStore2",    100, 0, 0, 0, 0, 0 };
+static OptFunc DOptPush1               = { OptPush1,        "OptPush1",         65, 0, 0, 0, 0, 0 };
 static OptFunc DOptShift1              = { OptShift1,       "OptShift1",       100, 0, 0, 0, 0, 0 };
 static OptFunc DOptShift2              = { OptShift2,       "OptShift2",       100, 0, 0, 0, 0, 0 };
 /*static OptFunc DOptSize1        = { OptSize1,        "OptSize1",        100, 0, 0, 0, 0, 0 };*/
@@ -1438,6 +1440,7 @@ static OptFunc* OptFuncs[] = {
     &DOptPtrLoad6,
     &DOptPtrStore1,
     &DOptPtrStore2,
+    &DOptPush1,
     &DOptRTS,
     &DOptRTSJumps1,
     &DOptRTSJumps2,
@@ -1584,7 +1587,7 @@ static void ReadOptStats (const char* Name)
 
        /* Parse the line */
                if (sscanf (B, "%31s %lu %*u %lu %*u", Name, &TotalRuns, &TotalChanges) != 3) {
-           /* Syntax error */
+           /* Syntax error */
            continue;
        }
 
@@ -1626,7 +1629,7 @@ static void WriteOptStats (const char* Name)
                         "%-20s %6lu %6lu %6lu %6lu\n",
                 O->Name,
                 O->TotalRuns,
-                O->LastRuns,
+                O->LastRuns,
                 O->TotalChanges,
                 O->LastChanges);
     }
@@ -1642,7 +1645,7 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max)
 {
     unsigned Changes, C;
 
-    /* Don't run the function if it is disabled or if it is prohibited by the 
+    /* Don't run the function if it is disabled or if it is prohibited by the
      * code size factor
      */
     if (F->Disabled || CodeSizeFactor < F->CodeSizeFactor) {
@@ -1671,131 +1674,174 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max)
 
 
 
-static void RunOptGroup1 (CodeSeg* S)
+static unsigned RunOptGroup1 (CodeSeg* S)
 /* Run the first group of optimization steps. These steps translate known
  * patterns emitted by the code generator into more optimal patterns. Order
  * of the steps is important, because some of the steps done earlier cover
  * the same patterns as later steps as subpatterns.
  */
 {
-    RunOptFunc (S, &DOptPtrStore1, 1);
-    RunOptFunc (S, &DOptPtrStore2, 1);
-    RunOptFunc (S, &DOptPtrLoad1, 1);
-    RunOptFunc (S, &DOptPtrLoad2, 1);
-    RunOptFunc (S, &DOptPtrLoad3, 1);
-    RunOptFunc (S, &DOptPtrLoad4, 1);
-    RunOptFunc (S, &DOptPtrLoad5, 1);
-    RunOptFunc (S, &DOptNegAX1, 1);
-    RunOptFunc (S, &DOptNegAX2, 1);
-    RunOptFunc (S, &DOptNegAX3, 1);
-    RunOptFunc (S, &DOptNegAX4, 1);
-    RunOptFunc (S, &DOptAdd1, 1);
-    RunOptFunc (S, &DOptAdd2, 1);
-    RunOptFunc (S, &DOptShift1, 1);
-    RunOptFunc (S, &DOptShift2, 1);
+    unsigned Changes = 0;
+
+    Changes += RunOptFunc (S, &DOptPtrStore1, 1);
+    Changes += RunOptFunc (S, &DOptPtrStore2, 1);
+    Changes += RunOptFunc (S, &DOptPtrLoad1, 1);
+    Changes += RunOptFunc (S, &DOptPtrLoad2, 1);
+    Changes += RunOptFunc (S, &DOptPtrLoad3, 1);
+    Changes += RunOptFunc (S, &DOptPtrLoad4, 1);
+    Changes += RunOptFunc (S, &DOptPtrLoad5, 1);
+    Changes += RunOptFunc (S, &DOptNegAX1, 1);
+    Changes += RunOptFunc (S, &DOptNegAX2, 1);
+    Changes += RunOptFunc (S, &DOptNegAX3, 1);
+    Changes += RunOptFunc (S, &DOptNegAX4, 1);
+    Changes += RunOptFunc (S, &DOptAdd1, 1);
+    Changes += RunOptFunc (S, &DOptAdd2, 1);
+    Changes += RunOptFunc (S, &DOptShift1, 1);
+    Changes += RunOptFunc (S, &DOptShift2, 1);
+
+    /* Return the number of changes */
+    return Changes;
 }
 
 
 
-static void RunOptGroup2 (CodeSeg* S)
+static unsigned RunOptGroup2 (CodeSeg* S)
 /* Run one group of optimization steps. This step involves just decoupling
  * instructions by replacing them by instructions that do not depend on
  * previous instructions. This makes it easier to find instructions that
  * aren't used.
  */
 {
-    RunOptFunc (S, &DOptDecouple, 1);
-}
+    unsigned Changes = 0;
+
+    Changes += RunOptFunc (S, &DOptDecouple, 1);
 
+    /* Return the number of changes */
+    return Changes;
+}
 
 
 
-static void RunOptGroup3 (CodeSeg* S)
+static unsigned RunOptGroup3 (CodeSeg* S)
 /* Run one group of optimization steps. These steps depend on each other,
  * that means that one step may allow another step to do additional work,
  * so we will repeat the steps as long as we see any changes.
  */
 {
-    unsigned Changes;
+    unsigned Changes, C;
 
+    Changes = 0;
     do {
-       Changes = 0;
-
-       Changes += RunOptFunc (S, &DOptPtrLoad6, 1);
-               Changes += RunOptFunc (S, &DOptNegA1, 1);
-               Changes += RunOptFunc (S, &DOptNegA2, 1);
-               Changes += RunOptFunc (S, &DOptSub1, 1);
-               Changes += RunOptFunc (S, &DOptSub2, 1);
-               Changes += RunOptFunc (S, &DOptAdd3, 1);
-       Changes += RunOptFunc (S, &DOptStackOps, 1);
-               Changes += RunOptFunc (S, &DOptJumpCascades, 1);
-               Changes += RunOptFunc (S, &DOptDeadJumps, 1);
-               Changes += RunOptFunc (S, &DOptRTS, 1);
-               Changes += RunOptFunc (S, &DOptDeadCode, 1);
-               Changes += RunOptFunc (S, &DOptJumpTarget, 1);
-       Changes += RunOptFunc (S, &DOptCondBranches, 1);
-       Changes += RunOptFunc (S, &DOptRTSJumps1, 1);
-       Changes += RunOptFunc (S, &DOptBoolTrans, 1);
-       Changes += RunOptFunc (S, &DOptCmp1, 1);
-       Changes += RunOptFunc (S, &DOptCmp2, 1);
-       Changes += RunOptFunc (S, &DOptCmp3, 1);
-       Changes += RunOptFunc (S, &DOptCmp4, 1);
-       Changes += RunOptFunc (S, &DOptCmp5, 1);
-       Changes += RunOptFunc (S, &DOptCmp6, 1);
-       Changes += RunOptFunc (S, &DOptCmp7, 1);
-       Changes += RunOptFunc (S, &DOptTest1, 1);
-       Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
-       Changes += RunOptFunc (S, &DOptUnusedStores, 1);
-       Changes += RunOptFunc (S, &DOptDupLoads, 1);
-       Changes += RunOptFunc (S, &DOptStoreLoad, 1);
-       Changes += RunOptFunc (S, &DOptTransfers, 1);
-
-    } while (Changes);
+               C = 0;
+
+               C += RunOptFunc (S, &DOptPtrLoad6, 1);
+               C += RunOptFunc (S, &DOptNegA1, 1);
+               C += RunOptFunc (S, &DOptNegA2, 1);
+               C += RunOptFunc (S, &DOptSub1, 1);
+               C += RunOptFunc (S, &DOptSub2, 1);
+               C += RunOptFunc (S, &DOptAdd3, 1);
+               C += RunOptFunc (S, &DOptStackOps, 1);
+               C += RunOptFunc (S, &DOptJumpCascades, 1);
+               C += RunOptFunc (S, &DOptDeadJumps, 1);
+               C += RunOptFunc (S, &DOptRTS, 1);
+               C += RunOptFunc (S, &DOptDeadCode, 1);
+               C += RunOptFunc (S, &DOptJumpTarget, 1);
+               C += RunOptFunc (S, &DOptCondBranches, 1);
+               C += RunOptFunc (S, &DOptRTSJumps1, 1);
+               C += RunOptFunc (S, &DOptBoolTrans, 1);
+               C += RunOptFunc (S, &DOptCmp1, 1);
+               C += RunOptFunc (S, &DOptCmp2, 1);
+               C += RunOptFunc (S, &DOptCmp3, 1);
+               C += RunOptFunc (S, &DOptCmp4, 1);
+               C += RunOptFunc (S, &DOptCmp5, 1);
+               C += RunOptFunc (S, &DOptCmp6, 1);
+               C += RunOptFunc (S, &DOptCmp7, 1);
+               C += RunOptFunc (S, &DOptTest1, 1);
+               C += RunOptFunc (S, &DOptUnusedLoads, 1);
+               C += RunOptFunc (S, &DOptUnusedStores, 1);
+               C += RunOptFunc (S, &DOptDupLoads, 1);
+               C += RunOptFunc (S, &DOptStoreLoad, 1);
+               C += RunOptFunc (S, &DOptTransfers, 1);
+
+       Changes += C;
+
+    } while (C);
+
+    /* Return the number of changes */
+    return Changes;
 }
 
 
 
-static void RunOptGroup4 (CodeSeg* S)
+static unsigned RunOptGroup4 (CodeSeg* S)
 /* 65C02 specific optimizations. */
 {
-    if (CPU < CPU_65C02) {
-       return;
-    }
+    unsigned Changes = 0;
 
-    /* Replace (zp),y by (zp) if Y is zero. If we have changes, run register
-     * load optimization again, since loads of Y may have become unnecessary.
-     */
-    if (RunOptFunc (S, &DOpt65C02Ind, 1) > 0) {
-       RunOptFunc (S, &DOptUnusedLoads, 1);
+    if (CPU >= CPU_65C02) {
+       /* Replace (zp),y by (zp) if Y is zero. If we have changes, run register
+        * load optimization again, since loads of Y may have become unnecessary.
+        */
+       unsigned C = RunOptFunc (S, &DOpt65C02Ind, 1);
+       Changes += C;
+       if (C) {
+           Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
+       }
     }
+
+    /* Return the number of changes */
+    return Changes;
 }
 
 
 
-static void RunOptGroup5 (CodeSeg* S)
+static unsigned RunOptGroup5 (CodeSeg* S)
+/* Run another round of pattern replacements. These are done late, since there
+ * may be better replacements before.
+ */
+{              
+    unsigned Changes = 0;
+
+    Changes += RunOptFunc (S, &DOptPush1, 1);
+    
+    /* Return the number of changes */
+    return Changes;
+}
+
+
+
+static unsigned RunOptGroup6 (CodeSeg* S)
 /* The last group of optimization steps. Adjust branches, do size optimizations.
  */
 {
+    unsigned Changes = 0;
+    unsigned C;
+
     /* Optimize for size, that is replace operations by shorter ones, even
      * if this does hinder further optimizations (no problem since we're
      * done soon).
      */
-    RunOptFunc (S, &DOptSize2, 1);
+    Changes += RunOptFunc (S, &DOptSize2, 1);
 
     /* Run the jump target optimization again, since the size optimization
      * above may have opened new oportunities.
      */
-    RunOptFunc (S, &DOptJumpTarget, 5);
+    Changes += RunOptFunc (S, &DOptJumpTarget, 5);
 
     /* Adjust branch distances */
-    RunOptFunc (S, &DOptBranchDist, 3);
+    Changes += RunOptFunc (S, &DOptBranchDist, 3);
 
     /* Replace conditional branches to RTS. If we had changes, we must run dead
      * code elimination again, since the change may have introduced dead code.
      */
-    if (RunOptFunc (S, &DOptRTSJumps2, 1)) {
-       RunOptFunc (S, &DOptDeadCode, 1);
+    C = RunOptFunc (S, &DOptRTSJumps2, 1);
+    Changes += C;
+    if (C) {
+       Changes += RunOptFunc (S, &DOptDeadCode, 1);
     }
+
+    /* Return the number of changes */
+    return Changes;
 }
 
 
@@ -1807,7 +1853,7 @@ void RunOpt (CodeSeg* S)
 
     /* If we shouldn't run the optimizer, bail out */
     if (!Optimize) {
-       return;
+       return;
     }
 
     /* Check if we are requested to write optimizer statistics */
@@ -1829,6 +1875,7 @@ void RunOpt (CodeSeg* S)
     RunOptGroup3 (S);
     RunOptGroup4 (S);
     RunOptGroup5 (S);
+    RunOptGroup6 (S);
 
     /* Write statistics */
     if (StatFileName) {
index ebda0fb5db070548b6afb665db15b1c48169e8da..7e9f92d6c9ac14b68c2af040ce8249738f1f3073 100644 (file)
@@ -146,25 +146,22 @@ unsigned OptAdd1 (CodeSeg* S)
 unsigned OptAdd2 (CodeSeg* S)
 /* Search for the sequence
  *
- *             ldy     #yy
- *      lda     (sp),y
- *     tax
- *      ldy     #xx
- *      lda     (sp),y
- *      ldy     #zz
+ *             ldy     #xx
+ *      jsr     ldaxysp
+ *      ldy     #yy
  *      jsr     addeqysp
  *
  * and replace it by:
  *
- *      ldy     #xx
+ *      ldy     #xx-1
  *      lda     (sp),y
- *      ldy     #zz
+ *      ldy     #yy
  *      clc
  *      adc     (sp),y
  *      sta     (sp),y
- *      ldy     #yy
+ *      ldy     #xx
  *      lda     (sp),y
- *      ldy     #zz+1
+ *      ldy     #yy+1
  *      adc     (sp),y
  *      sta     (sp),y
  *
@@ -177,7 +174,7 @@ unsigned OptAdd2 (CodeSeg* S)
     unsigned I = 0;
     while (I < CS_GetEntryCount (S)) {
 
-       CodeEntry* L[7];
+       CodeEntry* L[4];
 
        /* Get next entry */
                L[0] = CS_GetEntry (S, I);
@@ -185,66 +182,66 @@ unsigned OptAdd2 (CodeSeg* S)
        /* Check for the sequence */
        if (L[0]->OPC == OP65_LDY               &&
            CE_KnownImm (L[0])                  &&
-                   CS_GetEntries (S, L+1, I+1, 6)      &&
-           L[1]->OPC == OP65_LDA               &&
-           L[1]->AM == AM65_ZP_INDY            &&
-           !CE_HasLabel (L[1])                 &&
-           L[2]->OPC == OP65_TAX               &&
-           !CE_HasLabel (L[2])                 &&
-           L[3]->OPC == OP65_LDY               &&
-           CE_KnownImm (L[3])                  &&
-                   !CE_HasLabel (L[3])                 &&
-           L[4]->OPC == OP65_LDA               &&
-           L[4]->AM == AM65_ZP_INDY            &&
-           !CE_HasLabel (L[4])                 &&
-           L[5]->OPC == OP65_LDY               &&
-           CE_KnownImm (L[5])                  &&
-           !CE_HasLabel (L[5])                 &&
-           CE_IsCall (L[6], "addeqysp")        &&
-           !CE_HasLabel (L[6])                 &&
-           (GetRegInfo (S, I+7, REG_AX) & REG_AX) == 0) {
+           !CS_RangeHasLabel (S, I+1, 3)       &&
+                   CS_GetEntries (S, L+1, I+1, 3)      &&
+           CE_IsCall (L[1], "ldaxysp")         &&
+                   L[2]->OPC == OP65_LDY               &&
+           CE_KnownImm (L[2])                  &&
+                   CE_IsCall (L[3], "addeqysp")        &&
+                   (GetRegInfo (S, I+4, REG_AX) & REG_AX) == 0) {
 
+           /* Insert new code behind the addeqysp */
            char Buf [20];
            CodeEntry* X;
 
+           /* ldy     #xx-1 */
+           xsprintf (Buf, sizeof (Buf), "$%02X", (int)(L[0]->Num-1));
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+           /* lda     (sp),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+           CS_InsertEntry (S, X, I+5);
 
-           /* Insert new code behind the addeqysp */
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, L[3]->Arg, 0, L[3]->LI);
+           /* ldy     #yy */
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, L[2]->Arg, 0, L[2]->LI);
+           CS_InsertEntry (S, X, I+6);
+
+           /* clc */
+           X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[3]->LI);
            CS_InsertEntry (S, X, I+7);
 
-           X = NewCodeEntry (OP65_LDA, L[4]->AM, L[4]->Arg, 0, L[4]->LI);
+           /* adc     (sp),y */
+                   X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[3]->LI);
            CS_InsertEntry (S, X, I+8);
 
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, L[5]->Arg, 0, L[5]->LI);
+           /* sta     (sp),y */
+           X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[3]->LI);
            CS_InsertEntry (S, X, I+9);
 
-           X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[6]->LI);
+           /* ldy     #xx */
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
            CS_InsertEntry (S, X, I+10);
 
-           X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[6]->LI);
+           /* lda     (sp),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
            CS_InsertEntry (S, X, I+11);
 
-           X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[6]->LI);
+           /* ldy     #yy+1 */
+           xsprintf (Buf, sizeof (Buf), "$%02X", (int)(L[2]->Num+1));
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[2]->LI);
            CS_InsertEntry (S, X, I+12);
 
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
+           /* adc     (sp),y */
+           X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[3]->LI);
            CS_InsertEntry (S, X, I+13);
 
-           X = NewCodeEntry (OP65_LDA, L[1]->AM, L[1]->Arg, 0, L[1]->LI);
+           /* sta     (sp),y */
+           X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[3]->LI);
            CS_InsertEntry (S, X, I+14);
 
-           xsprintf (Buf, sizeof (Buf), "$%02X", (int)(L[5]->Num+1));
-           X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[5]->LI);
-           CS_InsertEntry (S, X, I+15);
-
-           X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[6]->LI);
-           CS_InsertEntry (S, X, I+16);
-
-           X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[6]->LI);
-           CS_InsertEntry (S, X, I+17);
-
            /* Delete the old code */
-           CS_DelEntries (S, I, 7);
+           CS_DelEntries (S, I, 4);
 
            /* Remember, we had changes */
            ++Changes;
index dd24c48c4e55667695e9e3f9da4f2ea1954e19ba..a88e7047d1fdfe58e9e9c96babd797bbbe6c1c3d 100644 (file)
@@ -283,63 +283,6 @@ static int GetCmpRegVal (const CodeEntry* E)
 
 
 
-static int IsCmpToZero (const CodeEntry* E)
-/* Check if the given instrcuction is a compare to zero instruction */
-{
-    return (E->OPC == OP65_CMP            &&
-           E->AM  == AM65_IMM            &&
-           (E->Flags & CEF_NUMARG) != 0  &&
-           E->Num == 0);
-}
-
-
-
-static int IsSpLoad (const CodeEntry* E)
-/* Return true if this is the load of A from the stack */
-{
-    return E->OPC == OP65_LDA && E->AM == AM65_ZP_INDY && strcmp (E->Arg, "sp") == 0;
-}
-
-
-
-static int IsLocalLoad16 (CodeSeg* S, unsigned Index,
-                         CodeEntry** L, unsigned Count)
-/* Check if a 16 bit load of a local variable follows:
- *
- *      ldy     #$xx
- *      lda     (sp),y
- *      tax
- *      dey
- *      lda     (sp),y
- *
- * If so, read Count entries following the first ldy into L and return true
- * if this is possible. Otherwise return false.
- */
-{
-    /* Be sure we read enough entries for the check */
-    CHECK (Count >= 5);
-
-    /* Read the first entry */
-    L[0] = CS_GetEntry (S, Index);
-
-    /* Check for the sequence */
-    return (L[0]->OPC == OP65_LDY                        &&
-           CE_KnownImm (L[0])                           &&
-                   CS_GetEntries (S, L+1, Index+1, Count-1)     &&
-                   IsSpLoad (L[1])                              &&
-           !CE_HasLabel (L[1])                          &&
-           L[2]->OPC == OP65_TAX                        &&
-           !CE_HasLabel (L[2])                          &&
-           L[3]->OPC == OP65_LDY                        &&
-           CE_KnownImm (L[3])                           &&
-           L[3]->Num == L[0]->Num - 1                   &&
-           !CE_HasLabel (L[3])                          &&
-           IsSpLoad (L[4])                              &&
-           !CE_HasLabel (L[4]));
-}
-
-
-
 /*****************************************************************************/
 /*            Remove calls to the bool transformer subroutines              */
 /*****************************************************************************/
@@ -434,13 +377,12 @@ unsigned OptCmp1 (CodeSeg* S)
 
        /* Check for the sequence */
                if (E->OPC == OP65_STX                  &&
+           !CS_RangeHasLabel (S, I+1, 2)       &&
            CS_GetEntries (S, L, I+1, 2)        &&
                    L[0]->OPC == OP65_STX               &&
            strcmp (L[0]->Arg, "tmp1") == 0     &&
-           !CE_HasLabel (L[0])                 &&
            L[1]->OPC == OP65_ORA               &&
-           strcmp (L[1]->Arg, "tmp1") == 0     &&
-           !CE_HasLabel (L[1])) {
+           strcmp (L[1]->Arg, "tmp1") == 0) {
 
            /* Remove the remaining instructions */
            CS_DelEntries (S, I+1, 2);
@@ -484,37 +426,93 @@ unsigned OptCmp2 (CodeSeg* S)
     unsigned I = 0;
     while (I < CS_GetEntryCount (S)) {
 
-       CodeEntry* L[2];
+       CodeEntry* L[3];
 
        /* Get next entry */
-               CodeEntry* E = CS_GetEntry (S, I);
+               L[0] = CS_GetEntry (S, I);
 
        /* Check for the sequence */
-               if ((E->OPC == OP65_ADC ||
-            E->OPC == OP65_AND ||
-            E->OPC == OP65_DEA ||
-            E->OPC == OP65_EOR ||
-            E->OPC == OP65_INA ||
-                    E->OPC == OP65_LDA ||
-            E->OPC == OP65_ORA ||
-            E->OPC == OP65_PLA ||
-            E->OPC == OP65_SBC ||
-            E->OPC == OP65_TXA ||
-            E->OPC == OP65_TYA)                       &&
-           CS_GetEntries (S, L, I+1, 2)               &&
-                   IsCmpToZero (L[0])                         &&
-           !CE_HasLabel (L[0])                        &&
-                   ((L[1]->Info & OF_FBRA) != 0         ||
-            (L[1]->OPC == OP65_JSR        &&
-             FindBoolCmpCond (L[1]->Arg) != CMP_INV)) &&
-           !CE_HasLabel (L[1])) {
-
-           /* Remove the compare */
-           CS_DelEntry (S, I+1);
+               if ((L[0]->OPC == OP65_ADC ||
+                    L[0]->OPC == OP65_AND ||
+                    L[0]->OPC == OP65_DEA ||
+                    L[0]->OPC == OP65_EOR ||
+                    L[0]->OPC == OP65_INA ||
+                    L[0]->OPC == OP65_LDA ||
+                    L[0]->OPC == OP65_ORA ||
+                    L[0]->OPC == OP65_PLA ||
+                    L[0]->OPC == OP65_SBC ||
+                    L[0]->OPC == OP65_TXA ||
+                    L[0]->OPC == OP65_TYA)         &&
+           !CS_RangeHasLabel (S, I+1, 2)   &&
+           CS_GetEntries (S, L+1, I+1, 2)   &&
+           L[1]->OPC == OP65_CMP           &&
+           CE_KnownImm (L[1])              &&
+           L[1]->Num == 0) {
+
+           /* Check for the call to boolxx. We cannot remove the compare if
+            * the carry flag is evaluated later, because the load will not
+            * set the carry flag.
+            */
+           if (L[2]->OPC == OP65_JSR) {
+               switch (FindBoolCmpCond (L[2]->Arg)) {
+
+                   case CMP_EQ:
+                   case CMP_NE:
+                   case CMP_GT:
+                   case CMP_GE:
+                   case CMP_LT:
+                   case CMP_LE:
+                       /* Remove the compare */
+                       CS_DelEntry (S, I+1);
+                       ++Changes;
+                       break;
+
+                   case CMP_UGT:
+                   case CMP_UGE:
+                   case CMP_ULT:
+                   case CMP_ULE:
+                   case CMP_INV:
+                       /* Leave it alone */
+                       break;
+               }
 
-           /* Remember, we had changes */
-           ++Changes;
+           } else {
 
+               /* Check for a branch on conditions that are set by the load.
+                        * Beware: The insn may branch to another conditional branch
+                * that evaluates other flags, so check that.
+                */
+               CodeEntry* E = L[2];
+               int Delete = 0;
+                       while (1) {
+                   if ((E->Info & (OF_CBRA|OF_UBRA)) != 0) {
+                       /* A conditional branch. Check if it jumps on a
+                        * condition not set by the load.
+                        */
+                       if ((E->Info & (OF_FBRA|OF_UBRA)) == 0) {
+                           /* Invalid branch */
+                           break;
+                       } else if (E->JumpTo == 0) {
+                           /* Jump to external */
+                           Delete = 1;
+                           break;
+                       } else {
+                           /* Check target of branch */
+                           E = E->JumpTo->Owner;
+                       }
+                   } else {
+                       /* Some other insn */
+                       Delete = 1;
+                       break;
+                   }
+               }
+
+               /* Delete the compare if we can */
+               if (Delete) {
+                   CS_DelEntry (S, I+1);
+                   ++Changes;
+               }
+           }
        }
 
        /* Next entry */
@@ -562,7 +560,7 @@ unsigned OptCmp3 (CodeSeg* S)
 
        /* Check for the sequence */
                if (E->OPC == OP65_LDA               &&
-           CS_GetEntries (S, L, I+1, 5) &&
+           CS_GetEntries (S, L, I+1, 5)     &&
            L[0]->OPC == OP65_LDX            &&
            !CE_HasLabel (L[0])              &&
            IsImmCmp16 (L+1)                 &&
@@ -610,10 +608,7 @@ unsigned OptCmp4 (CodeSeg* S)
 /* Optimize compares of local variables:
  *
  *      ldy     #o
- *      lda     (sp),y
- *      tax
- *      dey
- *      lda     (sp),y
+ *      jsr     ldaxysp
  *      cpx     #a
  *      bne     L1
  *     cmp     #b
@@ -626,42 +621,81 @@ unsigned OptCmp4 (CodeSeg* S)
     unsigned I = 0;
     while (I < CS_GetEntryCount (S)) {
 
-       CodeEntry* L[9];
+       CodeEntry* L[6];
+
+       /* Get the next entry */
+       L[0] = CS_GetEntry (S, I);
 
        /* Check for the sequence */
-               if (IsLocalLoad16 (S, I, L, 9) && IsImmCmp16 (L+5)) {
+       if (L[0]->OPC == OP65_LDY           &&
+           CE_KnownImm (L[0])              &&
+           CS_GetEntries (S, L+1, I+1, 5)  &&
+           !CE_HasLabel (L[1])             &&
+           CE_IsCall (L[1], "ldaxysp")     &&
+           IsImmCmp16 (L+2)) {
 
-                   if ((L[8]->Info & OF_FBRA) != 0 && L[5]->Num == 0 && L[7]->Num == 0) {
+                   if ((L[5]->Info & OF_FBRA) != 0 && L[2]->Num == 0 && L[4]->Num == 0) {
 
-               /* The value is zero, we may use the simple code version:
-                *      ldy     #o
-                *      lda     (sp),y
+               CodeEntry* X;
+               char Buf[20];
+
+               /* The value is zero, we may use the simple code version:
                 *      ldy     #o-1
+                *      lda     (sp),y
+                *      ldy     #o
                 *      ora     (sp),y
                 *      jne/jeq ...
                 */
-               CE_ReplaceOPC (L[4], OP65_ORA);
+               sprintf (Buf, "$%02X", (int)(L[0]->Num-1));
+               X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
+               CS_InsertEntry (S, X, I+1);
+
+               X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+               CS_InsertEntry (S, X, I+2);
+
+               X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
+               CS_InsertEntry (S, X, I+3);
+
+               X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+               CS_InsertEntry (S, X, I+4);
+
                CS_DelEntries (S, I+5, 3);   /* cpx/bne/cmp */
-               CS_DelEntry (S, I+2);        /* tax */
+               CS_DelEntry (S, I);          /* ldy */
 
                    } else {
 
+               CodeEntry* X;
+               char Buf[20];
+
                /* Change the code to just use the A register. Move the load
                 * of the low byte after the first branch if possible:
                 *
-                *      ldy     #o
+                *      ldy     #o-1
                 *      lda     (sp),y
                 *      cmp     #a
                 *      bne     L1
-                *      ldy     #o-1
+                *      ldy     #o
                 *      lda     (sp),y
                 *      cmp     #b
                 *      jne/jeq ...
                 */
-                       CS_DelEntry (S, I+2);             /* tax */
-               CE_ReplaceOPC (L[5], OP65_CMP);   /* cpx -> cmp */
-               CS_MoveEntry (S, I+4, I+2);       /* cmp */
-               CS_MoveEntry (S, I+5, I+3);       /* bne */
+               sprintf (Buf, "$%02X", (int)(L[0]->Num-1));
+               X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
+               CS_InsertEntry (S, X, I+3);
+
+               X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+               CS_InsertEntry (S, X, I+4);
+
+               X = NewCodeEntry (OP65_CMP, L[2]->AM, L[2]->Arg, 0, L[2]->LI);
+               CS_InsertEntry (S, X, I+5);
+
+               X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
+               CS_InsertEntry (S, X, I+7);
+
+               X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+               CS_InsertEntry (S, X, I+8);
+
+               CS_DelEntries (S, I, 3);          /* ldy/jsr/cpx */
 
            }
 
@@ -901,3 +935,4 @@ NextEntry:
 
 
 
+
index 838f82cdea95600d08dd340509d4df76fa04a28c..605c70317ca0e78511477e76aa906cba5dd65e89 100644 (file)
@@ -726,10 +726,10 @@ unsigned OptUnusedStores (CodeSeg* S)
            if ((GetRegInfo (S, I+1, R) & R) == 0) {
 
                /* Register value is not used, remove the load */
-               CS_DelEntry (S, I);
+               CS_DelEntry (S, I);
 
-               /* Remember, we had changes */
-               ++Changes;
+               /* Remember, we had changes */
+               ++Changes;
 
            }
        }
@@ -861,7 +861,7 @@ unsigned OptDupLoads (CodeSeg* S)
                 * that in the A register, replace the store by a STA. The
                 * optimizer will then remove the load instruction for Y
                 * later. If replacement by A is not possible try a
-                * replacement by X, but check for invalid addressing modes
+                * replacement by X, but check for invalid addressing modes
                 * in this case.
                 */
                        } else if (In->RegY >= 0) {
@@ -1033,7 +1033,7 @@ unsigned OptTransfers (CodeSeg* S)
                    goto NextEntry;
                }
                if ((X->Info & OF_FBRA) != 0) {
-                   if (I == 0) {
+                   if (I == 0) {
                        /* No preceeding entry */
                        goto NextEntry;
                    }
index 6aed9ccc2fbd9e54cb1e81d4c45856cce5881aaf..7ca08249ea7cc9dd905f1faa167e7460c77d058b 100644 (file)
@@ -185,12 +185,11 @@ unsigned OptNegAX1 (CodeSeg* S)
                CodeEntry* E = CS_GetEntry (S, I);
 
        /* Check if this is a call to bnegax, and if X is known and zero */
-       if (E->RI->In.RegX == 0             &&
-                   CE_IsCall (E, "bnegax")) {
+       if (E->RI->In.RegX == 0 && CE_IsCall (E, "bnegax")) {
 
-           /* We're cheating somewhat here ... */
-           E->Arg[5] = '\0';
-           E->Use &= ~REG_X;
+           CodeEntry* X = NewCodeEntry (OP65_JSR, AM65_ABS, "bnega", 0, E->LI);
+           CS_InsertEntry (S, X, I+1);
+           CS_DelEntry (S, I);
 
            /* We had changes */
            ++Changes;
@@ -213,18 +212,17 @@ unsigned OptNegAX1 (CodeSeg* S)
 unsigned OptNegAX2 (CodeSeg* S)
 /* Search for the sequence:
  *
- *     lda     (xx),y
- *     tax
- *     dey
- *     lda     (xx),y
+ *      ldy     #xx
+ *      jsr     ldaxysp
  *     jsr     bnegax
  *     jne/jeq ...
  *
  * and replace it by
  *
- *     lda     (xx),y
+ *      ldy     #xx
+ *     lda     (sp),y
  *     dey
- *     ora     (xx),y
+ *     ora     (sp),y
  *     jeq/jne ...
  */
 {
@@ -234,37 +232,39 @@ unsigned OptNegAX2 (CodeSeg* S)
     unsigned I = 0;
     while (I < CS_GetEntryCount (S)) {
 
-       CodeEntry* L[5];
+       CodeEntry* L[4];
 
        /* Get next entry */
-               CodeEntry* E = CS_GetEntry (S, I);
+               L[0] = CS_GetEntry (S, I);
 
        /* Check for the sequence */
-               if (E->OPC == OP65_LDA                  &&
-           E->AM == AM65_ZP_INDY               &&
-           CS_GetEntries (S, L, I+1, 5)        &&
-           L[0]->OPC == OP65_TAX               &&
-           L[1]->OPC == OP65_DEY               &&
-           L[2]->OPC == OP65_LDA               &&
-           L[2]->AM == AM65_ZP_INDY            &&
-           strcmp (L[2]->Arg, E->Arg) == 0     &&
-           !CE_HasLabel (L[2])                 &&
-                   CE_IsCall (L[3], "bnegax")          &&
-           !CE_HasLabel (L[3])                 &&
-                   (L[4]->Info & OF_ZBRA) != 0         &&
-           !CE_HasLabel (L[4])) {
-
-           /* lda --> ora */
-           CE_ReplaceOPC (L[2], OP65_ORA);
+       if (L[0]->OPC == OP65_LDY               &&
+           CE_KnownImm (L[0])                  &&
+           !CS_RangeHasLabel (S, I+1, 3)       &&
+                   CS_GetEntries (S, L+1, I+1, 3)      &&
+           CE_IsCall (L[1], "ldaxysp")         &&
+                   CE_IsCall (L[2], "bnegax")          &&
+                   (L[3]->Info & OF_ZBRA) != 0) {
+
+           CodeEntry* X;
+
+           /* lda (sp),y */
+           X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+           CS_InsertEntry (S, X, I+1);
+
+           /* dey */
+           X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[1]->LI);
+           CS_InsertEntry (S, X, I+2);
+
+           /* ora (sp),y */
+           X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
+           CS_InsertEntry (S, X, I+3);
 
            /* Invert the branch */
-           CE_ReplaceOPC (L[4], GetInverseBranch (L[4]->OPC));
+                   CE_ReplaceOPC (L[3], GetInverseBranch (L[3]->OPC));
 
-           /* Delete the entries no longer needed. Beware: Deleting entries
-            * will change the indices.
-            */
-                   CS_DelEntry (S, I+4);               /* jsr bnegax */
-           CS_DelEntry (S, I+1);               /* tax */
+           /* Delete the entries no longer needed. */
+                   CS_DelEntries (S, I+4, 2);
 
            /* Remember, we had changes */
            ++Changes;
diff --git a/src/cc65/coptpush.c b/src/cc65/coptpush.c
new file mode 100644 (file)
index 0000000..187db0f
--- /dev/null
@@ -0,0 +1,119 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               coptpush.c                                 */
+/*                                                                           */
+/*                         Optimize push sequences                          */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001      Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "xsprintf.h"
+
+/* cc65 */                       
+#include "codeent.h"
+#include "codeinfo.h"
+#include "coptpush.h"
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+unsigned OptPush1 (CodeSeg* S)
+/* Given a sequence
+ *
+ *     ldy     #xx
+ *     jsr     ldaxysp
+ *     jsr     pushax
+ *
+ * If a/x are not used later, replace that by
+ *
+ *     ldy     #xx+2
+ *     jsr     pushwysp
+ *
+ * saving 3 bytes and several cycles.
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[3];
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+       if (L[0]->OPC == OP65_LDY               &&
+           CE_KnownImm (L[0])                  &&
+           L[0]->Num < 0xFE                    &&
+           !CS_RangeHasLabel (S, I+1, 2)       &&
+                   CS_GetEntries (S, L+1, I+1, 2)      &&
+           CE_IsCall (L[1], "ldaxysp")         &&
+                   CE_IsCall (L[2], "pushax")          &&
+                   (GetRegInfo (S, I+3, REG_AX) & REG_AX) == 0) {
+
+           /* Insert new code behind the pushax */
+           char Buf [20];
+           CodeEntry* X;
+
+           /* ldy     #xx+1 */
+           xsprintf (Buf, sizeof (Buf), "$%02X", (int)(L[0]->Num+2));
+           X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
+           CS_InsertEntry (S, X, I+3);
+
+           /* jsr pushwysp */
+           X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwysp", 0, L[2]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+           /* Delete the old code */
+           CS_DelEntries (S, I, 3);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
diff --git a/src/cc65/coptpush.h b/src/cc65/coptpush.h
new file mode 100644 (file)
index 0000000..3990513
--- /dev/null
@@ -0,0 +1,74 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                               coptpush.h                                 */
+/*                                                                           */
+/*                         Optimize push sequences                          */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2001      Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef COPTPUSH_H
+#define COPTPUSH_H
+
+
+
+/* cc65 */
+#include "codeseg.h"
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+unsigned OptPush1 (CodeSeg* S);
+/* Given a sequence
+ *
+ *     ldy     #xx
+ *     jsr     ldaxysp
+ *     jsr     pushax
+ *
+ * If a/x are not used later, replace that by
+ *
+ *     ldy     #xx+2
+ *     jsr     pushwysp
+ *
+ * saving 3 bytes and several cycles.
+ */
+
+
+
+/* End of coptpush.h */
+
+#endif
+
+
+
index 1aeaabea3c887b4355c2423f1393e536aac53dc9..cbd09caa0a9bcb9eab9e69151bdeca4b04d2e1ac 100644 (file)
@@ -129,20 +129,16 @@ unsigned OptSub2 (CodeSeg* S)
 
        /* Check for the sequence */
                if (E->OPC == OP65_LDA                             &&
+           !CS_RangeHasLabel (S, I+1, 5)                  &&
            CS_GetEntries (S, L, I+1, 5)                   &&
                    L[0]->OPC == OP65_SEC                          &&
-           !CE_HasLabel (L[0])                            &&
                    L[1]->OPC == OP65_STA                          &&
            strcmp (L[1]->Arg, "tmp1") == 0                &&
-           !CE_HasLabel (L[1])                            &&
            L[2]->OPC == OP65_LDA                          &&
-                   !CE_HasLabel (L[2])                            &&
            L[3]->OPC == OP65_SBC                          &&
            strcmp (L[3]->Arg, "tmp1") == 0                &&
-                   !CE_HasLabel (L[3])                            &&
            L[4]->OPC == OP65_STA                          &&
-           strcmp (L[4]->Arg, L[2]->Arg) == 0             &&
-                   !CE_HasLabel (L[4])) {
+           strcmp (L[4]->Arg, L[2]->Arg) == 0) {
 
            /* Remove the store to tmp1 */
            CS_DelEntry (S, I+2);
index 34ab9af3a9b357cdc51b66278f0ae64e579f2810..a22ae93e5f6fd8ff08e59eafde69f1dee71be295 100644 (file)
@@ -39,6 +39,7 @@ OBJS =        anonname.o      \
        coptcmp.o       \
        coptind.o       \
        coptneg.o       \
+       coptpush.o      \
        coptstop.o      \
        coptsub.o       \
        copttest.o      \
index 2fcc6431b5afd1a9f9705847cad027632915c80a..5fb562d4ca2bff906e72839261d7bc070cc96932 100644 (file)
@@ -84,6 +84,7 @@ OBJS =        anonname.obj    \
        coptcmp.obj     \
        coptind.obj     \
        coptneg.obj     \
+       coptpush.obj    \
        coptstop.obj    \
        coptsub.obj     \
        copttest.obj    \
@@ -162,6 +163,7 @@ FILE coptc02.obj
 FILE coptcmp.obj
 FILE coptind.obj
 FILE coptneg.obj
+FILE coptpush.obj
 FILE coptstop.obj
 FILE coptsub.obj
 FILE copttest.obj