From c7490cf060e914ca03cf6586d3ec0c29d4cbe290 Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 11 Sep 2005 12:52:12 +0000 Subject: [PATCH] Some function renaming. Improved an optimization step. git-svn-id: svn://svn.cc65.org/cc65/trunk@3642 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeent.c | 36 +++++++---- src/cc65/codeent.h | 17 ++++-- src/cc65/codeopt.c | 20 +++--- src/cc65/codeseg.c | 14 ++--- src/cc65/coptadd.c | 16 ++--- src/cc65/coptc02.c | 10 +-- src/cc65/coptcmp.c | 19 +++--- src/cc65/coptind.c | 21 +++---- src/cc65/coptneg.c | 10 +-- src/cc65/coptsize.c | 14 ++--- src/cc65/coptstop.c | 142 ++++++++++++++++++++++++++++++------------- src/cc65/coptstore.c | 13 ++-- 12 files changed, 199 insertions(+), 133 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 3c2f03b32..13b7aed14 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -394,14 +394,26 @@ void CE_SetNumArg (CodeEntry* E, long Num) -int CE_KnownImm (const CodeEntry* E) -/* Return true if the argument of E is a known immediate value */ +int CE_IsConstImm (const CodeEntry* E) +/* Return true if the argument of E is a constant immediate value */ { return (E->AM == AM65_IMM && (E->Flags & CEF_NUMARG) != 0); } +int CE_IsKnownImm (const CodeEntry* E, unsigned long Num) +/* Return true if the argument of E is a constant immediate value that is + * equal to Num. + */ +{ + return E->AM == AM65_IMM && + (E->Flags & CEF_NUMARG) != 0 && + E->Num == Num; +} + + + int CE_UseLoadFlags (const CodeEntry* E) /* Return true if the instruction uses any flags that are set by a load of * a register (N and Z). @@ -519,7 +531,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_AND: if (RegValIsKnown (In->RegA)) { - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = In->RegA & (short) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -676,7 +688,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_EOR: if (RegValIsKnown (In->RegA)) { - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = In->RegA ^ (short) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -825,7 +837,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_LDA: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -855,7 +867,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_LDX: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegX = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -885,7 +897,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_LDY: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegY = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { @@ -946,7 +958,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_ORA: if (RegValIsKnown (In->RegA)) { - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { Out->RegA = In->RegA | (short) E->Num; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Use & REG_ZP, In)) { diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 99c003b74..01a815728 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -192,8 +192,13 @@ void CE_SetNumArg (CodeEntry* E, long Num); * have a numeric argument. */ -int CE_KnownImm (const CodeEntry* E); -/* Return true if the argument of E is a known immediate value */ +int CE_IsConstImm (const CodeEntry* E); +/* Return true if the argument of E is a constant immediate value */ + +int CE_IsKnownImm (const CodeEntry* E, unsigned long Num); +/* Return true if the argument of E is a constant immediate value that is + * equal to Num. + */ #if defined(HAVE_INLINE) INLINE int CE_IsCallTo (const CodeEntry* E, const char* Name) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index e26e747f4..3c956f293 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -491,14 +491,14 @@ static unsigned OptPtrStore1 (CodeSeg* S) if (CE_IsCallTo (L[0], "pushax") && CS_GetEntries (S, L+1, I+1, 3) && L[1]->OPC == OP65_LDY && - CE_KnownImm (L[1]) && + CE_IsConstImm (L[1]) && !CE_HasLabel (L[1]) && CE_IsCallTo (L[2], "ldauidx") && !CE_HasLabel (L[2]) && (K = OptPtrStore1Sub (S, I+3, L+3)) > 0 && CS_GetEntries (S, L+3+K, I+3+K, 2) && L[3+K]->OPC == OP65_LDY && - CE_KnownImm (L[3+K]) && + CE_IsConstImm (L[3+K]) && !CE_HasLabel (L[3+K]) && CE_IsCallTo (L[4+K], "staspidx") && !CE_HasLabel (L[4+K])) { @@ -633,8 +633,7 @@ static unsigned OptPtrStore2 (CodeSeg* S) L[7]->OPC == OP65_LDX && L[8]->OPC == OP65_LDA && L[9]->OPC == OP65_LDY && - CE_KnownImm (L[9]) && - L[9]->Num == 0 && + CE_IsKnownImm (L[9], 0) && CE_IsCallTo (L[10], "staspidx") && !CS_RangeHasLabel (S, I+1, 5) && !CS_RangeHasLabel (S, I+7, 4) && @@ -937,8 +936,7 @@ static unsigned OptPtrLoad3 (CodeSeg* S) L[4]->JumpTo->Owner == L[6] && L[5]->OPC == OP65_INX && L[6]->OPC == OP65_LDY && - CE_KnownImm (L[6]) && - L[6]->Num == 0 && + CE_IsKnownImm (L[6], 0) && CE_IsCallTo (L[7], "ldauidx") && !CS_RangeHasLabel (S, I+1, 5) && !CE_HasLabel (L[7]) && @@ -1029,7 +1027,7 @@ static unsigned OptPtrLoad4 (CodeSeg* S) L[1]->AM == AM65_IMM && !CE_HasLabel (L[1]) && L[2]->OPC == OP65_LDY && - CE_KnownImm (L[2]) && + CE_IsConstImm (L[2]) && !CE_HasLabel (L[2]) && L[3]->OPC == OP65_CLC && !CE_HasLabel (L[3]) && @@ -1043,8 +1041,7 @@ static unsigned OptPtrLoad4 (CodeSeg* S) L[6]->OPC == OP65_INX && !CE_HasLabel (L[6]) && L[7]->OPC == OP65_LDY && - CE_KnownImm (L[7]) && - L[7]->Num == 0 && + CE_IsKnownImm (L[7], 0) && CE_IsCallTo (L[8], "ldauidx") && !CE_HasLabel (L[8]) && /* Check the label last because this is quite costly */ @@ -1161,8 +1158,7 @@ static unsigned OptPtrLoad5 (CodeSeg* S) strcmp (L[3]->Arg, "regsave+1") == 0 && L[4]->OPC == OP65_CLC && L[5]->OPC == OP65_ADC && - CE_KnownImm (L[5]) && - L[5]->Num == 1 && + CE_IsKnownImm (L[5], 1) && L[6]->OPC == OP65_BCC && L[6]->JumpTo != 0 && L[6]->JumpTo->Owner == L[8] && @@ -1180,7 +1176,7 @@ static unsigned OptPtrLoad5 (CodeSeg* S) L[11]->AM == AM65_ZP && strcmp (L[11]->Arg, "regsave+1") == 0 && L[12]->OPC == OP65_LDY && - CE_KnownImm (L[12]) && + CE_IsConstImm (L[12]) && CE_IsCallTo (L[13], "ldauidx")) { CodeEntry* X; diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 20c59df7b..08222b9c4 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -1493,7 +1493,7 @@ void CS_GenRegInfo (CodeSeg* S) /* If this is an immidiate compare, the A register has * the value of the compare later. */ - if (CE_KnownImm (P)) { + if (CE_IsConstImm (P)) { if (BC == BC_EQ) { E->RI->Out2.RegA = (unsigned char)P->Num; } else { @@ -1506,7 +1506,7 @@ void CS_GenRegInfo (CodeSeg* S) /* If this is an immidiate compare, the X register has * the value of the compare later. */ - if (CE_KnownImm (P)) { + if (CE_IsConstImm (P)) { if (BC == BC_EQ) { E->RI->Out2.RegX = (unsigned char)P->Num; } else { @@ -1519,7 +1519,7 @@ void CS_GenRegInfo (CodeSeg* S) /* If this is an immidiate compare, the Y register has * the value of the compare later. */ - if (CE_KnownImm (P)) { + if (CE_IsConstImm (P)) { if (BC == BC_EQ) { E->RI->Out2.RegY = (unsigned char)P->Num; } else { diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index d490574d9..4a74bce5e 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -88,13 +88,13 @@ unsigned OptAdd1 (CodeSeg* S) /* Check for the sequence */ if (L[0]->OPC == OP65_LDY && - CE_KnownImm (L[0]) && + CE_IsConstImm (L[0]) && !CS_RangeHasLabel (S, I+1, 5) && CS_GetEntries (S, L+1, I+1, 5) && CE_IsCallTo (L[1], "ldaxysp") && CE_IsCallTo (L[2], "pushax") && L[3]->OPC == OP65_LDY && - CE_KnownImm (L[3]) && + CE_IsConstImm (L[3]) && CE_IsCallTo (L[4], "ldaxysp") && CE_IsCallTo (L[5], "tosaddax")) { @@ -208,12 +208,12 @@ unsigned OptAdd2 (CodeSeg* S) /* Check for the sequence */ if (L[0]->OPC == OP65_LDY && - CE_KnownImm (L[0]) && + CE_IsConstImm (L[0]) && !CS_RangeHasLabel (S, I+1, 3) && CS_GetEntries (S, L+1, I+1, 3) && CE_IsCallTo (L[1], "ldaxysp") && L[2]->OPC == OP65_LDY && - CE_KnownImm (L[2]) && + CE_IsConstImm (L[2]) && CE_IsCallTo (L[3], "addeqysp") && (GetRegInfo (S, I+4, REG_AX) & REG_AX) == 0) { diff --git a/src/cc65/coptc02.c b/src/cc65/coptc02.c index 4ba8a3032..bffb5acc8 100644 --- a/src/cc65/coptc02.c +++ b/src/cc65/coptc02.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -131,7 +131,7 @@ unsigned Opt65C02BitOps (CodeSeg* S) !CS_RangeHasLabel (S, I+1, 2) && CS_GetEntries (S, L+1, I+1, 2) && (L[1]->OPC == OP65_AND || L[1]->OPC == OP65_ORA) && - CE_KnownImm (L[1]) && + CE_IsConstImm (L[1]) && L[2]->OPC == OP65_STA && L[2]->AM == L[0]->AM && strcmp (L[2]->Arg, L[0]->Arg) == 0 && diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index a7bd187ef..881605ecc 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -309,7 +309,7 @@ unsigned OptCmp1 (CodeSeg* S) strcmp (L[1]->Arg, "tmp1") == 0 && L[2]->OPC == OP65_ORA && strcmp (L[2]->Arg, "tmp1") == 0) { - + CodeEntry* X; /* Insert the ora instead */ @@ -335,7 +335,7 @@ unsigned OptCmp1 (CodeSeg* S) -unsigned OptCmp2 (CodeSeg* S) +unsigned OptCmp2 (CodeSeg* S) /* Search for the sequence * * stx xx @@ -432,8 +432,7 @@ unsigned OptCmp3 (CodeSeg* S) !CS_RangeHasLabel (S, I+1, 2) && CS_GetEntries (S, L+1, I+1, 2) && L[1]->OPC == OP65_CMP && - CE_KnownImm (L[1]) && - L[1]->Num == 0) { + CE_IsKnownImm (L[1], 0)) { /* Check for the call to boolxx. We only remove the compare if * the carry flag is evaluated later, because the load will not @@ -614,7 +613,7 @@ unsigned OptCmp5 (CodeSeg* S) /* Check for the sequence */ if (L[0]->OPC == OP65_LDY && - CE_KnownImm (L[0]) && + CE_IsConstImm (L[0]) && CS_GetEntries (S, L+1, I+1, 5) && !CE_HasLabel (L[1]) && CE_IsCallTo (L[1], "ldaxysp") && @@ -828,7 +827,7 @@ unsigned OptCmp8 (CodeSeg* S) /* Check for a compare against an immediate value */ if ((E->Info & OF_CMP) != 0 && (RegVal = GetCmpRegVal (E)) >= 0 && - CE_KnownImm (E)) { + CE_IsConstImm (E)) { /* We are able to evaluate the compare at compile time. Check if * one or more branches are ahead. diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index ff121749f..f4bdecbb1 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -841,8 +841,7 @@ unsigned OptDupLoads (CodeSeg* S) case OP65_LDA: if (RegValIsKnown (In->RegA) && /* Value of A is known */ - CE_KnownImm (E) && /* Value to be loaded is known */ - In->RegA == (long) E->Num && /* Both are equal */ + CE_IsKnownImm (E, In->RegA) && /* Value to be loaded is known */ (N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */ !CE_UseLoadFlags (N)) { /* Which does not use the flags */ Delete = 1; @@ -851,8 +850,7 @@ unsigned OptDupLoads (CodeSeg* S) case OP65_LDX: if (RegValIsKnown (In->RegX) && /* Value of X is known */ - CE_KnownImm (E) && /* Value to be loaded is known */ - In->RegX == (long) E->Num && /* Both are equal */ + CE_IsKnownImm (E, In->RegX) && /* Value to be loaded is known */ (N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */ !CE_UseLoadFlags (N)) { /* Which does not use the flags */ Delete = 1; @@ -861,8 +859,7 @@ unsigned OptDupLoads (CodeSeg* S) case OP65_LDY: if (RegValIsKnown (In->RegY) && /* Value of Y is known */ - CE_KnownImm (E) && /* Value to be loaded is known */ - In->RegY == (long) E->Num && /* Both are equal */ + CE_IsKnownImm (E, In->RegY) && /* Value to be loaded is known */ (N = CS_GetNextEntry (S, I)) != 0 && /* There is a next entry */ !CE_UseLoadFlags (N)) { /* Which does not use the flags */ Delete = 1; @@ -1354,7 +1351,7 @@ unsigned OptPrecalc (CodeSeg* S) break; case OP65_AND: - if (CE_KnownImm (E) && E->Num == 0xFF) { + if (CE_IsKnownImm (E, 0xFF)) { /* AND with 0xFF, remove */ CS_DelEntry (S, I); ++Changes; @@ -1365,7 +1362,7 @@ unsigned OptPrecalc (CodeSeg* S) break; case OP65_ORA: - if (CE_KnownImm (E) && E->Num == 0x00) { + if (CE_IsKnownImm (E, 0x00)) { /* ORA with zero, remove */ CS_DelEntry (S, I); ++Changes; diff --git a/src/cc65/coptneg.c b/src/cc65/coptneg.c index 86394d9a1..058b1ccba 100644 --- a/src/cc65/coptneg.c +++ b/src/cc65/coptneg.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -239,7 +239,7 @@ unsigned OptNegAX2 (CodeSeg* S) /* Check for the sequence */ if (L[0]->OPC == OP65_LDY && - CE_KnownImm (L[0]) && + CE_IsConstImm (L[0]) && !CS_RangeHasLabel (S, I+1, 3) && CS_GetEntries (S, L+1, I+1, 3) && CE_IsCallTo (L[1], "ldaxysp") && diff --git a/src/cc65/coptsize.c b/src/cc65/coptsize.c index d19b2e2fc..6e14c42f1 100644 --- a/src/cc65/coptsize.c +++ b/src/cc65/coptsize.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2002-2005, Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -289,7 +289,7 @@ unsigned OptSize2 (CodeSeg* S) switch (E->OPC) { case OP65_LDA: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { short Val = (short) E->Num; if (Val == In->RegX) { X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); @@ -306,7 +306,7 @@ unsigned OptSize2 (CodeSeg* S) break; case OP65_LDX: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { short Val = (short) E->Num; if (RegValIsKnown (In->RegX) && Val == ((In->RegX - 1) & 0xFF)) { X = NewCodeEntry (OP65_DEX, AM65_IMP, 0, 0, E->LI); @@ -319,7 +319,7 @@ unsigned OptSize2 (CodeSeg* S) break; case OP65_LDY: - if (CE_KnownImm (E)) { + if (CE_IsConstImm (E)) { short Val = (short) E->Num; if (RegValIsKnown (In->RegY) && Val == ((In->RegY - 1) & 0xFF)) { X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, E->LI); diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index f0751198d..c7a0e1f58 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -126,7 +126,7 @@ static unsigned AdjustStackOffset (CodeSeg* S, unsigned Start, unsigned Stop, * value. */ P = CS_GetPrevEntry (S, I); - if (P && P->OPC == OP65_LDY && CE_KnownImm (P)) { + if (P && P->OPC == OP65_LDY && CE_IsConstImm (P)) { /* The Y load is just before the stack access, adjust it */ CE_SetNumArg (P, P->Num - Offs); @@ -514,57 +514,115 @@ static unsigned Opt_tosaddax (StackOpData* D) /* Optimize the tosaddax sequence if possible */ { CodeEntry* X; - + CodeEntry* N; /* We need the entry behind the add */ CHECK (D->NextEntry != 0); - /* Check the entry before the push. If it's a lda instruction with an - * addressing mode that allows us to replace it, we may use this - * location for the op and must not save the value in the zero page - * location. + /* Check if the X register is known and zero when the add is done, and + * if the add is followed by + * + * ldy #$00 + * jsr ldauidx ; or ldaidx + * + * If this is true, the addition does actually add an offset to a pointer + * before it is dereferenced. Since both subroutines take an offset in Y, + * we can pass the offset (instead of #$00) and remove the addition + * alltogether. */ - CheckDirectOp (D); + if (D->OpEntry->RI->In.RegX == 0 && + D->NextEntry->OPC == OP65_LDY && + CE_IsKnownImm (D->NextEntry, 0) && + !CE_HasLabel (D->NextEntry) && + (N = CS_GetNextEntry (D->Code, D->OpIndex + 1)) != 0 && + (CE_IsCallTo (N, "ldauidx") || + CE_IsCallTo (N, "ldaidx"))) { - /* Store the value into the zeropage instead of pushing it */ - ReplacePushByStore (D); + int Signed = (strcmp (N->Arg, "ldaidx") == 0); - /* Inline the add */ - D->IP = D->OpIndex+1; - X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); + /* Store the value into the zeropage instead of pushing it */ + ReplacePushByStore (D); - /* Low byte */ - AddOpLow (D, OP65_ADC); + /* Replace the ldy by a tay. Be sure to create the new entry before + * deleting the ldy, since we will reference the line info from this + * insn. + */ + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, D->NextEntry->LI); + DelEntry (D, D->OpIndex + 1); + InsertEntry (D, X, D->OpIndex + 1); + + /* Replace the call to ldaidx/ldauidx. Since X is already zero, and + * the ptr is in the zero page location, we just need to load from + * the pointer, and fix X in case of ldaidx. + */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, D->ZPLo, 0, N->LI); + DelEntry (D, D->OpIndex + 2); + InsertEntry (D, X, D->OpIndex + 2); + if (Signed) { + + CodeLabel* L; + + /* Add sign extension - N is unused now */ + N = CS_GetNextEntry (D->Code, D->OpIndex + 2); + CHECK (N != 0); + L = CS_GenLabel (D->Code, N); + + X = NewCodeEntry (OP65_BPL, AM65_BRA, L->Name, L, X->LI); + InsertEntry (D, X, D->OpIndex + 3); + + X = NewCodeEntry (OP65_DEX, AM65_IMP, 0, 0, X->LI); + InsertEntry (D, X, D->OpIndex + 4); + } - /* High byte */ - if (D->PushEntry->RI->In.RegX == 0) { - /* The high byte is the value in X plus the carry */ - CodeLabel* L = CS_GenLabel (D->Code, D->NextEntry); - X = NewCodeEntry (OP65_BCC, AM65_BRA, L->Name, L, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - } else if (D->OpEntry->RI->In.RegX == 0) { - /* The high byte is that of the first operand plus carry */ - CodeLabel* L; - if (RegValIsKnown (D->PushEntry->RI->In.RegX)) { - /* Value of first op high byte is known */ - const char* Arg = MakeHexArg (D->PushEntry->RI->In.RegX); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI); - } else { - /* Value of first op high byte is unknown */ - X = NewCodeEntry (OP65_LDX, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); - } - InsertEntry (D, X, D->IP++); - L = CS_GenLabel (D->Code, D->NextEntry); - X = NewCodeEntry (OP65_BCC, AM65_BRA, L->Name, L, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); } else { - /* High byte is unknown */ - AddOpHigh (D, OP65_ADC); + + /* Check the entry before the push. If it's a lda instruction with an + * addressing mode that allows us to replace it, we may use this + * location for the op and must not save the value in the zero page + * location. + */ + CheckDirectOp (D); + + /* Store the value into the zeropage instead of pushing it */ + ReplacePushByStore (D); + + /* Inline the add */ + D->IP = D->OpIndex+1; + X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + /* Low byte */ + AddOpLow (D, OP65_ADC); + + /* High byte */ + if (D->PushEntry->RI->In.RegX == 0) { + /* The high byte is the value in X plus the carry */ + CodeLabel* L = CS_GenLabel (D->Code, D->NextEntry); + X = NewCodeEntry (OP65_BCC, AM65_BRA, L->Name, L, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + } else if (D->OpEntry->RI->In.RegX == 0) { + /* The high byte is that of the first operand plus carry */ + CodeLabel* L; + if (RegValIsKnown (D->PushEntry->RI->In.RegX)) { + /* Value of first op high byte is known */ + const char* Arg = MakeHexArg (D->PushEntry->RI->In.RegX); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, D->OpEntry->LI); + } else { + /* Value of first op high byte is unknown */ + X = NewCodeEntry (OP65_LDX, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); + } + InsertEntry (D, X, D->IP++); + L = CS_GenLabel (D->Code, D->NextEntry); + X = NewCodeEntry (OP65_BCC, AM65_BRA, L->Name, L, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + } else { + /* High byte is unknown */ + AddOpHigh (D, OP65_ADC); + } } /* Remove the push and the call to the tosaddax function */ diff --git a/src/cc65/coptstore.c b/src/cc65/coptstore.c index 6a4916be5..b738c38db 100644 --- a/src/cc65/coptstore.c +++ b/src/cc65/coptstore.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2002-2005, Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -79,14 +79,13 @@ unsigned OptStore1 (CodeSeg* S) /* Check for the sequence */ if (L[0]->OPC == OP65_LDY && - CE_KnownImm (L[0]) && + CE_IsConstImm (L[0]) && L[0]->Num < 0xFF && !CS_RangeHasLabel (S, I+1, 3) && CS_GetEntries (S, L+1, I+1, 4) && CE_IsCallTo (L[1], "staxysp") && L[2]->OPC == OP65_LDY && - CE_KnownImm (L[2]) && - L[2]->Num == L[0]->Num + 1 && + CE_IsKnownImm (L[2], L[0]->Num + 1) && CE_IsCallTo (L[3], "ldaxysp") && !CE_UseLoadFlags (L[4])) { -- 2.39.5