From 5d274e4bc5b81002146e72602dae235dcd4c591e Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Thu, 14 Mar 2019 09:41:50 -0400 Subject: [PATCH] added optimization for indexed 16-bit array load of form (array[i & 0x7f]) --- src/cc65/codeopt.c | 3 ++ src/cc65/coptptrload.c | 113 +++++++++++++++++++++++++++++++++++++++++ src/cc65/coptptrload.h | 25 +++++++++ 3 files changed, 141 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index db63ba8e7..d920f001a 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -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); diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 81682ab09..c508d56f4 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -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; +} + + + diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index 4581ccb45..8a118a268 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -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 -- 2.39.2