ARM9: Start implementing unconditional instructions
Vicki Pfau vi@endrift.com
Thu, 23 Feb 2017 02:13:10 -0800
4 files changed,
41 insertions(+),
2 deletions(-)
M
include/mgba/internal/arm/emitter-arm.h
→
include/mgba/internal/arm/emitter-arm.h
@@ -337,4 +337,22 @@ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR, MRC), \ DECLARE_ARM_SWI_BLOCK(EMITTER) +#define DECLARE_ARM_F_EMITTER_BLOCK(EMITTER, V) \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, BLX), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5)), \ + DO_256(MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, BLX), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), \ + DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, ILL)), + #endif
M
include/mgba/internal/arm/isa-arm.h
→
include/mgba/internal/arm/isa-arm.h
@@ -17,6 +17,8 @@
typedef void (*ARMInstruction)(struct ARMCore*, uint32_t opcode); extern const ARMInstruction _armv4Table[0x1000]; extern const ARMInstruction _armv5Table[0x1000]; +extern const ARMInstruction _armv4FTable[0x1000]; +extern const ARMInstruction _armv5FTable[0x1000]; CXX_GUARD_END
M
src/arm/arm.c
→
src/arm/arm.c
@@ -235,6 +235,7 @@ cpu->prefetch[0] = cpu->prefetch[1]; \
cpu->gprs[ARM_PC] += WORD_SIZE_ARM; \ LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ \ + ARMInstruction instruction; \ unsigned condition = opcode >> 28; \ if (condition != 0xE) { \ bool conditionMet = false; \@@ -282,14 +283,16 @@ case 0xD: \
conditionMet = ARM_COND_LE; \ break; \ default: \ - break; \ + instruction = _arm ## VERSION ## FTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)]; \ + instruction(cpu, opcode); \ + return; \ } \ if (!conditionMet) { \ cpu->cycles += ARM_PREFETCH_CYCLES; \ return; \ } \ } \ - ARMInstruction instruction = _arm ## VERSION ## Table[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)]; \ + instruction = _arm ## VERSION ## Table[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)]; \ instruction(cpu, opcode); \ } \ \
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -654,6 +654,14 @@ } else {
ARM_WRITE_PC; }) + +DEFINE_INSTRUCTION_ARM(BLX, + int32_t immediate = (opcode & 0x00FFFFFF) << 8; + cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - WORD_SIZE_ARM; + cpu->gprs[ARM_PC] += (immediate >> 6) + ((opcode >> 23) & 2); + _ARMSetMode(cpu, MODE_THUMB); + THUMB_WRITE_PC;) + DEFINE_INSTRUCTION_ARM(BLX2, int rm = opcode & 0x0000000F; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - WORD_SIZE_ARM;@@ -795,3 +803,11 @@
const ARMInstruction _armv5Table[0x1000] = { DECLARE_ARM_EMITTER_BLOCK(_ARMInstruction, 5) }; + +const ARMInstruction _armv4FTable[0x1000] = { + DECLARE_ARM_F_EMITTER_BLOCK(_ARMInstruction, 4) +}; + +const ARMInstruction _armv5FTable[0x1000] = { + DECLARE_ARM_F_EMITTER_BLOCK(_ARMInstruction, 5) +};