]> git.sur5r.net Git - cc65/commitdiff
added optimization for indexed pointer load of a constant, e.g.: y = ((unsigned char...
authorSteven Hugg <hugg@fasterlight.com>
Thu, 14 Mar 2019 11:20:16 +0000 (07:20 -0400)
committergreg-king5 <greg.king5@verizon.net>
Mon, 1 Apr 2019 02:33:22 +0000 (22:33 -0400)
src/cc65/codeopt.c
src/cc65/coptptrload.c
src/cc65/coptptrload.h

index 575398c116dc5438338274dc234d5eb415bdded1..db63ba8e77555a9503634f7e50ec1d2bb0c964ce 100644 (file)
@@ -814,6 +814,7 @@ static OptFunc DOptPtrLoad14    = { OptPtrLoad14,    "OptPtrLoad14",    108, 0,
 static OptFunc DOptPtrLoad15    = { OptPtrLoad15,    "OptPtrLoad15",     86, 0, 0, 0, 0, 0 };
 static OptFunc DOptPtrLoad16    = { OptPtrLoad16,    "OptPtrLoad16",    100, 0, 0, 0, 0, 0 };
 static OptFunc DOptPtrLoad17    = { OptPtrLoad17,    "OptPtrLoad17",    190, 0, 0, 0, 0, 0 };
+static OptFunc DOptPtrLoad18    = { OptPtrLoad18,    "OptPtrLoad18",    100, 0, 0, 0, 0, 0 };
 static OptFunc DOptPtrStore1    = { OptPtrStore1,    "OptPtrStore1",     65, 0, 0, 0, 0, 0 };
 static OptFunc DOptPtrStore2    = { OptPtrStore2,    "OptPtrStore2",     65, 0, 0, 0, 0, 0 };
 static OptFunc DOptPtrStore3    = { OptPtrStore3,    "OptPtrStore3",    100, 0, 0, 0, 0, 0 };
@@ -905,6 +906,7 @@ static OptFunc* OptFuncs[] = {
     &DOptPtrLoad15,
     &DOptPtrLoad16,
     &DOptPtrLoad17,
+    &DOptPtrLoad18,
     &DOptPtrLoad2,
     &DOptPtrLoad3,
     &DOptPtrLoad4,
@@ -1246,6 +1248,7 @@ static unsigned RunOptGroup1 (CodeSeg* S)
     Changes += RunOptFunc (S, &DOptPtrLoad5, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad6, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad7, 1);
+    Changes += RunOptFunc (S, &DOptPtrLoad18, 1); /* Before OptPtrLoad11 */
     Changes += RunOptFunc (S, &DOptPtrLoad11, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad12, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad13, 1);
index ee783c93f3ad3fd58f88660a14ea751f8e10e697..81682ab096cd37d0dfc158b757ab45842da1a52c 100644 (file)
@@ -1457,3 +1457,100 @@ unsigned OptPtrLoad17 (CodeSeg* S)
     /* Return the number of changes made */
     return Changes;
 }
+
+
+
+unsigned OptPtrLoad18 (CodeSeg* S)
+/* Search for the sequence:
+**
+**      ldx     #$xx
+**      lda     #$yy
+**      clc
+**      adc     xxx
+**      bcc     L
+**      inx
+** L:   ldy     #$00
+**      jsr     ldauidx
+**
+** and replace it by:
+**
+**      ldy     xxx
+**      ldx     #$00
+**      lda     $xxyy,y
+**
+** This is similar to OptPtrLoad3 but works on a constant address
+** instead of a label. Also, the initial X and A loads are reversed.
+** Must be run before OptPtrLoad11.
+*/
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+        CodeEntry* L[8];
+
+        /* Get next entry */
+        L[0] = CS_GetEntry (S, I);
+
+        /* Check for the sequence */
+        if (L[0]->OPC == OP65_LDX                            &&
+            L[0]->AM == AM65_IMM                             &&
+            CS_GetEntries (S, L+1, I+1, 7)                   &&
+            L[1]->OPC == OP65_LDA                            &&
+            L[1]->AM == AM65_IMM                             &&
+            L[2]->OPC == OP65_CLC                            &&
+            L[3]->OPC == OP65_ADC                            &&
+            (L[3]->AM == AM65_ABS || L[3]->AM == AM65_ZP)    &&
+            (L[4]->OPC == OP65_BCC || L[4]->OPC == OP65_JCC) &&
+            L[4]->JumpTo != 0                                &&
+            L[4]->JumpTo->Owner == L[6]                      &&
+            L[5]->OPC == OP65_INX                            &&
+            L[6]->OPC == OP65_LDY                            &&
+            CE_IsKnownImm (L[6], 0)                          &&
+            CE_IsCallTo (L[7], "ldauidx")                    &&
+            !CS_RangeHasLabel (S, I+1, 5)                    &&
+            !CE_HasLabel (L[7])                              &&
+            strlen (L[0]->Arg) == 3                          &&
+            L[0]->Arg[0] == '$'                              &&
+            strlen (L[1]->Arg) == 3                          &&
+            L[1]->Arg[0] == '$'                              ) {
+
+            CodeEntry* X;
+            char* Label;
+
+            /* We will create all the new stuff behind the current one so
+            ** we keep the line references.
+            */
+            X = NewCodeEntry (OP65_LDY, L[3]->AM, L[3]->Arg, 0, L[0]->LI);
+            CS_InsertEntry (S, X, I+8);
+
+            X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI);
+            CS_InsertEntry (S, X, I+9);
+
+            Label = xmalloc(6);
+            sprintf(Label, "$%s%s", L[0]->Arg+1, L[1]->Arg+1);
+            X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI);
+            CS_InsertEntry (S, X, I+10);
+            xfree (Label);
+
+            /* Remove the old code */
+            CS_DelEntries (S, I, 8);
+
+            /* Remember, we had changes */
+            ++Changes;
+
+        }
+
+        /* Next entry */
+        ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
index fd93bf5c2cf55e708dcf9166520c94dfc44f71c5..4581ccb45f7c6ef465f07feaa520dcc79155a005 100644 (file)
@@ -356,6 +356,27 @@ unsigned OptPtrLoad17 (CodeSeg* S);
 ** the step with less than 200% so it gets executed when -Oi is in effect.
 */
 
+unsigned OptPtrLoad18 (CodeSeg* S);
+/* Search for the sequence:
+**
+**      ldx     #$xx
+**      lda     #$yy
+**      clc
+**      adc     xxx
+**      bcc     L
+**      inx
+** L:   ldy     #$00
+**      jsr     ldauidx
+**
+** and replace it by:
+**
+**      ldy     xxx
+**      ldx     #$00
+**      lda     $xxyy,y
+**
+** This is similar to OptPtrLoad3 but works on a constant address
+** instead of a label. Also, the initial X and A loads are reversed.
+*/
 
 
 /* End of coptptrload.h */