]> git.sur5r.net Git - cc65/commitdiff
added optimization for indexed 16-bit array load of form (array[i & 0x7f])
authorSteven Hugg <hugg@fasterlight.com>
Thu, 14 Mar 2019 13:41:50 +0000 (09:41 -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 db63ba8e77555a9503634f7e50ec1d2bb0c964ce..d920f001a6134488cad838e84aa3302a56e45db3 100644 (file)
@@ -815,6 +815,7 @@ static OptFunc DOptPtrLoad15    = { OptPtrLoad15,    "OptPtrLoad15",     86, 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 DOptPtrLoad19    = { OptPtrLoad19,    "OptPtrLoad19",     65, 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 };
@@ -907,6 +908,7 @@ static OptFunc* OptFuncs[] = {
     &DOptPtrLoad16,
     &DOptPtrLoad17,
     &DOptPtrLoad18,
+    &DOptPtrLoad19,
     &DOptPtrLoad2,
     &DOptPtrLoad3,
     &DOptPtrLoad4,
@@ -1256,6 +1258,7 @@ static unsigned RunOptGroup1 (CodeSeg* S)
     Changes += RunOptFunc (S, &DOptPtrLoad15, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad16, 1);
     Changes += RunOptFunc (S, &DOptPtrLoad17, 1);
+    Changes += RunOptFunc (S, &DOptPtrLoad19, 1);
     Changes += RunOptFunc (S, &DOptBNegAX1, 1);
     Changes += RunOptFunc (S, &DOptBNegAX2, 1);
     Changes += RunOptFunc (S, &DOptBNegAX3, 1);
index 81682ab096cd37d0dfc158b757ab45842da1a52c..c508d56f492b67d6147736b69fb998df3b0903f7 100644 (file)
@@ -1554,3 +1554,116 @@ unsigned OptPtrLoad18 (CodeSeg* S)
 
 
 
+unsigned OptPtrLoad19 (CodeSeg* S)
+/* Search for the sequence:
+**
+**     and     #mask           (any value < 128)
+**      jsr     aslax1/shlax1
+**      clc
+**      adc     #<(label+0)
+**      tay
+**      txa
+**      adc     #>(label+0)
+**      tax
+**      tya
+**      ldy     #$01
+**      jsr     ldaxidx
+**
+** and replace it by:
+**
+**     and     #mask           (remove if == 127)
+**     asl
+**     tay
+**     lda     label,y
+**     ldx     label+1,y
+*/
+{
+    unsigned Changes = 0;
+    unsigned I;
+
+    /* Walk over the entries */
+    I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+        CodeEntry* L[11];
+
+        /* Get next entry */
+        L[0] = CS_GetEntry (S, I);
+
+        /* Check for the sequence */
+        if (L[0]->OPC == OP65_AND                               &&
+            L[0]->AM == AM65_IMM                                &&
+            CE_HasNumArg (L[0]) && L[0]->Num <= 127             &&
+            CS_GetEntries (S, L+1, I+1, 10)                     &&
+            L[1]->OPC == OP65_JSR                               &&
+            (strcmp (L[1]->Arg, "aslax1") == 0          ||
+             strcmp (L[1]->Arg, "shlax1") == 0)                 &&
+            L[2]->OPC == OP65_CLC                               &&
+            L[3]->OPC == OP65_ADC                               &&
+            L[4]->OPC == OP65_TAY                               &&
+            L[5]->OPC == OP65_TXA                               &&
+            L[6]->OPC == OP65_ADC                               &&
+            L[7]->OPC == OP65_TAX                               &&
+            L[8]->OPC == OP65_TYA                               &&
+            L[9]->OPC == OP65_LDY                               &&
+            CE_IsKnownImm(L[9], 1)                              &&
+            strlen(L[3]->Arg) >= 3                              &&
+            L[3]->Arg[0] == '<'                                 &&
+            strlen(L[6]->Arg) >= 3                              &&
+            L[6]->Arg[0] == '>'                                 &&
+            !strcmp(L[3]->Arg+1, L[6]->Arg+1)                   &&
+            CE_IsCallTo (L[10], "ldaxidx")                      &&
+            !CS_RangeHasLabel (S, I+1, 10)) {
+
+            CodeEntry* X;
+            char* Label;
+            int Len = strlen(L[3]->Arg);
+
+            /* Track the insertion point */
+            unsigned IP = I + 11;
+
+            /* asl a */
+            X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, L[1]->LI);
+            CS_InsertEntry (S, X, IP++);
+
+            /* tay */
+            X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[1]->LI);
+            CS_InsertEntry (S, X, IP++);
+
+            /* lda label,y */
+            Label = memcpy (xmalloc (Len-2), L[3]->Arg+2, Len-3);
+            Label[Len-3] = '\0';
+            X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[9]->LI);
+            CS_InsertEntry (S, X, IP++);
+            xfree (Label);
+
+            /* lda label+1,y */
+            Label = memcpy (xmalloc (Len), L[3]->Arg+2, Len-3);
+            strcpy(&Label[Len-3], "+1");
+            X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[9]->LI);
+            CS_InsertEntry (S, X, IP++);
+            xfree (Label);
+
+            /* Remove the old code */
+            /* Remove the AND only if it's == 127, since ASL erases high bit */
+            if (L[0]->Num == 127)
+                CS_DelEntries (S, I, 11);
+            else
+                CS_DelEntries (S, I+1, 10);
+
+            /* Remember, we had changes */
+            ++Changes;
+
+        }
+
+        /* Next entry */
+        ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
index 4581ccb45f7c6ef465f07feaa520dcc79155a005..8a118a268ec9890010b46b25b9ed089e260d33f4 100644 (file)
@@ -379,6 +379,31 @@ unsigned OptPtrLoad18 (CodeSeg* S);
 */
 
 
+unsigned OptPtrLoad19 (CodeSeg* S);
+/* Search for the sequence:
+**
+**     and     #mask           (any value < 128)
+**      jsr     aslax1/shlax1
+**      clc
+**      adc     #<(label+0)
+**      tay
+**      txa
+**      adc     #>(label+0)
+**      tax
+**      tya
+**      ldy     #$01
+**      jsr     ldaxidx
+**
+** and replace it by:
+**
+**     and     #mask           (remove if == 127)
+**     asl
+**     tay
+**     lda     label,y
+**     ldx     label+1,y
+*/
+
+
 /* End of coptptrload.h */
 
 #endif