mirror of
https://github.com/cc65/cc65.git
synced 2024-12-23 19:29:37 +00:00
Tracking zero page locations
git-svn-id: svn://svn.cc65.org/cc65/trunk@1190 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
7639643144
commit
1118dd1237
@ -200,36 +200,27 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
|
||||
|
||||
|
||||
|
||||
static unsigned GetReg (unsigned short Use, const RegContents* RC)
|
||||
/* Map the register info in Use plus the validity into in RI into exactly
|
||||
* one register.
|
||||
*/
|
||||
{
|
||||
if ((Use & REG_A) != 0) {
|
||||
return (RC && RC->RegA >= 0)? REG_A : REG_NONE;
|
||||
} else if ((Use & REG_X) != 0) {
|
||||
return (RC && RC->RegX >= 0)? REG_X : REG_NONE;
|
||||
} else if ((Use & REG_Y) != 0) {
|
||||
return (RC && RC->RegY >= 0)? REG_Y : REG_NONE;
|
||||
} else if ((Use & REG_TMP1) != 0) {
|
||||
return (RC && RC->Tmp1 >= 0)? REG_TMP1 : REG_NONE;
|
||||
} else if ((Use & REG_SREG_LO) != 0) {
|
||||
return (RC && RC->SRegLo >= 0)? REG_SREG_LO : REG_NONE;
|
||||
} else if ((Use & REG_SREG_HI) != 0) {
|
||||
return (RC && RC->SRegHi >= 0)? REG_SREG_HI : REG_NONE;
|
||||
} else {
|
||||
return REG_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
const char* MakeHexArg (unsigned Num)
|
||||
/* Convert Num into a string in the form $XY, suitable for passing it as an
|
||||
* argument to NewCodeEntry, and return a pointer to the string.
|
||||
* BEWARE: The function returns a pointer to a static buffer, so the value is
|
||||
* gone if you call it twice (and apart from that it's not thread and signal
|
||||
* safe).
|
||||
*/
|
||||
{
|
||||
static char Buf[4];
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", (char) Num);
|
||||
return Buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg,
|
||||
CodeLabel* JumpTo, LineInfo* LI)
|
||||
/* Create a new code entry, initialize and return it */
|
||||
@ -430,7 +421,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (CE_KnownImm (E)) {
|
||||
Out->RegA = In->RegA & (short) E->Num;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Use, In)) {
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Out->RegA = In->RegA & In->Tmp1;
|
||||
break;
|
||||
@ -454,7 +445,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (E->AM == AM65_ACC && In->RegA >= 0) {
|
||||
Out->RegA = (In->RegA << 1) & 0xFF;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = (In->Tmp1 << 1) & 0xFF;
|
||||
break;
|
||||
@ -535,7 +526,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (E->AM == AM65_ACC && In->RegA >= 0) {
|
||||
Out->RegA = (In->RegA - 1) & 0xFF;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = (In->Tmp1 - 1) & 0xFF;
|
||||
break;
|
||||
@ -569,7 +560,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (CE_KnownImm (E)) {
|
||||
Out->RegA = In->RegA ^ (short) E->Num;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Use, In)) {
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Out->RegA = In->RegA ^ In->Tmp1;
|
||||
break;
|
||||
@ -599,7 +590,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (E->AM == AM65_ACC && In->RegA >= 0) {
|
||||
Out->RegA = (In->RegA + 1) & 0xFF;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = (In->Tmp1 + 1) & 0xFF;
|
||||
break;
|
||||
@ -682,7 +673,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (CE_KnownImm (E)) {
|
||||
Out->RegA = (unsigned char) E->Num;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Use, In)) {
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Out->RegA = In->Tmp1;
|
||||
break;
|
||||
@ -706,7 +697,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (CE_KnownImm (E)) {
|
||||
Out->RegX = (unsigned char) E->Num;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Use, In)) {
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Out->RegX = In->Tmp1;
|
||||
break;
|
||||
@ -730,7 +721,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (CE_KnownImm (E)) {
|
||||
Out->RegY = (unsigned char) E->Num;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Use, In)) {
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Out->RegY = In->Tmp1;
|
||||
break;
|
||||
@ -754,7 +745,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (E->AM == AM65_ACC && In->RegA >= 0) {
|
||||
Out->RegA = (In->RegA >> 1) & 0xFF;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = (In->Tmp1 >> 1) & 0xFF;
|
||||
break;
|
||||
@ -779,7 +770,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (CE_KnownImm (E)) {
|
||||
Out->RegA = In->RegA | (short) E->Num;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Use, In)) {
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Out->RegA = In->RegA | In->Tmp1;
|
||||
break;
|
||||
@ -832,7 +823,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (E->AM == AM65_ACC) {
|
||||
Out->RegA = -1;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = -1;
|
||||
break;
|
||||
@ -854,7 +845,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
if (E->AM == AM65_ACC) {
|
||||
Out->RegA = -1;
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = -1;
|
||||
break;
|
||||
@ -893,7 +884,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
|
||||
case OP65_STA:
|
||||
if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, 0)) {
|
||||
switch (GetKnownReg (E->Chg, 0)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = In->RegA;
|
||||
break;
|
||||
@ -912,7 +903,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
|
||||
case OP65_STX:
|
||||
if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, 0)) {
|
||||
switch (GetKnownReg (E->Chg, 0)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = In->RegX;
|
||||
break;
|
||||
@ -931,7 +922,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
|
||||
case OP65_STY:
|
||||
if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, 0)) {
|
||||
switch (GetKnownReg (E->Chg, 0)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = In->RegY;
|
||||
break;
|
||||
@ -950,7 +941,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
|
||||
case OP65_STZ:
|
||||
if (E->AM == AM65_ZP) {
|
||||
switch (GetReg (E->Chg, 0)) {
|
||||
switch (GetKnownReg (E->Chg, 0)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = 0;
|
||||
break;
|
||||
@ -981,7 +972,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
RC_InvalidateZP (Out);
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
if (In->RegA >= 0) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 &= ~In->RegA;
|
||||
break;
|
||||
@ -993,7 +984,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = -1;
|
||||
break;
|
||||
@ -1014,7 +1005,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
RC_InvalidateZP (Out);
|
||||
} else if (E->AM == AM65_ZP) {
|
||||
if (In->RegA >= 0) {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 |= In->RegA;
|
||||
break;
|
||||
@ -1026,7 +1017,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (GetReg (E->Chg, In)) {
|
||||
switch (GetKnownReg (E->Chg, In)) {
|
||||
case REG_TMP1:
|
||||
Out->Tmp1 = -1;
|
||||
break;
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@musoftware.de */
|
||||
@ -89,6 +89,14 @@ struct CodeEntry {
|
||||
|
||||
|
||||
|
||||
const char* MakeHexArg (unsigned Num);
|
||||
/* Convert Num into a string in the form $XY, suitable for passing it as an
|
||||
* argument to NewCodeEntry, and return a pointer to the string.
|
||||
* BEWARE: The function returns a pointer to a static buffer, so the value is
|
||||
* gone if you call it twice (and apart from that it's not thread and signal
|
||||
* safe).
|
||||
*/
|
||||
|
||||
CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg,
|
||||
CodeLabel* JumpTo, LineInfo* LI);
|
||||
/* Create a new code entry, initialize and return it */
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -44,6 +44,7 @@
|
||||
#include "codeseg.h"
|
||||
#include "datatype.h"
|
||||
#include "error.h"
|
||||
#include "reginfo.h"
|
||||
#include "symtab.h"
|
||||
#include "codeinfo.h"
|
||||
|
||||
@ -558,3 +559,28 @@ int RegAXUsed (struct CodeSeg* S, unsigned Index)
|
||||
|
||||
|
||||
|
||||
unsigned GetKnownReg (unsigned Use, const RegContents* RC)
|
||||
/* Return the register or zero page location from the set in Use, thats
|
||||
* contents are known. If Use does not contain any register, or if the
|
||||
* register in question does not have a known value, return REG_NONE.
|
||||
*/
|
||||
{
|
||||
if ((Use & REG_A) != 0) {
|
||||
return (RC && RC->RegA >= 0)? REG_A : REG_NONE;
|
||||
} else if ((Use & REG_X) != 0) {
|
||||
return (RC && RC->RegX >= 0)? REG_X : REG_NONE;
|
||||
} else if ((Use & REG_Y) != 0) {
|
||||
return (RC && RC->RegY >= 0)? REG_Y : REG_NONE;
|
||||
} else if ((Use & REG_TMP1) != 0) {
|
||||
return (RC && RC->Tmp1 >= 0)? REG_TMP1 : REG_NONE;
|
||||
} else if ((Use & REG_SREG_LO) != 0) {
|
||||
return (RC && RC->SRegLo >= 0)? REG_SREG_LO : REG_NONE;
|
||||
} else if ((Use & REG_SREG_HI) != 0) {
|
||||
return (RC && RC->SRegHi >= 0)? REG_SREG_HI : REG_NONE;
|
||||
} else {
|
||||
return REG_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -54,6 +54,9 @@ struct CodeSeg;
|
||||
|
||||
|
||||
|
||||
/* Forward to struct RegContents */
|
||||
struct RegContents;
|
||||
|
||||
/* Defines for registers. */
|
||||
#define REG_NONE 0x0000U
|
||||
#define REG_A 0x0001U
|
||||
@ -134,6 +137,12 @@ int RegYUsed (struct CodeSeg* S, unsigned Index);
|
||||
int RegAXUsed (struct CodeSeg* S, unsigned Index);
|
||||
/* Check if the value in A or(!) the value in X are used. */
|
||||
|
||||
unsigned GetKnownReg (unsigned Use, const struct RegContents* RC);
|
||||
/* Return the register or zero page location from the set in Use, thats
|
||||
* contents are known. If Use does not contain any register, or if the
|
||||
* register in question does not have a known value, return REG_NONE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* End of codeinfo.h */
|
||||
|
@ -962,9 +962,9 @@ static unsigned OptDecouple (CodeSeg* S)
|
||||
* txa -> lda #imm
|
||||
* tay -> ldy #imm
|
||||
* tya -> lda #imm
|
||||
* lda sreg -> lda #imm
|
||||
* ldx sreg -> ldx #imm
|
||||
* ldy sreg -> ldy #imm
|
||||
* lda zp -> lda #imm
|
||||
* ldx zp -> ldx #imm
|
||||
* ldy zp -> ldy #imm
|
||||
*
|
||||
* Provided that the register values are known of course.
|
||||
*/
|
||||
@ -979,10 +979,11 @@ static unsigned OptDecouple (CodeSeg* S)
|
||||
I = 0;
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
char Buf [16];
|
||||
const char* Arg;
|
||||
|
||||
/* Get next entry */
|
||||
/* Get next entry and it's input register values */
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
const RegContents* In = &E->RI->In;
|
||||
|
||||
/* Assume we have no replacement */
|
||||
CodeEntry* X = 0;
|
||||
@ -992,93 +993,120 @@ static unsigned OptDecouple (CodeSeg* S)
|
||||
|
||||
case OP65_DEX:
|
||||
if (E->RI->In.RegX >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", (E->RI->In.RegX - 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg ((E->RI->In.RegX - 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_DEY:
|
||||
if (E->RI->In.RegY >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", (E->RI->In.RegY - 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg ((E->RI->In.RegY - 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_INX:
|
||||
if (E->RI->In.RegX >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", (E->RI->In.RegX + 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg ((E->RI->In.RegX + 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_INY:
|
||||
if (E->RI->In.RegY >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", (E->RI->In.RegY + 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg ((E->RI->In.RegY + 1) & 0xFF);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_LDA:
|
||||
if (E->AM == AM65_ZP) {
|
||||
if ((E->Use & REG_SREG_LO) != 0 && E->RI->In.SRegLo >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.SRegLo);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, E->LI);
|
||||
} else if ((E->Use & REG_SREG_HI) != 0 && E->RI->In.SRegHi >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.SRegHi);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, E->LI);
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Arg = MakeHexArg (In->Tmp1);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
|
||||
case REG_SREG_LO:
|
||||
Arg = MakeHexArg (In->SRegLo);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
|
||||
case REG_SREG_HI:
|
||||
Arg = MakeHexArg (In->SRegHi);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_LDX:
|
||||
if (E->AM == AM65_ZP) {
|
||||
if ((E->Use & REG_SREG_LO) != 0 && E->RI->In.SRegLo >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.SRegLo);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Buf, 0, E->LI);
|
||||
} else if ((E->Use & REG_SREG_HI) != 0 && E->RI->In.SRegHi >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.SRegHi);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Buf, 0, E->LI);
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Arg = MakeHexArg (In->Tmp1);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
|
||||
case REG_SREG_LO:
|
||||
Arg = MakeHexArg (In->SRegLo);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
|
||||
case REG_SREG_HI:
|
||||
Arg = MakeHexArg (In->SRegHi);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_LDY:
|
||||
if (E->AM == AM65_ZP) {
|
||||
if ((E->Use & REG_SREG_LO) != 0 && E->RI->In.SRegLo >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.SRegLo);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, E->LI);
|
||||
} else if ((E->Use & REG_SREG_HI) != 0 && E->RI->In.SRegHi >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.SRegHi);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, E->LI);
|
||||
switch (GetKnownReg (E->Use, In)) {
|
||||
case REG_TMP1:
|
||||
Arg = MakeHexArg (In->Tmp1);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
|
||||
case REG_SREG_LO:
|
||||
Arg = MakeHexArg (In->SRegLo);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
|
||||
case REG_SREG_HI:
|
||||
Arg = MakeHexArg (In->SRegHi);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_TAX:
|
||||
if (E->RI->In.RegA >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.RegA);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg (In->RegA);
|
||||
X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_TAY:
|
||||
if (E->RI->In.RegA >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.RegA);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg (In->RegA);
|
||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_TXA:
|
||||
if (E->RI->In.RegX >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.RegX);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg (In->RegX);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_TYA:
|
||||
if (E->RI->In.RegY >= 0) {
|
||||
xsprintf (Buf, sizeof (Buf), "$%02X", E->RI->In.RegY);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, E->LI);
|
||||
Arg = MakeHexArg (In->RegY);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1210,6 +1238,14 @@ static unsigned OptSize1 (CodeSeg* S)
|
||||
/* Get next entry */
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's a subroutine call */
|
||||
if (E->OPC == OP65_JSR) {
|
||||
|
||||
/* Check for any of the known functions */
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Next entry */
|
||||
++I;
|
||||
@ -1623,7 +1659,13 @@ static void WriteOptStats (const char* Name)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write the file */
|
||||
/* Write a header */
|
||||
fprintf (F,
|
||||
"; Optimizer Total Last Total Last\n"
|
||||
"; Step Runs Runs Chg Chg\n");
|
||||
|
||||
|
||||
/* Write the data */
|
||||
for (I = 0; I < OPTFUNC_COUNT; ++I) {
|
||||
const OptFunc* O = OptFuncs[I];
|
||||
fprintf (F,
|
||||
|
@ -89,6 +89,28 @@ static int IsShortDist (int Distance)
|
||||
|
||||
|
||||
|
||||
static short RegVal (unsigned short Use, const RegContents* RC)
|
||||
/* Return the contents of the given register */
|
||||
{
|
||||
if ((Use & REG_A) != 0) {
|
||||
return RC->RegA;
|
||||
} else if ((Use & REG_X) != 0) {
|
||||
return RC->RegX;
|
||||
} else if ((Use & REG_Y) != 0) {
|
||||
return RC->RegY;
|
||||
} else if ((Use & REG_TMP1) != 0) {
|
||||
return RC->Tmp1;
|
||||
} else if ((Use & REG_SREG_LO) != 0) {
|
||||
return RC->SRegLo;
|
||||
} else if ((Use & REG_SREG_HI) != 0) {
|
||||
return RC->SRegHi;
|
||||
} else {
|
||||
return REG_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Replace jumps to RTS by RTS */
|
||||
/*****************************************************************************/
|
||||
@ -809,10 +831,8 @@ unsigned OptDupLoads (CodeSeg* S)
|
||||
*/
|
||||
if (In->RegA >= 0 && /* Value of A is known */
|
||||
E->AM == AM65_ZP && /* Store into zp */
|
||||
(((E->Chg & REG_SREG_LO) != 0 && /* Store into sreg */
|
||||
In->RegA == In->SRegLo) || /* Value identical */
|
||||
((E->Chg & REG_SREG_HI) != 0 && /* Store into sreg+1 */
|
||||
In->RegA == In->SRegHi))) { /* Value identical */
|
||||
In->RegA == RegVal (E->Chg, In)) { /* Value identical */
|
||||
|
||||
Delete = 1;
|
||||
}
|
||||
break;
|
||||
@ -824,10 +844,8 @@ unsigned OptDupLoads (CodeSeg* S)
|
||||
*/
|
||||
if (In->RegX >= 0 && /* Value of A is known */
|
||||
E->AM == AM65_ZP && /* Store into zp */
|
||||
(((E->Chg & REG_SREG_LO) != 0 && /* Store into sreg */
|
||||
In->RegX == In->SRegLo) || /* Value identical */
|
||||
((E->Chg & REG_SREG_HI) != 0 && /* Store into sreg+1 */
|
||||
In->RegX == In->SRegHi))) { /* Value identical */
|
||||
In->RegX == RegVal (E->Chg, In)) { /* Value identical */
|
||||
|
||||
Delete = 1;
|
||||
|
||||
/* If the value in the X register is known and the same as
|
||||
@ -852,11 +870,10 @@ unsigned OptDupLoads (CodeSeg* S)
|
||||
*/
|
||||
if (In->RegY >= 0 && /* Value of Y is known */
|
||||
E->AM == AM65_ZP && /* Store into zp */
|
||||
(((E->Chg & REG_SREG_LO) != 0 && /* Store into sreg */
|
||||
In->RegY == In->SRegLo) || /* Value identical */
|
||||
((E->Chg & REG_SREG_HI) != 0 && /* Store into sreg+1 */
|
||||
In->RegY == In->SRegHi))) { /* Value identical */
|
||||
In->RegX == RegVal (E->Chg, In)) { /* Value identical */
|
||||
|
||||
Delete = 1;
|
||||
|
||||
/* If the value in the Y register is known and the same as
|
||||
* that in the A register, replace the store by a STA. The
|
||||
* optimizer will then remove the load instruction for Y
|
||||
@ -881,8 +898,7 @@ unsigned OptDupLoads (CodeSeg* S)
|
||||
* remove the store.
|
||||
*/
|
||||
if (CPU >= CPU_65C02 && E->AM == AM65_ZP) {
|
||||
if (((E->Chg & REG_SREG_LO) != 0 && In->SRegLo == 0) ||
|
||||
((E->Chg & REG_SREG_HI) != 0 && In->SRegHi == 0)) {
|
||||
if (RegVal (E->Chg, In) == 0) {
|
||||
Delete = 1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user