Some function renaming.

Improved an optimization step.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3642 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2005-09-11 12:52:12 +00:00
parent b02ff264ad
commit c7490cf060
12 changed files with 199 additions and 133 deletions

View file

@ -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)) {

View file

@ -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)

View file

@ -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;

View file

@ -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 {

View file

@ -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) {

View file

@ -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 &&

View file

@ -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.

View file

@ -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;

View file

@ -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") &&

View file

@ -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);

View file

@ -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 */

View file

@ -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])) {