1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-05 21:29:03 +00:00

Replace staxspidx if possible

git-svn-id: svn://svn.cc65.org/cc65/trunk@1153 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2002-02-13 11:42:56 +00:00
parent 18b591e268
commit 164310971c

View File

@ -157,6 +157,55 @@ static unsigned Opt_staspidx (CodeSeg* S, unsigned Push, unsigned Store,
static unsigned Opt_staxspidx (CodeSeg* S, unsigned Push, unsigned Store,
const char* ZPLo, const char* ZPHi)
/* Optimize the staxspidx sequence if possible */
{
CodeEntry* X;
CodeEntry* PushEntry;
CodeEntry* StoreEntry;
/* Get the push entry */
PushEntry = CS_GetEntry (S, Push);
/* Store the value into the zeropage instead of pushing it */
X = NewCodeEntry (OP65_STA, AM65_ZP, ZPLo, 0, PushEntry->LI);
CS_InsertEntry (S, X, Push+1);
X = NewCodeEntry (OP65_STX, AM65_ZP, ZPHi, 0, PushEntry->LI);
CS_InsertEntry (S, X, Push+2);
/* Correct the index of the store and get a pointer to the entry */
Store += 2;
StoreEntry = CS_GetEntry (S, Store);
/* Inline the store */
X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, ZPLo, 0, StoreEntry->LI);
CS_InsertEntry (S, X, Store+1);
X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, StoreEntry->LI);
CS_InsertEntry (S, X, Store+2);
if (StoreEntry->RI->In.RegX >= 0) {
/* Value of X is known */
char Buf [16];
xsprintf (Buf, sizeof (Buf), "$%02X", StoreEntry->RI->In.RegX);
X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, StoreEntry->LI);
} else {
/* Value unknown */
X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, StoreEntry->LI);
}
CS_InsertEntry (S, X, Store+3);
X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, ZPLo, 0, StoreEntry->LI);
CS_InsertEntry (S, X, Store+4);
/* Remove the push and the call to the staspidx function */
CS_DelEntry (S, Store);
CS_DelEntry (S, Push);
/* We changed the sequence */
return 1;
}
static unsigned Opt_tosaddax (CodeSeg* S, unsigned Push, unsigned Add,
const char* ZPLo, const char* ZPHi)
/* Optimize the tosaddax sequence if possible */
@ -492,20 +541,29 @@ static unsigned Opt_tosxorax (CodeSeg* S, unsigned Push, unsigned Xor,
/* Flags for the functions */
typedef enum {
STOP_NONE, /* Nothing special */
STOP_A_UNUSED /* Call only if a unused later */
} STOP_FLAGS;
typedef unsigned (*OptFunc) (CodeSeg* S, unsigned Push, unsigned Store,
const char* ZPLo, const char* ZPHi);
const char* ZPLo, const char* ZPHi);
typedef struct OptFuncDesc OptFuncDesc;
struct OptFuncDesc {
const char* Name; /* Name of the replaced runtime function */
OptFunc Func; /* Function pointer */
const char* Name; /* Name of the replaced runtime function */
OptFunc Func; /* Function pointer */
STOP_FLAGS Flags; /* Flags */
};
static const OptFuncDesc FuncTable[] = {
{ "staspidx", Opt_staspidx },
{ "tosaddax", Opt_tosaddax },
{ "tosandax", Opt_tosandax },
{ "tosorax", Opt_tosorax },
{ "tosxorax", Opt_tosxorax },
{ "staspidx", Opt_staspidx, STOP_NONE },
{ "staxspidx", Opt_staxspidx, STOP_A_UNUSED },
{ "tosaddax", Opt_tosaddax, STOP_NONE },
{ "tosandax", Opt_tosandax, STOP_NONE },
{ "tosorax", Opt_tosorax, STOP_NONE },
{ "tosxorax", Opt_tosxorax, STOP_NONE },
};
#define FUNC_COUNT (sizeof(FuncTable) / sizeof(FuncTable[0]))
@ -586,28 +644,40 @@ unsigned OptStackOps (CodeSeg* S)
const OptFuncDesc* F = FindFunc (E->Arg);
if (F) {
/* Determine the register to use */
const char* ZPLo;
const char* ZPHi;
UsedRegs |= GetRegInfo (S, I+1, REG_SREG | REG_PTR1 | REG_PTR2);
if ((UsedRegs & REG_SREG) == REG_NONE) {
/* SREG is available */
ZPLo = "sreg";
ZPHi = "sreg+1";
} else if ((UsedRegs & REG_PTR1) == REG_NONE) {
ZPLo = "ptr1";
ZPHi = "ptr1+1";
} else if ((UsedRegs & REG_PTR2) == REG_NONE) {
ZPLo = "ptr2";
ZPHi = "ptr2+1";
} else {
/* No registers available */
ZPLo = 0;
ZPHi = 0;
}
const char* ZPLo = 0;
const char* ZPHi = 0;
int PreCondOk = 1;
/* If we have a register, call the optimizer function */
if (ZPLo && ZPHi) {
/* Check the flags */
if (F->Flags & STOP_A_UNUSED) {
/* a must be unused later */
if (RegAUsed (S, I+1)) {
/* Cannot optimize */
PreCondOk = 0;
}
}
/* Determine the zero page locations to use */
if (PreCondOk) {
UsedRegs |= GetRegInfo (S, I+1, REG_SREG | REG_PTR1 | REG_PTR2);
if ((UsedRegs & REG_SREG) == REG_NONE) {
/* SREG is available */
ZPLo = "sreg";
ZPHi = "sreg+1";
} else if ((UsedRegs & REG_PTR1) == REG_NONE) {
ZPLo = "ptr1";
ZPHi = "ptr1+1";
} else if ((UsedRegs & REG_PTR2) == REG_NONE) {
ZPLo = "ptr2";
ZPHi = "ptr2+1";
} else {
/* No registers available */
PreCondOk = 0;
}
}
/* If preconditions are ok, call the optimizer function */
if (PreCondOk) {
/* Adjust stack offsets */
unsigned Op = I + AdjustStackOffset (S, Push, I, 2);