all repos — mgba @ 4009b7b66486e55053452896210e8703387fb8a7

mGBA Game Boy Advance Emulator

ARM9: Add ARMv5 differences for LDM/POP
Vicki Pfau vi@endrift.com
Mon, 30 Jan 2017 17:48:01 -0800
commit

4009b7b66486e55053452896210e8703387fb8a7

parent

0a568f28777a0ba27606b026645352807f70eda5

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

@@ -59,6 +59,10 @@ #define DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, NAME, MODE, W) \

DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W)), \ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W)) +#define DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, NAME, MODE, W, V) \ + DO_8(MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5 ## MODE ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W), V >= 5)), \ + DO_8(MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## v5 ## MODE ## W), DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W), V >= 5)) + #define DECLARE_ARM_BRANCH_BLOCK(EMITTER, NAME) \ DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))

@@ -265,33 +269,33 @@ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \

DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, DA, , V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, DA, W, V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, IA, , V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, IA, W, V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, DB, , V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, DB, W, V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, IB, , V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \ + DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCKv5(EMITTER, LDM, IB, W, V), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \
M include/mgba/internal/arm/emitter-thumb.hinclude/mgba/internal/arm/emitter-thumb.h

@@ -84,7 +84,7 @@ DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \

DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \ DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \ DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, POP)), \ - DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, POPR)), \ + DO_4(MIN_V(DECLARE_INSTRUCTION_THUMB(EMITTER, POPR), DECLARE_INSTRUCTION_THUMB(EMITTER, POPRv4), V >= 5)), \ DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BKPT)), \ DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \ DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, STMIA))), \
M src/arm/decoder-arm.csrc/arm/decoder-arm.c

@@ -252,15 +252,18 @@ WRITEBACK | \

ARM_MEMORY_ ## DIRECTION;) +#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, SUFFIX) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DA, NAME, DECREMENT_AFTER, 0) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DB, NAME, DECREMENT_BEFORE, 0) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IA, NAME, INCREMENT_AFTER, 0) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IB, NAME, INCREMENT_BEFORE, 0) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \ + #define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DA, NAME, DECREMENT_AFTER, 0) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DB, NAME, DECREMENT_BEFORE, 0) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IA, NAME, INCREMENT_AFTER, 0) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IB, NAME, INCREMENT_BEFORE, 0) \ - DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \ + DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, ) \ DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDA, NAME, DECREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \ DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \ DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDB, NAME, DECREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \

@@ -325,6 +328,7 @@ DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_BYTE)

DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_WORD) DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(LDM) +DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(LDM, v5) DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(STM) DEFINE_SWP_DECODER_ARM(SWP, ARM_ACCESS_WORD)
M src/arm/decoder-thumb.csrc/arm/decoder-thumb.c

@@ -248,6 +248,7 @@ DEFINE_SP_MODIFY_THUMB(SUB4, SUB)

DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POP, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, 0) DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POPR, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, 1 << ARM_PC) +DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POPRv4, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, 1 << ARM_PC) DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSH, ARM_SP, STM, ARM_MEMORY_DECREMENT_BEFORE, 0) DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSHR, ARM_SP, STM, ARM_MEMORY_DECREMENT_BEFORE, 1 << ARM_LR)
M src/arm/isa-arm.csrc/arm/isa-arm.c

@@ -287,6 +287,8 @@ if (!((1 << rn) & rs)) { \

cpu->gprs[rn] = address; \ } +#define ADDR_MODE_4_WRITEBACK_LDMv5 ADDR_MODE_4_WRITEBACK_LDM + #define ADDR_MODE_4_WRITEBACK_STM cpu->gprs[rn] = address; #define ARM_LOAD_POST_BODY \

@@ -450,7 +452,7 @@ POST_BODY; \

WRITEBACK;) -#define DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(NAME, LS, POST_BODY) \ +#define DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM_NO_S(NAME, LS, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DA, LS, , , , DA, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DAW, LS, ADDR_MODE_4_WRITEBACK_ ## NAME, , , DA, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DB, LS, , , , DB, POST_BODY) \

@@ -459,6 +461,9 @@ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IA, LS, , , , IA, POST_BODY) \

DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IAW, LS, ADDR_MODE_4_WRITEBACK_ ## NAME, , , IA, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IB, LS, , , , IB, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IBW, LS, ADDR_MODE_4_WRITEBACK_ ## NAME, , , IB, POST_BODY) \ + +#define DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(NAME, LS, POST_BODY) \ + DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM_NO_S(NAME, LS, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDA, LS, , ARM_MS_PRE, ARM_MS_POST, DA, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDAW, LS, ADDR_MODE_4_WRITEBACK_ ## NAME, ARM_MS_PRE, ARM_MS_POST, DA, POST_BODY) \ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDB, LS, , ARM_MS_PRE, ARM_MS_POST, DB, POST_BODY) \

@@ -609,6 +614,20 @@ load,

currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; if (rs & 0x8000) { ARM_WRITE_PC; + }) + +DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM_NO_S(LDMv5, + load, + currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; + if (rs & 0x8000) { + _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_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM,
M src/arm/isa-thumb.csrc/arm/isa-thumb.c

@@ -361,7 +361,7 @@ ,

THUMB_LOAD_POST_BODY; cpu->gprs[ARM_SP] = address) -DEFINE_LOAD_STORE_MULTIPLE_THUMB(POPR, +DEFINE_LOAD_STORE_MULTIPLE_THUMB(POPRv4, ARM_SP, load, IA,

@@ -369,6 +369,22 @@ rs |= 1 << ARM_PC,

THUMB_LOAD_POST_BODY; cpu->gprs[ARM_SP] = address; THUMB_WRITE_PC;) + +DEFINE_LOAD_STORE_MULTIPLE_THUMB(POPR, + ARM_SP, + load, + IA, + rs |= 1 << ARM_PC, + THUMB_LOAD_POST_BODY; + cpu->gprs[ARM_SP] = address; + _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_LOAD_STORE_MULTIPLE_THUMB(PUSH, ARM_SP,