From ffc118cd94465ee5c3573a6176304b8cd86397e8 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Thu, 14 Mar 2019 07:20:16 -0400 Subject: [PATCH] added optimization for indexed pointer load of a constant, e.g.: y = ((unsigned char*)0x100)[i] --- src/cc65/codeopt.c | 3 ++ src/cc65/coptptrload.c | 97 ++++++++++++++++++++++++++++++++++++++++++ src/cc65/coptptrload.h | 21 +++++++++ 3 files changed, 121 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 575398c11..db63ba8e7 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -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); diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index ee783c93f..81682ab09 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -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; +} + + + diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index fd93bf5c2..4581ccb45 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -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 */