all repos — mgba @ e0050083eda3057d5b420d1da935d348a8a1a6eb

mGBA Game Boy Advance Emulator

ARM9: Start implementing Thumb9
Jeffrey Pfau jeffrey@endrift.com
Tue, 03 Jan 2017 22:23:39 -0800
commit

e0050083eda3057d5b420d1da935d348a8a1a6eb

parent

7e38db453355e5864af5976ae9e0356d85bd00ce

M include/mgba/internal/arm/emitter-inlines.hinclude/mgba/internal/arm/emitter-inlines.h

@@ -29,4 +29,6 @@ #define DO_INTERLACE(LEFT, RIGHT) \

LEFT, \ RIGHT +#define MIN_V(PASS, FAIL, COND) (COND ? PASS : FAIL) + #endif
M include/mgba/internal/arm/emitter-thumb.hinclude/mgba/internal/arm/emitter-thumb.h

@@ -17,7 +17,7 @@ DECLARE_INSTRUCTION_THUMB(EMITTER, NAME ## 01), \

DECLARE_INSTRUCTION_THUMB(EMITTER, NAME ## 10), \ DECLARE_INSTRUCTION_THUMB(EMITTER, NAME ## 11) -#define DECLARE_THUMB_EMITTER_BLOCK(EMITTER) \ +#define DECLARE_THUMB_EMITTER_BLOCK(EMITTER, V) \ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LSL1))), \ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LSR1))), \ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ASR1))), \

@@ -106,7 +106,7 @@ DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BLE)), \

DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \ DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, SWI)), \ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, B))), \ - DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL))), \ + DO_8(DO_4(MIN_V(DECLARE_INSTRUCTION_THUMB(EMITTER, BLX1), DECLARE_INSTRUCTION_THUMB(EMITTER, ILL), V >= 5))), \ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL1))), \ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL2))) \
M include/mgba/internal/arm/isa-thumb.hinclude/mgba/internal/arm/isa-thumb.h

@@ -13,7 +13,8 @@

struct ARMCore; typedef void (*ThumbInstruction)(struct ARMCore*, uint16_t opcode); -extern const ThumbInstruction _thumbTable[0x400]; +extern const ThumbInstruction _thumbv4Table[0x400]; +extern const ThumbInstruction _thumbv5Table[0x400]; CXX_GUARD_END
M src/arm/arm.csrc/arm/arm.c

@@ -223,15 +223,6 @@ cpu->cpsr.i = 1;

cpu->cycles += currentCycles; } -static inline void ThumbStep(struct ARMCore* cpu) { - uint32_t opcode = cpu->prefetch[0]; - cpu->prefetch[0] = cpu->prefetch[1]; - cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; - LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); - ThumbInstruction instruction = _thumbTable[opcode >> 6]; - instruction(cpu, opcode); -} - #define ARM_IMPLEMENT(VERSION) \ static inline void ARM ## VERSION ## Step(struct ARMCore* cpu) { \ uint32_t opcode = cpu->prefetch[0]; \

@@ -297,9 +288,18 @@ ARMInstruction instruction = _arm ## VERSION ## Table[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)]; \

instruction(cpu, opcode); \ } \ \ - void ARM ## VERSION ## Run(struct ARMCore* cpu) { \ + static inline void Thumb ## VERSION ## Step(struct ARMCore* cpu) { \ + uint32_t opcode = cpu->prefetch[0]; \ + cpu->prefetch[0] = cpu->prefetch[1]; \ + cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; \ + LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ + ThumbInstruction instruction = _thumb ## VERSION ## Table[opcode >> 6]; \ + instruction(cpu, opcode); \ + } \ + \ + void ARM ## VERSION ## Run(struct ARMCore* cpu) { \ if (cpu->executionMode == MODE_THUMB) { \ - ThumbStep(cpu); \ + Thumb ## VERSION ## Step(cpu); \ } else { \ ARM ## VERSION ## Step(cpu); \ } \

@@ -311,7 +311,7 @@ \

void ARM ## VERSION ## RunLoop(struct ARMCore* cpu) { \ if (cpu->executionMode == MODE_THUMB) { \ while (cpu->cycles < cpu->nextEvent) { \ - ThumbStep(cpu); \ + Thumb ## VERSION ## Step(cpu); \ } \ } else { \ while (cpu->cycles < cpu->nextEvent) { \

@@ -319,28 +319,6 @@ ARM ## VERSION ## Step(cpu); \

} \ } \ cpu->irqh.processEvents(cpu); \ - } \ - \ - int32_t ARM ## VERSION ## RunCycles(struct ARMCore* cpu, int32_t cycles) { \ - int32_t startCycles = cpu->cycles; \ - int32_t endCycles = startCycles + cycles; \ - \ - if (cpu->executionMode == MODE_THUMB) { \ - while (cpu->cycles < cpu->nextEvent && cpu->cycles < endCycles) { \ - ThumbStep(cpu); \ - } \ - } else { \ - while (cpu->cycles < cpu->nextEvent && cpu->cycles < endCycles) { \ - ARM ## VERSION ## Step(cpu); \ - } \ - } \ - \ - endCycles = cpu->cycles - startCycles; \ - if (cpu->cycles >= cpu->nextEvent) { \ - /* TODO: Handle HALT */ \ - cpu->irqh.processEvents(cpu); \ - } \ - return endCycles; \ } ARM_IMPLEMENT(v4)
M src/arm/decoder-thumb.csrc/arm/decoder-thumb.c

@@ -282,6 +282,14 @@ info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 |

ARM_OPERAND_REGISTER_2 | ARM_OPERAND_IMMEDIATE_3; info->branchType = ARM_BRANCH_LINKED;) +DEFINE_THUMB_DECODER(BLX1, BLX, + info->op1.reg = ARM_PC; + info->op2.reg = ARM_LR; + info->op3.immediate = (opcode & 0x07FF) << 1; + info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 | + ARM_OPERAND_REGISTER_2 | ARM_OPERAND_IMMEDIATE_3; + info->branchType = ARM_BRANCH_LINKED;) + DEFINE_THUMB_DECODER(BX, BX, info->op1.reg = (opcode >> 3) & 0xF; info->operandFormat = ARM_OPERAND_REGISTER_1;

@@ -295,7 +303,7 @@

typedef void (*ThumbDecoder)(uint16_t opcode, struct ARMInstructionInfo* info); static const ThumbDecoder _thumbDecoderTable[0x400] = { - DECLARE_THUMB_EMITTER_BLOCK(_ThumbDecode) + DECLARE_THUMB_EMITTER_BLOCK(_ThumbDecode, 5) }; void ARMDecodeThumb(uint16_t opcode, struct ARMInstructionInfo* info) {
M src/arm/decoder.csrc/arm/decoder.c

@@ -389,6 +389,7 @@ }

break; case ARM_MN_B: case ARM_MN_BL: + case ARM_MN_BLX: if (info->operandFormat & ARM_OPERAND_IMMEDIATE_1) { written = _decodePCRelative(info->op1.immediate, pc, buffer, blen); ADVANCE(written);
M src/arm/isa-thumb.csrc/arm/isa-thumb.c

@@ -382,6 +382,14 @@ cpu->gprs[ARM_PC] = cpu->gprs[ARM_LR] + immediate;

cpu->gprs[ARM_LR] = pc - 1; THUMB_WRITE_PC;) +DEFINE_INSTRUCTION_THUMB(BLX1, + uint16_t immediate = (opcode & 0x07FF) << 1; + uint32_t pc = cpu->gprs[ARM_PC]; + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_LR] + immediate) & 0xFFFFFFFC; + cpu->gprs[ARM_LR] = pc - 1; + _ARMSetMode(cpu, MODE_ARM); + ARM_WRITE_PC;) + DEFINE_INSTRUCTION_THUMB(BX, int rm = (opcode >> 3) & 0xF; _ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001);

@@ -398,6 +406,10 @@ })

DEFINE_INSTRUCTION_THUMB(SWI, cpu->irqh.swi16(cpu, opcode & 0xFF)) -const ThumbInstruction _thumbTable[0x400] = { - DECLARE_THUMB_EMITTER_BLOCK(_ThumbInstruction) +const ThumbInstruction _thumbv4Table[0x400] = { + DECLARE_THUMB_EMITTER_BLOCK(_ThumbInstruction, 4) +}; + +const ThumbInstruction _thumbv5Table[0x400] = { + DECLARE_THUMB_EMITTER_BLOCK(_ThumbInstruction, 5) };