mirror of https://github.com/mgba-emu/mgba.git
Fill in more opcodes, implement CMN, CMP, TEQ, TST
This commit is contained in:
parent
fd4ee12eb5
commit
e093960316
89
src/arm.c
89
src/arm.c
|
@ -134,50 +134,43 @@ inline void ARMCycle(struct ARMCore* cpu) {
|
||||||
cpu->cpsr.c = cpu->shifterCarryOut; \
|
cpu->cpsr.c = cpu->shifterCarryOut; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: shifter
|
#define DEFINE_INSTRUCTION_EX_ARM(NAME, COND, COND_BODY, BODY) \
|
||||||
#define DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, COND, COND_BODY, S, S_BODY, BODY, POST_BODY) \
|
static void _ARMInstruction ## NAME ## COND (struct ARMCore* cpu, uint32_t opcode) { \
|
||||||
static void _ARMInstruction ## NAME ## S ## COND (struct ARMCore* cpu, uint32_t opcode) { \
|
|
||||||
if (!COND_BODY) { \
|
if (!COND_BODY) { \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
|
BODY; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_INSTRUCTION_ARM(NAME, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, EQ, ARM_COND_EQ, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, NE, ARM_COND_NE, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, CS, ARM_COND_CS, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, CC, ARM_COND_CC, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, MI, ARM_COND_MI, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, PL, ARM_COND_PL, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, VS, ARM_COND_VS, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, VC, ARM_COND_VC, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, HI, ARM_COND_HI, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, LS, ARM_COND_LS, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, GE, ARM_COND_GE, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, LT, ARM_COND_LT, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, GT, ARM_COND_GT, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, LE, ARM_COND_LE, BODY) \
|
||||||
|
DEFINE_INSTRUCTION_EX_ARM(NAME, AL, ARM_COND_AL, BODY)
|
||||||
|
|
||||||
|
// TODO: shifter
|
||||||
|
#define DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, S, S_BODY, BODY, POST_BODY) \
|
||||||
|
DEFINE_INSTRUCTION_ARM(NAME ## S, \
|
||||||
int rd = (opcode >> 12) & 0xF; \
|
int rd = (opcode >> 12) & 0xF; \
|
||||||
int rn = (opcode >> 16) & 0xF; \
|
int rn = (opcode >> 16) & 0xF; \
|
||||||
BODY; \
|
BODY; \
|
||||||
S_BODY; \
|
S_BODY; \
|
||||||
POST_BODY; \
|
POST_BODY;)
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_ALU_INSTRUCTION_ARM(NAME, S_BODY, BODY, POST_BODY) \
|
#define DEFINE_ALU_INSTRUCTION_ARM(NAME, S_BODY, BODY, POST_BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, EQ, ARM_COND_EQ, , , BODY, POST_BODY) \
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, , , BODY, POST_BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, NE, ARM_COND_NE, , , BODY, POST_BODY) \
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, S, S_BODY, BODY, POST_BODY)
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, CS, ARM_COND_CS, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, CC, ARM_COND_CC, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, MI, ARM_COND_MI, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, PL, ARM_COND_PL, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, VS, ARM_COND_VS, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, VC, ARM_COND_VC, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, HI, ARM_COND_HI, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, LS, ARM_COND_LS, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, GE, ARM_COND_GE, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, LT, ARM_COND_LT, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, GT, ARM_COND_GT, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, LE, ARM_COND_LE, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, AL, ARM_COND_AL, , , BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, EQ, ARM_COND_EQ, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, NE, ARM_COND_NE, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, CS, ARM_COND_CS, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, CC, ARM_COND_CC, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, MI, ARM_COND_MI, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, PL, ARM_COND_PL, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, VS, ARM_COND_VS, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, VC, ARM_COND_VC, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, HI, ARM_COND_HI, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, LS, ARM_COND_LS, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, GE, ARM_COND_GE, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, LT, ARM_COND_LT, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, GT, ARM_COND_GT, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, LE, ARM_COND_LE, S, S_BODY, BODY, POST_BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, AL, ARM_COND_AL, S, S_BODY, BODY, POST_BODY)
|
|
||||||
|
|
||||||
// Begin ALU definitions
|
// Begin ALU definitions
|
||||||
|
|
||||||
|
@ -191,6 +184,12 @@ DEFINE_ALU_INSTRUCTION_ARM(ADC, ARM_ADDITION_S(cpu->gprs[rn], shifterOperand, cp
|
||||||
DEFINE_ALU_INSTRUCTION_ARM(AND, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]), \
|
DEFINE_ALU_INSTRUCTION_ARM(AND, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]), \
|
||||||
cpu->gprs[rd] = cpu->gprs[rn] & cpu->shifterOperand;, )
|
cpu->gprs[rd] = cpu->gprs[rn] & cpu->shifterOperand;, )
|
||||||
|
|
||||||
|
DEFINE_ALU_INSTRUCTION_ARM(CMN, ARM_ADDITION_S(cpu->gprs[rn], cpu->shifterOperand, aluOut), \
|
||||||
|
int32_t aluOut = cpu->gprs[rn] + cpu->shifterOperand;, )
|
||||||
|
|
||||||
|
DEFINE_ALU_INSTRUCTION_ARM(CMP, ARM_SUBTRACTION_S(cpu->gprs[rn], cpu->shifterOperand, aluOut), \
|
||||||
|
int32_t aluOut = cpu->gprs[rn] - cpu->shifterOperand;, )
|
||||||
|
|
||||||
DEFINE_ALU_INSTRUCTION_ARM(EOR, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]), \
|
DEFINE_ALU_INSTRUCTION_ARM(EOR, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]), \
|
||||||
cpu->gprs[rd] = cpu->gprs[rn] ^ cpu->shifterOperand;, )
|
cpu->gprs[rd] = cpu->gprs[rn] ^ cpu->shifterOperand;, )
|
||||||
|
|
||||||
|
@ -208,8 +207,18 @@ DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_S(cpu->gprs[rn], shifterOperand,
|
||||||
DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(cpu->gprs[rn], cpu->shifterOperand, d), \
|
DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(cpu->gprs[rn], cpu->shifterOperand, d), \
|
||||||
int32_t d = cpu->gprs[rn] - cpu->shifterOperand;, cpu->gprs[rd] = d)
|
int32_t d = cpu->gprs[rn] - cpu->shifterOperand;, cpu->gprs[rd] = d)
|
||||||
|
|
||||||
|
DEFINE_ALU_INSTRUCTION_ARM(TEQ, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, aluOut), \
|
||||||
|
int32_t aluOut = cpu->gprs[rn] ^ cpu->shifterOperand;, )
|
||||||
|
|
||||||
|
DEFINE_ALU_INSTRUCTION_ARM(TST, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, aluOut), \
|
||||||
|
int32_t aluOut = cpu->gprs[rn] & cpu->shifterOperand;, )
|
||||||
|
|
||||||
// End ALU definitions
|
// End ALU definitions
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
DEFINE_INSTRUCTION_ARM(MSR,)
|
||||||
|
DEFINE_INSTRUCTION_ARM(MRS,)
|
||||||
|
|
||||||
#define DECLARE_INSTRUCTION_ARM(COND, NAME) \
|
#define DECLARE_INSTRUCTION_ARM(COND, NAME) \
|
||||||
_ARMInstruction ## NAME ## COND
|
_ARMInstruction ## NAME ## COND
|
||||||
|
|
||||||
|
@ -253,7 +262,15 @@ DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(cpu->gprs[rn], cpu->shifterOpe
|
||||||
DECLARE_ARM_ALU_BLOCK(COND, SBC, SMULL, STRH, 0, 0), \
|
DECLARE_ARM_ALU_BLOCK(COND, SBC, SMULL, STRH, 0, 0), \
|
||||||
DECLARE_ARM_ALU_BLOCK(COND, SBCS, SMULLS, LDRH, LDRSB, LDRSH), \
|
DECLARE_ARM_ALU_BLOCK(COND, SBCS, SMULLS, LDRH, LDRSB, LDRSH), \
|
||||||
DECLARE_ARM_ALU_BLOCK(COND, RSC, SMLAL, STRH, 0, 0), \
|
DECLARE_ARM_ALU_BLOCK(COND, RSC, SMLAL, STRH, 0, 0), \
|
||||||
DECLARE_ARM_ALU_BLOCK(COND, RSCS, SMLALS, LDRH, LDRSB, LDRSH)
|
DECLARE_ARM_ALU_BLOCK(COND, RSCS, SMLALS, LDRH, LDRSB, LDRSH), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, MRS, SWP, STRH, 0, 0), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, TST, 0, LDRH, LDRSB, LDRSH), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, MSR, 0, STRH, 0, 0), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, TEQ, 0, LDRH, LDRSB, LDRSH), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, MRS, SWPB, STRH, 0, 0), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, CMP, 0, LDRH, LDRSB, LDRSH), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, MSR, 0, STRH, 0, 0), \
|
||||||
|
DECLARE_ARM_ALU_BLOCK(COND, CMN, 0, LDRH, LDRSB, LDRSH)
|
||||||
|
|
||||||
static const ARMInstruction armTable[0xF000] = {
|
static const ARMInstruction armTable[0xF000] = {
|
||||||
DECLARE_COND_BLOCK(EQ),
|
DECLARE_COND_BLOCK(EQ),
|
||||||
|
|
Loading…
Reference in New Issue