Implement LDM, STM

This commit is contained in:
Jeffrey Pfau 2013-04-17 23:44:35 -07:00
parent dd479ad907
commit cb03781a5b
1 changed files with 68 additions and 22 deletions

View File

@ -355,27 +355,68 @@ void ARMStep(struct ARMCore* cpu) {
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE)), BODY) \ DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE)), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE)), BODY) \ DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE)), BODY) \
// TODO #define ARM_MS_PRE \
#define DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME, ADDRESS, S_PRE, S_POST, BODY) \ enum PrivilegeMode privilegeMode = cpu->privilegeMode; \
DEFINE_INSTRUCTION_ARM(NAME, BODY;) ARMSetPrivilegeMode(cpu, MODE_SYSTEM);
#define DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(NAME, BODY) \ #define ARM_MS_POST ARMSetPrivilegeMode(cpu, privilegeMode);
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DA, ADDR_MODE_4_DA, , , BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DAW, ADDR_MODE_4_DAW, , , BODY) \ #define ADDR_MODE_4_DA uint32_t addr = cpu->gprs[rn]
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DB, ADDR_MODE_4_DB, , , BODY) \ #define ADDR_MODE_4_IA uint32_t addr = cpu->gprs[rn]
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DBW, ADDR_MODE_4_DBW, , , BODY) \ #define ADDR_MODE_4_DB uint32_t addr = cpu->gprs[rn] - 4
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IA, ADDR_MODE_4_IA, , , BODY) \ #define ADDR_MODE_4_IB uint32_t addr = cpu->gprs[rn] + 4
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IAW, ADDR_MODE_4_IAW, , , BODY) \ #define ADDR_MODE_4_DAW cpu->gprs[rn] = addr
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IB, ADDR_MODE_4_IB, , , BODY) \ #define ADDR_MODE_4_IAW cpu->gprs[rn] = addr
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IBW, ADDR_MODE_4_IBW, , , BODY) \ #define ADDR_MODE_4_DBW cpu->gprs[rn] = addr + 4
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDA, ADDR_MODE_4_DA, S_PRE, S_POST, BODY) \ #define ADDR_MODE_4_IBW cpu->gprs[rn] = addr - 4
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDAW, ADDR_MODE_4_DAW, S_PRE, S_POST, BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDB, ADDR_MODE_4_DB, S_PRE, S_POST, BODY) \ #define ARM_M_INCREMENT(BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDBW, ADDR_MODE_4_DBW, S_PRE, S_POST, BODY) \ for (m = rs, i = 0; m; m >>= 1, ++i) { \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIA, ADDR_MODE_4_IA, S_PRE, S_POST, BODY) \ if (m & 1) { \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIAW, ADDR_MODE_4_IAW, S_PRE, S_POST, BODY) \ BODY; \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIB, ADDR_MODE_4_IB, S_PRE, S_POST, BODY) \ addr += 4; \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIBW, ADDR_MODE_4_IBW, S_PRE, S_POST, BODY) } \
}
#define ARM_M_DECREMENT(BODY) \
for (m = 0x8000, i = 15; m; m >>= 1, --i) { \
if (rs & m) { \
BODY; \
addr -= 4; \
} \
}
#define DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME, ADDRESS, WRITEBACK, LOOP, S_PRE, S_POST, BODY, POST_BODY) \
DEFINE_INSTRUCTION_ARM(NAME, \
int rn = (opcode >> 16) & 0xF; \
int rs = opcode & 0x0000FFFF; \
int m; \
int i; \
ADDRESS; \
S_PRE; \
LOOP(BODY); \
S_POST; \
WRITEBACK; \
POST_BODY;)
#define DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(NAME, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DA, ADDR_MODE_4_DA, , ARM_M_DECREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DAW, ADDR_MODE_4_DA, ADDR_MODE_4_DAW, ARM_M_DECREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DB, ADDR_MODE_4_DB, , ARM_M_DECREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## DBW, ADDR_MODE_4_DB, ADDR_MODE_4_DBW, ARM_M_DECREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IA, ADDR_MODE_4_IA, , ARM_M_INCREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IAW, ADDR_MODE_4_IA, ADDR_MODE_4_IAW, ARM_M_INCREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IB, ADDR_MODE_4_IB, , ARM_M_INCREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## IBW, ADDR_MODE_4_IB, ADDR_MODE_4_IBW, ARM_M_INCREMENT, , , BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDA, ADDR_MODE_4_DA, , ARM_M_DECREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDAW, ADDR_MODE_4_DA, ADDR_MODE_4_DAW, ARM_M_DECREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDB, ADDR_MODE_4_DB, , ARM_M_DECREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SDBW, ADDR_MODE_4_DB, ADDR_MODE_4_DBW, ARM_M_DECREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIA, ADDR_MODE_4_IA, , ARM_M_INCREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIAW, ADDR_MODE_4_IA, ADDR_MODE_4_IAW, ARM_M_INCREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIB, ADDR_MODE_4_IB, , ARM_M_INCREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY) \
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_EX_ARM(NAME ## SIBW, ADDR_MODE_4_IB, ADDR_MODE_4_IBW, ARM_M_INCREMENT, ARM_MS_PRE, ARM_MS_POST, BODY, POST_BODY)
// Begin ALU definitions // Begin ALU definitions
@ -484,8 +525,13 @@ DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT,
cpu->memory->store8(cpu->memory, address, cpu->gprs[rd]); cpu->memory->store8(cpu->memory, address, cpu->gprs[rd]);
ARMSetPrivilegeMode(cpu, priv);) ARMSetPrivilegeMode(cpu, priv);)
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM, ARM_STUB) DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM,
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM, ARM_STUB) cpu->gprs[i] = cpu->memory->load32(cpu->memory, addr);,
if (rs & 0x8000) {
ARM_WRITE_PC;
})
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM, cpu->memory->store32(cpu->memory, addr, cpu->gprs[i]);, )
DEFINE_INSTRUCTION_ARM(SWP, ARM_STUB) DEFINE_INSTRUCTION_ARM(SWP, ARM_STUB)
DEFINE_INSTRUCTION_ARM(SWPB, ARM_STUB) DEFINE_INSTRUCTION_ARM(SWPB, ARM_STUB)