/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2001-2003 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* common */
#include "check.h"
+#include "cpu.h"
/* cc65 */
#include "codeinfo.h"
-#include "cpu.h"
#include "error.h"
#include "opcodes.h"
/* Opcode description table */
const OPCDesc OPCTable[OPCODE_COUNT] = {
- /* Opcodes for the virtual stack machine */
- { OPC_CALL, /* opcode */
- "call", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM | OF_CALL /* flags */
- },
- { OPC_ENTER, /* opcode */
- "enter", /* mnemonic */
- 1, /* size */
- REG_Y, /* use */
- REG_AXY, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_JMP, /* opcode */
- "jump", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM | OF_UBRA /* flags */
- },
- { OPC_LDA, /* opcode */
- "lda", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_A, /* chg */
- OF_CPU_VM | OF_LOAD /* flags */
- },
- { OPC_LDAX, /* opcode */
- "ldax", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_AX, /* chg */
- OF_CPU_VM | OF_LOAD /* flags */
- },
- { OPC_LDEAX, /* opcode */
- "ldeax", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_EAX, /* chg */
- OF_CPU_VM | OF_LOAD /* flags */
- },
- { OPC_LEA, /* opcode */
- "lea", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_AX, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_LEAVE, /* opcode */
- "leave", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_PHA, /* opcode */
- "pha", /* mnemonic */
- 1, /* size */
- REG_A, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_PHAX, /* opcode */
- "phax", /* mnemonic */
- 1, /* size */
- REG_AX, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_PHEAX, /* opcode */
- "pheax", /* mnemonic */
- 1, /* size */
- REG_EAX, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_RET, /* opcode */
- "ret", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM | OF_RET /* flags */
- },
- { OPC_SPACE, /* opcode */
- "space", /* mnemonic */
- 1, /* size */
- REG_NONE, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_STA, /* opcode */
- "sta", /* mnemonic */
- 1, /* size */
- REG_A, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_STAX, /* opcode */
- "stax", /* mnemonic */
- 1, /* size */
- REG_AX, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
- { OPC_STEAX, /* opcode */
- "steax", /* mnemonic */
- 1, /* size */
- REG_EAX, /* use */
- REG_NONE, /* chg */
- OF_CPU_VM /* flags */
- },
-
/* 65XX opcodes */
{ OP65_ADC, /* opcode */
"adc", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_AND, /* opcode */
"and", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_ASL, /* opcode */
"asl", /* mnemonic */
0, /* size */
- REG_A, /* use */
- REG_A, /* chg */
- OF_NONE /* flags */
+ REG_NONE, /* use */
+ REG_NONE, /* chg */
+ OF_SETF /* flags */
},
{ OP65_BCC, /* opcode */
"bcc", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_BMI, /* opcode */
"bmi", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF | OF_CMP /* flags */
},
{ OP65_CPX, /* opcode */
"cpx", /* mnemonic */
0, /* size */
REG_X, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF | OF_CMP /* flags */
},
{ OP65_CPY, /* opcode */
"cpy", /* mnemonic */
0, /* size */
REG_Y, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF | OF_CMP /* flags */
},
{ OP65_DEA, /* opcode */
"dea", /* mnemonic */
1, /* size */
REG_A, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_REG_INCDEC | OF_SETF /* flags */
},
{ OP65_DEC, /* opcode */
"dec", /* mnemonic */
0, /* size */
REG_NONE, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_DEX, /* opcode */
"dex", /* mnemonic */
1, /* size */
REG_X, /* use */
REG_X, /* chg */
- OF_NONE /* flags */
+ OF_REG_INCDEC | OF_SETF /* flags */
},
{ OP65_DEY, /* opcode */
"dey", /* mnemonic */
1, /* size */
REG_Y, /* use */
REG_Y, /* chg */
- OF_NONE /* flags */
+ OF_REG_INCDEC | OF_SETF /* flags */
},
{ OP65_EOR, /* opcode */
"eor", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_INA, /* opcode */
"ina", /* mnemonic */
1, /* size */
REG_A, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_REG_INCDEC | OF_SETF /* flags */
},
{ OP65_INC, /* opcode */
"inc", /* mnemonic */
0, /* size */
REG_NONE, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_INX, /* opcode */
"inx", /* mnemonic */
1, /* size */
REG_X, /* use */
REG_X, /* chg */
- OF_NONE /* flags */
+ OF_REG_INCDEC | OF_SETF /* flags */
},
{ OP65_INY, /* opcode */
"iny", /* mnemonic */
1, /* size */
REG_Y, /* use */
REG_Y, /* chg */
- OF_NONE /* flags */
+ OF_REG_INCDEC | OF_SETF /* flags */
},
{ OP65_JCC, /* opcode */
"jcc", /* mnemonic */
0, /* size */
REG_NONE, /* use */
REG_A, /* chg */
- OF_LOAD /* flags */
+ OF_LOAD | OF_SETF /* flags */
},
{ OP65_LDX, /* opcode */
"ldx", /* mnemonic */
0, /* size */
REG_NONE, /* use */
REG_X, /* chg */
- OF_LOAD /* flags */
+ OF_LOAD | OF_SETF /* flags */
},
{ OP65_LDY, /* opcode */
"ldy", /* mnemonic */
0, /* size */
REG_NONE, /* use */
REG_Y, /* chg */
- OF_LOAD /* flags */
+ OF_LOAD | OF_SETF /* flags */
},
{ OP65_LSR, /* opcode */
"lsr", /* mnemonic */
0, /* size */
- REG_A, /* use */
- REG_A, /* chg */
- OF_NONE /* flags */
+ REG_NONE, /* use */
+ REG_NONE, /* chg */
+ OF_SETF /* flags */
},
{ OP65_NOP, /* opcode */
"nop", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_PHA, /* opcode */
"pha", /* mnemonic */
1, /* size */
REG_Y, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_NONE /* flags */
},
{ OP65_PLA, /* opcode */
"pla", /* mnemonic */
1, /* size */
REG_NONE, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_PLP, /* opcode */
"plp", /* mnemonic */
1, /* size */
REG_NONE, /* use */
REG_X, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_PLY, /* opcode */
"ply", /* mnemonic */
1, /* size */
REG_NONE, /* use */
REG_Y, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_ROL, /* opcode */
"rol", /* mnemonic */
0, /* size */
- REG_A, /* use */
- REG_A, /* chg */
- OF_NONE /* flags */
+ REG_NONE, /* use */
+ REG_NONE, /* chg */
+ OF_SETF /* flags */
},
{ OP65_ROR, /* opcode */
"ror", /* mnemonic */
0, /* size */
- REG_A, /* use */
- REG_A, /* chg */
- OF_NONE /* flags */
+ REG_NONE, /* use */
+ REG_NONE, /* chg */
+ OF_SETF /* flags */
},
+ /* Mark RTI as "uses all registers but doesn't change them", so the
+ * optimizer won't remove preceeding loads.
+ */
{ OP65_RTI, /* opcode */
"rti", /* mnemonic */
1, /* size */
- REG_NONE, /* use */
+ REG_AXY, /* use */
REG_NONE, /* chg */
- OF_RET /* flags */
+ OF_RET /* flags */
},
{ OP65_RTS, /* opcode */
"rts", /* mnemonic */
1, /* size */
REG_NONE, /* use */
REG_NONE, /* chg */
- OF_RET /* flags */
+ OF_RET /* flags */
},
{ OP65_SBC, /* opcode */
"sbc", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_A, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_SEC, /* opcode */
"sec", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_STORE /* flags */
},
{ OP65_STX, /* opcode */
"stx", /* mnemonic */
0, /* size */
REG_X, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_STORE /* flags */
},
{ OP65_STY, /* opcode */
"sty", /* mnemonic */
0, /* size */
REG_Y, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ 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 */
REG_A, /* use */
REG_X, /* chg */
- OF_XFR /* flags */
+ OF_XFR | OF_SETF /* flags */
},
{ OP65_TAY, /* opcode */
"tay", /* mnemonic */
1, /* size */
REG_A, /* use */
REG_Y, /* chg */
- OF_XFR /* flags */
+ OF_XFR | OF_SETF /* flags */
},
{ OP65_TRB, /* opcode */
"trb", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_TSB, /* opcode */
"tsb", /* mnemonic */
0, /* size */
REG_A, /* use */
REG_NONE, /* chg */
- OF_NONE /* flags */
+ OF_SETF /* flags */
},
{ OP65_TSX, /* opcode */
"tsx", /* mnemonic */
1, /* size */
REG_NONE, /* use */
REG_X, /* chg */
- OF_XFR /* flags */
+ OF_XFR | OF_SETF /* flags */
},
{ OP65_TXA, /* opcode */
"txa", /* mnemonic */
1, /* size */
REG_X, /* use */
REG_A, /* chg */
- OF_XFR /* flags */
+ OF_XFR | OF_SETF /* flags */
},
{ OP65_TXS, /* opcode */
"txs", /* mnemonic */
{ OP65_TYA, /* opcode */
"tya", /* mnemonic */
1, /* size */
- REG_A, /* use */
+ REG_Y, /* use */
REG_A, /* chg */
- OF_XFR /* flags */
+ OF_XFR | OF_SETF /* flags */
},
};
case OP65_BMI: return OP65_BPL;
case OP65_BNE: return OP65_BEQ;
case OP65_BPL: return OP65_BMI;
- case OP65_BVC: return OP65_BVS;
+ case OP65_BVC: return OP65_BVS;
case OP65_BVS: return OP65_BVC;
- case OP65_JCC: return OP65_JCS;
- case OP65_JCS: return OP65_JCC;
- case OP65_JEQ: return OP65_JNE;
- case OP65_JMI: return OP65_JPL;
- case OP65_JNE: return OP65_JEQ;
- case OP65_JPL: return OP65_JMI;
- case OP65_JVC: return OP65_JVS;
- case OP65_JVS: return OP65_JVC;
+ case OP65_JCC: return OP65_JCS;
+ case OP65_JCS: return OP65_JCC;
+ case OP65_JEQ: return OP65_JNE;
+ case OP65_JMI: return OP65_JPL;
+ case OP65_JNE: return OP65_JEQ;
+ case OP65_JPL: return OP65_JMI;
+ case OP65_JVC: return OP65_JVS;
+ case OP65_JVS: return OP65_JVC;
default:
Internal ("GetInverseBranch: Invalid opcode: %d", OPC);
return 0;
{
switch (OPC) {
case OP65_BCC:
- case OP65_JCC: return OP65_BCC;
+ case OP65_JCC: return OP65_BCC;
case OP65_BCS:
- case OP65_JCS: return OP65_BCS;
+ case OP65_JCS: return OP65_BCS;
case OP65_BEQ:
- case OP65_JEQ: return OP65_BEQ;
+ case OP65_JEQ: return OP65_BEQ;
case OP65_BMI:
- case OP65_JMI: return OP65_BMI;
+ case OP65_JMI: return OP65_BMI;
case OP65_BNE:
- case OP65_JNE: return OP65_BNE;
+ case OP65_JNE: return OP65_BNE;
case OP65_BPL:
- case OP65_JPL: return OP65_BPL;
+ case OP65_JPL: return OP65_BPL;
case OP65_BVC:
- case OP65_JVC: return OP65_BVC;
+ case OP65_JVC: return OP65_BVC;
case OP65_BVS:
- case OP65_JVS: return OP65_BVS;
+ case OP65_JVS: return OP65_BVS;
case OP65_BRA:
- case OP65_JMP: return (CPU == CPU_65C02)? OP65_BRA : OP65_JMP;
+ case OP65_JMP: return (CPUIsets[CPU] & CPU_ISET_65SC02)? OP65_BRA : OP65_JMP;
default:
Internal ("MakeShortBranch: Invalid opcode: %d", OPC);
return 0;
{
switch (OPC) {
case OP65_BCC:
- case OP65_JCC: return OP65_JCC;
+ case OP65_JCC: return OP65_JCC;
case OP65_BCS:
- case OP65_JCS: return OP65_JCS;
+ case OP65_JCS: return OP65_JCS;
case OP65_BEQ:
- case OP65_JEQ: return OP65_JEQ;
+ case OP65_JEQ: return OP65_JEQ;
case OP65_BMI:
- case OP65_JMI: return OP65_JMI;
+ case OP65_JMI: return OP65_JMI;
case OP65_BNE:
- case OP65_JNE: return OP65_JNE;
+ case OP65_JNE: return OP65_JNE;
case OP65_BPL:
- case OP65_JPL: return OP65_JPL;
+ case OP65_JPL: return OP65_JPL;
case OP65_BVC:
- case OP65_JVC: return OP65_JVC;
+ case OP65_JVC: return OP65_JVC;
case OP65_BVS:
- case OP65_JVS: return OP65_JVS;
+ case OP65_JVS: return OP65_JVS;
case OP65_BRA:
- case OP65_JMP: return OP65_JMP;
+ case OP65_JMP: return OP65_JMP;
default:
Internal ("MakeLongBranch: Invalid opcode: %d", OPC);
return 0;
/* Get the condition for the conditional branch in OPC */
{
switch (OPC) {
- case OP65_BCC: return BC_CC;
- case OP65_BCS: return BC_CS;
- case OP65_BEQ: return BC_EQ;
- case OP65_BMI: return BC_MI;
- case OP65_BNE: return BC_NE;
- case OP65_BPL: return BC_PL;
- case OP65_BVC: return BC_VC;
- case OP65_BVS: return BC_VS;
- case OP65_JCC: return BC_CC;
- case OP65_JCS: return BC_CS;
- case OP65_JEQ: return BC_EQ;
- case OP65_JMI: return BC_MI;
- case OP65_JNE: return BC_NE;
- case OP65_JPL: return BC_PL;
- case OP65_JVC: return BC_VC;
- case OP65_JVS: return BC_VS;
+ case OP65_BCC: return BC_CC;
+ case OP65_BCS: return BC_CS;
+ case OP65_BEQ: return BC_EQ;
+ case OP65_BMI: return BC_MI;
+ case OP65_BNE: return BC_NE;
+ case OP65_BPL: return BC_PL;
+ case OP65_BVC: return BC_VC;
+ case OP65_BVS: return BC_VS;
+ case OP65_JCC: return BC_CC;
+ case OP65_JCS: return BC_CS;
+ case OP65_JEQ: return BC_EQ;
+ case OP65_JMI: return BC_MI;
+ case OP65_JNE: return BC_NE;
+ case OP65_JPL: return BC_PL;
+ case OP65_JVC: return BC_VC;
+ case OP65_JVS: return BC_VS;
default:
Internal ("GetBranchCond: Invalid opcode: %d", OPC);
return 0;
+