From 9142a300c1f66272bd91fb81c88bc9b30f17afe2 Mon Sep 17 00:00:00 2001 From: uz Date: Tue, 12 Jun 2012 18:11:53 +0000 Subject: [PATCH] Another optimization for array stores. git-svn-id: svn://svn.cc65.org/cc65/trunk@5715 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeopt.c | 5 +- src/cc65/coptptrstore.c | 140 ++++++++++++++++++++++++++++++++++++---- src/cc65/coptptrstore.h | 40 ++++++++---- 3 files changed, 161 insertions(+), 24 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 18444a265..def758a8a 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1204,7 +1204,8 @@ static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 40, 0, static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrStore4 = { OptPtrStore4, "OptPtrStore4", 65, 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrStore5 = { OptPtrStore5, "OptPtrStore5", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrStore5 = { OptPtrStore5, "OptPtrStore5", 65, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrStore6 = { OptPtrStore6, "OptPtrStore6", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPush1 = { OptPush1, "OptPush1", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPush2 = { OptPush2, "OptPush2", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptPushPop = { OptPushPop, "OptPushPop", 0, 0, 0, 0, 0, 0 }; @@ -1299,6 +1300,7 @@ static OptFunc* OptFuncs[] = { &DOptPtrStore3, &DOptPtrStore4, &DOptPtrStore5, + &DOptPtrStore6, &DOptPush1, &DOptPush2, &DOptPushPop, @@ -1574,6 +1576,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptPtrStore3, 1); Changes += RunOptFunc (S, &DOptPtrStore4, 1); Changes += RunOptFunc (S, &DOptPtrStore5, 1); + Changes += RunOptFunc (S, &DOptPtrStore6, 1); Changes += RunOptFunc (S, &DOptAdd3, 1); /* Before OptPtrLoad5! */ Changes += RunOptFunc (S, &DOptPtrLoad1, 1); Changes += RunOptFunc (S, &DOptPtrLoad2, 1); diff --git a/src/cc65/coptptrstore.c b/src/cc65/coptptrstore.c index f6cfae71f..63cfd22d5 100644 --- a/src/cc65/coptptrstore.c +++ b/src/cc65/coptptrstore.c @@ -491,6 +491,9 @@ unsigned OptPtrStore4 (CodeSeg* S) * ldx #$00 * lda yyy * sta (ptr1),y + * + * In case a/x is loaded from the register bank before the clc, we can even + * use the register bank instead of ptr1. */ { unsigned Changes = 0; @@ -526,7 +529,7 @@ unsigned OptPtrStore4 (CodeSeg* S) CodeEntry* X; const char* ZPLoc; - + /* Track the insertion point */ unsigned IP = I + 9; @@ -567,7 +570,7 @@ unsigned OptPtrStore4 (CodeSeg* S) } /* Next entry */ - ++I; + ++I; } @@ -578,6 +581,129 @@ unsigned OptPtrStore4 (CodeSeg* S) unsigned OptPtrStore5 (CodeSeg* S) +/* Search for the sequence: + * + * clc + * adc xxx + * bcc L + * inx + * L: jsr pushax + * ldy yyy + * ldx #$00 + * lda (sp),y + * ldy #$00 + * jsr staspidx + * + * and replace it by: + * + * sta ptr1 + * stx ptr1+1 + * ldy yyy-2 + * ldx #$00 + * lda (sp),y + * ldy xxx + * sta (ptr1),y + * + * In case a/x is loaded from the register bank before the clc, we can even + * use the register bank instead of ptr1. + */ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[10]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_CLC && + CS_GetEntries (S, L+1, I+1, 9) && + L[1]->OPC == OP65_ADC && + (L[1]->AM == AM65_ABS || + L[1]->AM == AM65_ZP || + L[1]->AM == AM65_IMM) && + (L[2]->OPC == OP65_BCC || L[2]->OPC == OP65_JCC) && + L[2]->JumpTo != 0 && + L[2]->JumpTo->Owner == L[4] && + L[3]->OPC == OP65_INX && + CE_IsCallTo (L[4], "pushax") && + L[5]->OPC == OP65_LDY && + CE_IsConstImm (L[5]) && + L[6]->OPC == OP65_LDX && + L[7]->OPC == OP65_LDA && + L[7]->AM == AM65_ZP_INDY && + strcmp (L[7]->Arg, "sp") == 0 && + L[8]->OPC == OP65_LDY && + (L[8]->AM == AM65_ABS || + L[8]->AM == AM65_ZP || + L[8]->AM == AM65_IMM) && + CE_IsCallTo (L[9], "staspidx") && + !CS_RangeHasLabel (S, I+1, 3) && + !CS_RangeHasLabel (S, I+5, 5)) { + + CodeEntry* X; + const char* Arg; + const char* ZPLoc; + + /* Track the insertion point */ + unsigned IP = I + 10; + + /* If the sequence is preceeded by a load of a ZP value, we can + * use this ZP value as a pointer. + */ + if (I < 2 || (ZPLoc = ZPLoadAX (S, I-2)) == 0) { + + ZPLoc = "ptr1"; + + /* Must use ptr1 */ + X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[9]->LI); + CS_InsertEntry (S, X, IP++); + + X = NewCodeEntry (OP65_STX, AM65_ZP, "ptr1+1", 0, L[9]->LI); + CS_InsertEntry (S, X, IP++); + + } + + Arg = MakeHexArg (L[5]->Num - 2); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[5]->LI); + CS_InsertEntry (S, X, IP++); + + X = NewCodeEntry (OP65_LDX, L[6]->AM, L[6]->Arg, 0, L[6]->LI); + CS_InsertEntry (S, X, IP++); + + X = NewCodeEntry (OP65_LDA, L[7]->AM, L[7]->Arg, 0, L[7]->LI); + CS_InsertEntry (S, X, IP++); + + X = NewCodeEntry (OP65_LDY, L[1]->AM, L[1]->Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, IP++); + + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, ZPLoc, 0, L[9]->LI); + CS_InsertEntry (S, X, IP++); + + /* Remove the old code */ + CS_DelEntries (S, I, 10); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptPtrStore6 (CodeSeg* S) /* Search for the sequence: * * jsr pushax @@ -601,16 +727,6 @@ unsigned OptPtrStore5 (CodeSeg* S) * In case a/x is loaded from the register bank before the pushax, we can even * use the register bank instead of ptr1. * - * - * jsr pushax - * ldy xxx - * jsr ldauidx - * ldx #$00 - * lda (zp),y - * subop - * ldy yyy - * sta (zp),y - * jsr staspidx */ { unsigned Changes = 0; diff --git a/src/cc65/coptptrstore.h b/src/cc65/coptptrstore.h index 76d283cf2..bb21a9966 100644 --- a/src/cc65/coptptrstore.h +++ b/src/cc65/coptptrstore.h @@ -153,6 +153,34 @@ unsigned OptPtrStore4 (CodeSeg* S); */ unsigned OptPtrStore5 (CodeSeg* S); +/* Search for the sequence: + * + * clc + * adc xxx + * bcc L + * inx + * L: jsr pushax + * ldy yyy + * ldx #$00 + * lda (sp),y + * ldy #$00 + * jsr staspidx + * + * and replace it by: + * + * sta ptr1 + * stx ptr1+1 + * ldy yyy-2 + * ldx #$00 + * lda (sp),y + * ldy xxx + * sta (ptr1),y + * + * In case a/x is loaded from the register bank before the clc, we can even + * use the register bank instead of ptr1. + */ + +unsigned OptPtrStore6 (CodeSeg* S); /* Search for the sequence: * * jsr pushax @@ -176,16 +204,6 @@ unsigned OptPtrStore5 (CodeSeg* S); * In case a/x is loaded from the register bank before the pushax, we can even * use the register bank instead of ptr1. * - * - * jsr pushax - * ldy xxx - * jsr ldauidx - * ldx #$00 - * lda (zp),y - * subop - * ldy yyy - * sta (zp),y - * jsr staspidx */ @@ -195,4 +213,4 @@ unsigned OptPtrStore5 (CodeSeg* S); - + -- 2.39.5