all repos — mgba @ b1393f129485a5180dc1081c7a135a8ecd508cd6

mGBA Game Boy Advance Emulator

ARM9: Start implementing unconditional instructions
Vicki Pfau vi@endrift.com
Thu, 23 Feb 2017 02:13:10 -0800
commit

b1393f129485a5180dc1081c7a135a8ecd508cd6

parent

e5ae0209a6974f495b4f7f18629e1113ed6c6aa0

M include/mgba/internal/arm/emitter-arm.hinclude/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.hinclude/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.csrc/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.csrc/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) +};