X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fopcodes.c;h=2c838a695f6c5038092dad89ccb85d6fc17dfe44;hb=57c2e0cc0bcda3d08692abc60f5c85510801801d;hp=c6d9b35f55f933713a49201a929aebe8f17f68ab;hpb=a9674c071ac8686a78423b429e39f0e41c247484;p=cc65 diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index c6d9b35f5..2c838a695 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2001-2004 Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -39,10 +39,10 @@ /* common */ #include "check.h" +#include "cpu.h" /* cc65 */ #include "codeinfo.h" -#include "cpu.h" #include "error.h" #include "opcodes.h" @@ -55,86 +55,7 @@ /* Opcode description table */ -const OPCDesc OPCTable[OPCODE_COUNT] = { - - /* Opcodes for the virtual stack machine */ - { OPC_LDA, /* opcode */ - "loada", /* mnemonic */ - 0, /* size */ - REG_NONE, /* use */ - REG_A, /* chg */ - OF_CPU_VM | OF_LOAD /* flags */ - }, - { OPC_LDAX, /* opcode */ - "loadax", /* mnemonic */ - 0, /* size */ - REG_NONE, /* use */ - REG_AX, /* chg */ - OF_CPU_VM | OF_LOAD /* flags */ - }, - { OPC_LDEAX, /* opcode */ - "loadeax", /* mnemonic */ - 0, /* size */ - REG_NONE, /* use */ - REG_EAX, /* chg */ - OF_CPU_VM | OF_LOAD /* flags */ - }, - { OPC_PHA, /* opcode */ - "pusha", /* mnemonic */ - 0, /* size */ - REG_A, /* use */ - REG_NONE, /* chg */ - OF_CPU_VM /* flags */ - }, - { OPC_PHAX, /* opcode */ - "pushax", /* mnemonic */ - 0, /* size */ - REG_AX, /* use */ - REG_NONE, /* chg */ - OF_CPU_VM /* flags */ - }, - { OPC_PHEAX, /* opcode */ - "pusheax", /* mnemonic */ - 0, /* size */ - REG_EAX, /* use */ - REG_NONE, /* chg */ - OF_CPU_VM /* flags */ - }, - { OPC_STA, /* opcode */ - "storea", /* mnemonic */ - 0, /* size */ - REG_A, /* use */ - REG_NONE, /* chg */ - OF_CPU_VM /* flags */ - }, - { OPC_STAX, /* opcode */ - "storeax", /* mnemonic */ - 0, /* size */ - REG_AX, /* use */ - REG_NONE, /* chg */ - OF_CPU_VM /* flags */ - }, - { OPC_STEAX, /* opcode */ - "storeeax", /* mnemonic */ - 0, /* size */ - REG_EAX, /* use */ - REG_NONE, /* chg */ - OF_CPU_VM /* flags */ - }, - { OPC_LEA, /* opcode */ - "lea", /* mnemonic */ - 0, /* size */ - REG_NONE, /* use */ - REG_AX, /* chg */ - OF_CPU_VM /* flags */ - }, - { OPC_JMP, /* opcode */ - "jump", /* mnemonic */ - 0, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CPU_VM | OF_UBRA /* flags */ - }, +const OPCDesc OPCTable[OP65_COUNT] = { /* 65XX opcodes */ { OP65_ADC, /* opcode */ @@ -142,21 +63,21 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 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 | OF_NOIMP /* flags */ }, { OP65_BCC, /* opcode */ "bcc", /* mnemonic */ @@ -184,7 +105,7 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 0, /* size */ REG_A, /* use */ REG_NONE, /* chg */ - OF_NONE /* flags */ + OF_SETF /* flags */ }, { OP65_BMI, /* opcode */ "bmi", /* mnemonic */ @@ -233,7 +154,7 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 2, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_CBRA /* flags */ + OF_CBRA /* flags */ }, { OP65_CLC, /* opcode */ "clc", /* mnemonic */ @@ -268,84 +189,84 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 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 | OF_NOIMP /* 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 | OF_NOIMP /* 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 */ @@ -408,7 +329,7 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 5, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_CBRA | OF_LBRA /* flags */ + OF_CBRA | OF_LBRA /* flags */ }, { OP65_JVS, /* opcode */ "jvs", /* mnemonic */ @@ -422,28 +343,28 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 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 | OF_NOIMP /* flags */ }, { OP65_NOP, /* opcode */ "nop", /* mnemonic */ @@ -457,7 +378,7 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 0, /* size */ REG_A, /* use */ REG_A, /* chg */ - OF_NONE /* flags */ + OF_SETF /* flags */ }, { OP65_PHA, /* opcode */ "pha", /* mnemonic */ @@ -485,168 +406,178 @@ const OPCDesc OPCTable[OPCODE_COUNT] = { 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_NONE, /* chg */ - OF_NONE /* flags */ + OF_NONE /* flags */ }, { OP65_PLX, /* opcode */ "plx", /* 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 | OF_NOIMP /* 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 | OF_NOIMP /* 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 */ 1, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_NONE /* flags */ + OF_NONE /* flags */ }, { OP65_SED, /* opcode */ "sed", /* mnemonic */ 1, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_NONE /* flags */ + OF_NONE /* flags */ }, { OP65_SEI, /* opcode */ "sei", /* mnemonic */ 1, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_NONE /* flags */ + OF_NONE /* flags */ }, { OP65_STA, /* opcode */ "sta", /* 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 */ 1, /* size */ REG_X, /* use */ REG_NONE, /* chg */ - OF_XFR /* flags */ + OF_XFR /* flags */ }, { OP65_TYA, /* opcode */ "tya", /* mnemonic */ 1, /* size */ - REG_A, /* use */ + REG_Y, /* use */ REG_A, /* chg */ - OF_XFR /* flags */ + OF_XFR | OF_SETF /* flags */ }, }; @@ -689,7 +620,7 @@ const OPCDesc* FindOP65 (const char* M) Mnemo[I] = '\0'; /* Search for the mnemonic in the table and return the result */ - return bsearch (Mnemo, OPCTable+OP65_FIRST, OP65_COUNT, + return bsearch (Mnemo, OPCTable, OP65_COUNT, sizeof (OPCTable[0]), FindCmp ); } @@ -754,16 +685,16 @@ opc_t GetInverseBranch (opc_t OPC) 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; @@ -779,23 +710,23 @@ opc_t MakeShortBranch (opc_t OPC) { 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; @@ -811,23 +742,23 @@ opc_t MakeLongBranch (opc_t OPC) { 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; @@ -840,22 +771,22 @@ bc_t GetBranchCond (opc_t OPC) /* 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; @@ -884,3 +815,4 @@ bc_t GetInverseCond (bc_t BC) +