ARM9: Add mode switching via LDR
Vicki Pfau vi@endrift.com
Tue, 21 Mar 2017 11:24:33 -0700
3 files changed,
48 insertions(+),
12 deletions(-)
M
include/mgba/internal/arm/emitter-arm.h
→
include/mgba/internal/arm/emitter-arm.h
@@ -37,6 +37,10 @@ #define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, NAME, P, U, W) \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W)), \ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W)) +#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCKv5(EMITTER, NAME, P, U, W, V) \ + DO_8(MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5 ## I ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W), V >= 5)), \ + DO_8(MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5 ## I ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W), V >= 5)) + #define DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, NAME, P, U, W) \ DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \@@ -53,6 +57,24 @@ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL) + +#define DECLARE_ARM_LOAD_STORE_BLOCKv5(EMITTER, NAME, P, U, W, V) \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_LSL_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), V >= 5), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_LSR_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), V >= 5), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_ASR_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), V >= 5), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_ROR_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), V >= 5), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_LSL_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), V >= 5), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_LSR_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), V >= 5), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_ASR_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), V >= 5), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5_ROR_ ## P ## U ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), V >= 5), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL) #define DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, NAME, MODE, W) \@@ -205,7 +227,7 @@ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCKv5(EMITTER, LDR, , , , V), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \@@ -213,7 +235,7 @@ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCKv5(EMITTER, LDR, , U, , V), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \@@ -221,23 +243,23 @@ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCKv5(EMITTER, LDR, P, , , V), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCKv5(EMITTER, LDR, P, , W, V), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCKv5(EMITTER, LDR, P, U, , V), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCKv5(EMITTER, LDR, P, U, W, V), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \ + DECLARE_ARM_LOAD_STORE_BLOCKv5(EMITTER, LDR, , , , V), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \@@ -245,7 +267,7 @@ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \ + DECLARE_ARM_LOAD_STORE_BLOCKv5(EMITTER, LDR, , U, , V), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \@@ -253,17 +275,17 @@ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \ + DECLARE_ARM_LOAD_STORE_BLOCKv5(EMITTER, LDR, P, , , V), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \ + DECLARE_ARM_LOAD_STORE_BLOCKv5(EMITTER, LDR, P, , W, V), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \ + DECLARE_ARM_LOAD_STORE_BLOCKv5(EMITTER, LDR, P, U, , V), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \ + DECLARE_ARM_LOAD_STORE_BLOCKv5(EMITTER, LDR, P, U, W, V), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \
M
src/arm/decoder-arm.c
→
src/arm/decoder-arm.c
@@ -323,6 +323,7 @@
// Begin load/store definitions DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD) +DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRv5, LDR, LOAD_CYCLES, ARM_ACCESS_WORD) DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRB, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE) DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD) DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE)
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -275,6 +275,18 @@ if (rd == ARM_PC) { \
ARM_WRITE_PC; \ } +#define ARM_LOAD_POST_BODY_v5 \ + currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; \ + if (rd == ARM_PC) { \ + _ARMSetMode(cpu, cpu->gprs[ARM_PC] & 0x00000001); \ + cpu->gprs[ARM_PC] &= 0xFFFFFFFE; \ + if (cpu->executionMode == MODE_THUMB) { \ + THUMB_WRITE_PC; \ + } else { \ + ARM_WRITE_PC; \ + } \ + } + #define ARM_STORE_POST_BODY \ currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32;@@ -589,6 +601,7 @@
// Begin load/store definitions DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRv5, cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY_v5;) DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory.load8(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;) DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory.load16(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;) DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, address, ¤tCycles)); ARM_LOAD_POST_BODY;)