First support for STZ
git-svn-id: svn://svn.cc65.org/cc65/trunk@1187 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
d814a9a6fb
commit
f38852df82
9 changed files with 170 additions and 45 deletions
|
@ -6,7 +6,7 @@
|
|||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@musoftware.de */
|
||||
|
@ -420,6 +420,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if ((E->Chg & REG_SREG_HI) != 0 && In->SRegHi >= 0) {
|
||||
Out->SRegHi = (In->SRegHi << 1) & 0xFF;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -492,6 +495,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if ((E->Chg & REG_SREG_HI) != 0 && In->SRegHi >= 0) {
|
||||
Out->SRegHi = (In->SRegHi - 1) & 0xFF;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -532,6 +538,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if ((E->Chg & REG_SREG_HI) != 0 && In->SRegHi >= 0) {
|
||||
Out->SRegHi = (In->SRegHi + 1) & 0xFF;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -654,6 +663,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if (E->Chg & REG_SREG_HI) {
|
||||
Out->SRegHi = (In->SRegHi >> 1) & 0xFF;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -707,6 +719,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if (E->Chg & REG_SREG_HI) {
|
||||
Out->SRegHi = -1;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -719,6 +734,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if (E->Chg & REG_SREG_HI) {
|
||||
Out->SRegHi = -1;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -749,6 +767,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if (E->Chg & REG_SREG_HI) {
|
||||
Out->SRegHi = In->RegA;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -759,6 +780,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if (E->Chg & REG_SREG_HI) {
|
||||
Out->SRegHi = In->RegX;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -769,6 +793,22 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||
} else if (E->Chg & REG_SREG_HI) {
|
||||
Out->SRegHi = In->RegY;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_STZ:
|
||||
if (E->AM == AM65_ZP) {
|
||||
if (E->Chg & REG_SREG_LO) {
|
||||
Out->SRegLo = 0;
|
||||
} else if (E->Chg & REG_SREG_HI) {
|
||||
Out->SRegHi = 0;
|
||||
}
|
||||
} else if (E->AM == AM65_ZPX) {
|
||||
/* Invalidates all ZP registers */
|
||||
RC_InvalidateZP (Out);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1351,6 +1351,7 @@ struct OptFunc {
|
|||
/* A list of all the function descriptions */
|
||||
static OptFunc DOpt65C02BitOps = { Opt65C02BitOps, "Opt65C02BitOps", 66, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOpt65C02Stores = { Opt65C02Stores, "Opt65C02Stores", 100, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd1 = { OptAdd1, "OptAdd1", 60, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd2 = { OptAdd2, "OptAdd2", 200, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd3 = { OptAdd3, "OptAdd3", 40, 0, 0, 0, 0, 0 };
|
||||
|
@ -1406,6 +1407,7 @@ static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0,
|
|||
static OptFunc* OptFuncs[] = {
|
||||
&DOpt65C02BitOps,
|
||||
&DOpt65C02Ind,
|
||||
&DOpt65C02Stores,
|
||||
&DOptAdd1,
|
||||
&DOptAdd2,
|
||||
&DOptAdd3,
|
||||
|
@ -1775,17 +1777,17 @@ static unsigned RunOptGroup3 (CodeSeg* S)
|
|||
static unsigned RunOptGroup4 (CodeSeg* S)
|
||||
/* 65C02 specific optimizations. */
|
||||
{
|
||||
unsigned C;
|
||||
unsigned Changes = 0;
|
||||
|
||||
if (CPU >= CPU_65C02) {
|
||||
Changes += RunOptFunc (S, &DOpt65C02BitOps, 1);
|
||||
/* Replace (zp),y by (zp) if Y is zero. If we have changes, run register
|
||||
* load optimization again, since loads of Y may have become unnecessary.
|
||||
Changes += RunOptFunc (S, &DOpt65C02Ind, 1);
|
||||
Changes += RunOptFunc (S, &DOpt65C02Stores, 1);
|
||||
if (Changes) {
|
||||
/* The 65C02 replacement codes do often make the use of a register
|
||||
* value unnecessary, so if we have changes, run another load
|
||||
* removal pass.
|
||||
*/
|
||||
C = RunOptFunc (S, &DOpt65C02Ind, 1);
|
||||
Changes += C;
|
||||
if (C) {
|
||||
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,26 +146,73 @@ unsigned Opt65C02BitOps (CodeSeg* S)
|
|||
/* LDA #XX */
|
||||
sprintf (Buf, "$%02X", (int) ((~L[1]->Num) & 0xFF));
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, L[1]->LI);
|
||||
CS_InsertEntry (S, X, I);
|
||||
CS_InsertEntry (S, X, I+3);
|
||||
|
||||
/* TRB */
|
||||
X = NewCodeEntry (OP65_TRB, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
CS_InsertEntry (S, X, I+4);
|
||||
|
||||
} else {
|
||||
|
||||
/* LDA #XX */
|
||||
sprintf (Buf, "$%02X", (int) L[1]->Num);
|
||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Buf, 0, L[1]->LI);
|
||||
CS_InsertEntry (S, X, I);
|
||||
CS_InsertEntry (S, X, I+3);
|
||||
|
||||
/* TRB */
|
||||
/* TSB */
|
||||
X = NewCodeEntry (OP65_TSB, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
CS_InsertEntry (S, X, I+4);
|
||||
}
|
||||
|
||||
/* Delete the old stuff */
|
||||
CS_DelEntries (S, I+2, 3);
|
||||
CS_DelEntries (S, I, 3);
|
||||
|
||||
/* We had changes */
|
||||
++Changes;
|
||||
}
|
||||
|
||||
/* Next entry */
|
||||
++I;
|
||||
|
||||
}
|
||||
|
||||
/* Free register info */
|
||||
CS_FreeRegInfo (S);
|
||||
|
||||
/* Return the number of changes made */
|
||||
return Changes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned Opt65C02Stores (CodeSeg* S)
|
||||
/* Use STZ where possible */
|
||||
{
|
||||
unsigned Changes = 0;
|
||||
unsigned I;
|
||||
|
||||
/* Generate register info for this step */
|
||||
CS_GenRegInfo (S);
|
||||
|
||||
/* Walk over the entries */
|
||||
I = 0;
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_STA &&
|
||||
(E->AM == AM65_ZP || E->AM == AM65_ABS ||
|
||||
E->AM == AM65_ZPX || E->AM == AM65_ABSX ) &&
|
||||
E->RI->In.RegA == 0) {
|
||||
|
||||
/* Replace by STZ */
|
||||
CodeEntry* X = NewCodeEntry (OP65_STZ, E->AM, E->Arg, 0, E->LI);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
|
||||
/* Delete the old stuff */
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* We had changes */
|
||||
++Changes;
|
||||
|
|
|
@ -55,6 +55,9 @@ unsigned Opt65C02Ind (CodeSeg* S);
|
|||
unsigned Opt65C02BitOps (CodeSeg* S);
|
||||
/* Use special bit op instructions of the C02 */
|
||||
|
||||
unsigned Opt65C02Stores (CodeSeg* S);
|
||||
/* Use STZ where possible */
|
||||
|
||||
|
||||
|
||||
/* End of coptc02.h */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
|
@ -850,12 +850,12 @@ unsigned OptDupLoads (CodeSeg* S)
|
|||
* location does already contain the value to be stored,
|
||||
* remove the store.
|
||||
*/
|
||||
if (In->RegX >= 0 && /* Value of A is known */
|
||||
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->RegX == In->SRegLo) || /* Value identical */
|
||||
In->RegY == In->SRegLo) || /* Value identical */
|
||||
((E->Chg & REG_SREG_HI) != 0 && /* Store into sreg+1 */
|
||||
In->RegX == In->SRegHi))) { /* Value identical */
|
||||
In->RegY == In->SRegHi))) { /* 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
|
||||
|
@ -875,6 +875,19 @@ unsigned OptDupLoads (CodeSeg* S)
|
|||
}
|
||||
break;
|
||||
|
||||
case OP65_STZ:
|
||||
/* If we store into a known zero page location, and this
|
||||
* location does already contain the value to be stored,
|
||||
* 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)) {
|
||||
Delete = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP65_TAX:
|
||||
if (In->RegA >= 0 &&
|
||||
In->RegA == In->RegX &&
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
|
@ -513,6 +513,13 @@ const OPCDesc OPCTable[OPCODE_COUNT] = {
|
|||
REG_NONE, /* chg */
|
||||
OF_STORE /* flags */
|
||||
},
|
||||
{ OP65_STZ, /* opcode */
|
||||
"stz", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_NONE, /* use */
|
||||
REG_NONE, /* chg */
|
||||
OF_STORE /* flags */
|
||||
},
|
||||
{ OP65_TAX, /* opcode */
|
||||
"tax", /* mnemonic */
|
||||
1, /* size */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
|
@ -118,6 +118,7 @@ typedef enum {
|
|||
OP65_STA,
|
||||
OP65_STX,
|
||||
OP65_STY,
|
||||
OP65_STZ,
|
||||
OP65_TAX,
|
||||
OP65_TAY,
|
||||
OP65_TRB,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
|
@ -59,6 +59,15 @@ void RC_Invalidate (RegContents* C)
|
|||
|
||||
|
||||
|
||||
void RC_InvalidateZP (RegContents* C)
|
||||
/* Invalidate all ZP registers */
|
||||
{
|
||||
C->SRegLo = -1;
|
||||
C->SRegHi = -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RegInfo* NewRegInfo (const RegContents* RC)
|
||||
/* Allocate a new register info, initialize and return it. If RC is not
|
||||
* a NULL pointer, it is used to initialize both, the input and output
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
|
@ -78,6 +78,9 @@ struct RegInfo {
|
|||
void RC_Invalidate (RegContents* C);
|
||||
/* Invalidate all registers */
|
||||
|
||||
void RC_InvalidateZP (RegContents* C);
|
||||
/* Invalidate all ZP registers */
|
||||
|
||||
RegInfo* NewRegInfo (const RegContents* RC);
|
||||
/* Allocate a new register info, initialize and return it. If RC is not
|
||||
* a NULL pointer, it is used to initialize both, the input and output
|
||||
|
|
Loading…
Add table
Reference in a new issue