1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Fixed processor states tracking for the BIT/TRB/TSB opcode.

Added new opcode descriptions about whether and how the opcode accesses memory.
This commit is contained in:
acqn 2020-09-08 23:41:02 +08:00 committed by Oliver Schmidt
parent 66c5faeb9a
commit 810e17edfe
3 changed files with 60 additions and 31 deletions

View File

@ -889,12 +889,38 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
Val = In->SRegHi; Val = In->SRegHi;
break; break;
} }
} else if (CE_IsConstImm (E)) {
/* 65C02 special */
Val = (short) E->Num;
}
/* BIT is unique with regards to the Z/V/N flags:
** - The Z is set/cleared according to whether the AND result is zero.
** - The V is coped directly from Bit 6 of the orginal argument.
** - The N is coped directly from Bit 7 of the orginal argument.
** Note the V/N flags are not affected in imm addressing mode supported by 65c02!
*/
if (E->AM == AM65_IMM) {
if (RegValIsKnown (Val)) {
Out->PFlags &= ~(UNKNOWN_PFVAL_V | UNKNOWN_PFVAL_N);
if (Val & PFVAL_V) {
Out->PFlags |= PFVAL_V;
} }
Out->PFlags &= ~UNKNOWN_PFVAL_V; Out->PFlags &= ~UNKNOWN_PFVAL_V;
if (Val & PFVAL_V) { if (Val & PFVAL_V) {
Out->PFlags |= PFVAL_V; Out->PFlags |= PFVAL_V;
} }
DeduceZN (Out, Val); } else {
Out->PFlags |= UNKNOWN_PFVAL_V | UNKNOWN_PFVAL_N;
}
}
if ((RegValIsKnown (Val) && RegValIsKnown (In->RegA))) {
Val &= In->RegA;
} else if (((RegValIsKnown (Val) && Val == 0) ||
(RegValIsKnown (In->RegA) && In->RegA == 0))) {
Val = 0;
}
DeduceZ (Out, Val);
break; break;
case OP65_BMI: case OP65_BMI:

View File

@ -63,21 +63,21 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_A, /* chg */ REG_A, /* chg */
OF_SETF /* flags */ OF_SETF | OF_READ /* flags */
}, },
{ OP65_AND, /* opcode */ { OP65_AND, /* opcode */
"and", /* mnemonic */ "and", /* mnemonic */
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_A, /* chg */ REG_A, /* chg */
OF_SETF /* flags */ OF_SETF | OF_READ /* flags */
}, },
{ OP65_ASL, /* opcode */ { OP65_ASL, /* opcode */
"asl", /* mnemonic */ "asl", /* mnemonic */
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_NOIMP /* flags */ OF_SETF | OF_NOIMP | OF_RMW /* flags */
}, },
{ OP65_BCC, /* opcode */ { OP65_BCC, /* opcode */
"bcc", /* mnemonic */ "bcc", /* mnemonic */
@ -105,7 +105,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF /* flags */ OF_READ /* flags */
}, },
{ OP65_BMI, /* opcode */ { OP65_BMI, /* opcode */
"bmi", /* mnemonic */ "bmi", /* mnemonic */
@ -189,21 +189,21 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_CMP /* flags */ OF_SETF | OF_CMP | OF_READ /* flags */
}, },
{ OP65_CPX, /* opcode */ { OP65_CPX, /* opcode */
"cpx", /* mnemonic */ "cpx", /* mnemonic */
0, /* size */ 0, /* size */
REG_X, /* use */ REG_X, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_CMP /* flags */ OF_SETF | OF_CMP | OF_READ /* flags */
}, },
{ OP65_CPY, /* opcode */ { OP65_CPY, /* opcode */
"cpy", /* mnemonic */ "cpy", /* mnemonic */
0, /* size */ 0, /* size */
REG_Y, /* use */ REG_Y, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_CMP /* flags */ OF_SETF | OF_CMP | OF_READ /* flags */
}, },
{ OP65_DEA, /* opcode */ { OP65_DEA, /* opcode */
"dea", /* mnemonic */ "dea", /* mnemonic */
@ -217,7 +217,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_NOIMP /* flags */ OF_SETF | OF_NOIMP | OF_RMW /* flags */
}, },
{ OP65_DEX, /* opcode */ { OP65_DEX, /* opcode */
"dex", /* mnemonic */ "dex", /* mnemonic */
@ -238,7 +238,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_A, /* chg */ REG_A, /* chg */
OF_SETF /* flags */ OF_SETF | OF_READ /* flags */
}, },
{ OP65_INA, /* opcode */ { OP65_INA, /* opcode */
"ina", /* mnemonic */ "ina", /* mnemonic */
@ -252,7 +252,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_NOIMP /* flags */ OF_SETF | OF_NOIMP | OF_RMW /* flags */
}, },
{ OP65_INX, /* opcode */ { OP65_INX, /* opcode */
"inx", /* mnemonic */ "inx", /* mnemonic */
@ -301,7 +301,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
3, /* size */ 3, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_UBRA | OF_LBRA /* flags */ OF_UBRA | OF_LBRA | OF_READ /* flags */
}, },
{ OP65_JNE, /* opcode */ { OP65_JNE, /* opcode */
"jne", /* mnemonic */ "jne", /* mnemonic */
@ -322,7 +322,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
3, /* size */ 3, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_CALL /* flags */ OF_CALL | OF_READ /* flags */
}, },
{ OP65_JVC, /* opcode */ { OP65_JVC, /* opcode */
"jvc", /* mnemonic */ "jvc", /* mnemonic */
@ -343,28 +343,28 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_A, /* chg */ REG_A, /* chg */
OF_LOAD | OF_SETF /* flags */ OF_LOAD | OF_SETF | OF_READ /* flags */
}, },
{ OP65_LDX, /* opcode */ { OP65_LDX, /* opcode */
"ldx", /* mnemonic */ "ldx", /* mnemonic */
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_X, /* chg */ REG_X, /* chg */
OF_LOAD | OF_SETF /* flags */ OF_LOAD | OF_SETF | OF_READ /* flags */
}, },
{ OP65_LDY, /* opcode */ { OP65_LDY, /* opcode */
"ldy", /* mnemonic */ "ldy", /* mnemonic */
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_Y, /* chg */ REG_Y, /* chg */
OF_LOAD | OF_SETF /* flags */ OF_LOAD | OF_SETF | OF_READ /* flags */
}, },
{ OP65_LSR, /* opcode */ { OP65_LSR, /* opcode */
"lsr", /* mnemonic */ "lsr", /* mnemonic */
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_NOIMP /* flags */ OF_SETF | OF_NOIMP | OF_RMW /* flags */
}, },
{ OP65_NOP, /* opcode */ { OP65_NOP, /* opcode */
"nop", /* mnemonic */ "nop", /* mnemonic */
@ -378,7 +378,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_A, /* chg */ REG_A, /* chg */
OF_SETF /* flags */ OF_SETF | OF_READ /* flags */
}, },
{ OP65_PHA, /* opcode */ { OP65_PHA, /* opcode */
"pha", /* mnemonic */ "pha", /* mnemonic */
@ -441,14 +441,14 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_NOIMP /* flags */ OF_SETF | OF_NOIMP | OF_RMW /* flags */
}, },
{ OP65_ROR, /* opcode */ { OP65_ROR, /* opcode */
"ror", /* mnemonic */ "ror", /* mnemonic */
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF | OF_NOIMP /* flags */ OF_SETF | OF_NOIMP | OF_RMW /* flags */
}, },
/* Mark RTI as "uses all registers but doesn't change them", so the /* Mark RTI as "uses all registers but doesn't change them", so the
** optimizer won't remove preceeding loads. ** optimizer won't remove preceeding loads.
@ -472,7 +472,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_A, /* chg */ REG_A, /* chg */
OF_SETF /* flags */ OF_SETF | OF_READ /* flags */
}, },
{ OP65_SEC, /* opcode */ { OP65_SEC, /* opcode */
"sec", /* mnemonic */ "sec", /* mnemonic */
@ -500,7 +500,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_STORE /* flags */ OF_STORE | OF_WRITE /* flags */
}, },
{ OP65_STP, /* opcode */ { OP65_STP, /* opcode */
"stp", /* mnemonic */ "stp", /* mnemonic */
@ -514,21 +514,21 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_X, /* use */ REG_X, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_STORE /* flags */ OF_STORE | OF_WRITE /* flags */
}, },
{ OP65_STY, /* opcode */ { OP65_STY, /* opcode */
"sty", /* mnemonic */ "sty", /* mnemonic */
0, /* size */ 0, /* size */
REG_Y, /* use */ REG_Y, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_STORE /* flags */ OF_STORE | OF_WRITE /* flags */
}, },
{ OP65_STZ, /* opcode */ { OP65_STZ, /* opcode */
"stz", /* mnemonic */ "stz", /* mnemonic */
0, /* size */ 0, /* size */
REG_NONE, /* use */ REG_NONE, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_STORE /* flags */ OF_STORE | OF_WRITE /* flags */
}, },
{ OP65_TAX, /* opcode */ { OP65_TAX, /* opcode */
"tax", /* mnemonic */ "tax", /* mnemonic */
@ -549,14 +549,14 @@ const OPCDesc OPCTable[OP65_COUNT] = {
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF /* flags */ OF_RMW /* flags */
}, },
{ OP65_TSB, /* opcode */ { OP65_TSB, /* opcode */
"tsb", /* mnemonic */ "tsb", /* mnemonic */
0, /* size */ 0, /* size */
REG_A, /* use */ REG_A, /* use */
REG_NONE, /* chg */ REG_NONE, /* chg */
OF_SETF /* flags */ OF_RMW /* flags */
}, },
{ OP65_TSX, /* opcode */ { OP65_TSX, /* opcode */
"tsx", /* mnemonic */ "tsx", /* mnemonic */

View File

@ -176,13 +176,16 @@ typedef enum {
#define OF_XFR 0x0100U /* Transfer instruction */ #define OF_XFR 0x0100U /* Transfer instruction */
#define OF_CALL 0x0200U /* A subroutine call */ #define OF_CALL 0x0200U /* A subroutine call */
#define OF_REG_INCDEC 0x0400U /* A register increment or decrement */ #define OF_REG_INCDEC 0x0400U /* A register increment or decrement */
#define OF_SETF 0x0800U /* Insn will set all load flags (not carry) */ #define OF_SETF 0x0800U /* Insn will set both Z and N flags according to the result */
#define OF_CMP 0x1000U /* A compare A/X/Y instruction */ #define OF_CMP 0x1000U /* A compare A/X/Y instruction */
#define OF_NOIMP 0x2000U /* Implicit addressing mode is actually A */ #define OF_NOIMP 0x2000U /* Implicit addressing mode is actually A */
#define OF_READ 0x4000U /* Read from the memory address */
#define OF_WRITE 0x8000U /* Write to the memory address */
/* Combined infos */ /* Combined infos */
#define OF_BRA (OF_UBRA | OF_CBRA) /* Operation is a jump/branch */ #define OF_BRA (OF_UBRA | OF_CBRA) /* Operation is a jump/branch */
#define OF_DEAD (OF_UBRA | OF_RET) /* Dead end - no exec behind this point */ #define OF_DEAD (OF_UBRA | OF_RET) /* Dead end - no exec behind this point */
#define OF_RMW (OF_READ | OF_WRITE) /* Read, Modify and Write */
/* Opcode description */ /* Opcode description */
typedef struct { typedef struct {