Partially implement LDR/STR and friends

This commit is contained in:
Jeffrey Pfau 2013-04-06 04:16:27 -07:00
parent 92e74a78e1
commit 96da9c7ef1
2 changed files with 116 additions and 59 deletions

171
src/arm.c
View File

@ -15,6 +15,7 @@ static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) {
return mode != MODE_SYSTEM && mode != MODE_USER;
}
// Addressing mode 1
static inline void _barrelShift(struct ARMCore* cpu, uint32_t opcode) {
// TODO
}
@ -153,6 +154,24 @@ inline void ARMCycle(struct ARMCore* cpu) {
cpu->cpsr.c = cpu->shifterCarryOut; \
}
#define ADDR_MODE_2_ADDRESS (address)
#define ADDR_MODE_2_RN (cpu->gprs[rn])
#define ADDR_MODE_2_RM (cpu->gprs[rm])
#define ADDR_MODE_2_IMMEDIATE (opcode & 0x00000FFF)
#define ADDR_MODE_2_INDEX(U_OP, M) (cpu->gprs[rn] U_OP M)
#define ADDR_MODE_2_WRITEBACK(ADDR) (cpu->gprs[rn] = ADDR)
#define ADDR_MODE_2_LSL(I) (cpu->gprs[rm] << I)
#define ADDR_MODE_2_LSR(I) (I ? ((uint32_t) cpu->gprs[rm]) >> I : 0)
#define ADDR_MODE_2_ASR(I) (I ? ((int32_t) cpu->gprs[rm]) >> I : ((int32_t) cpu->gprs[rm]) >> 31)
#define ADDR_MODE_2_ROR(I) (I ? ARM_ROR(cpu->gprs[rm], I) : (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1))
#define ADDR_MODE_3_ADDRESS ADDR_MODE_2_ADDRESS
#define ADDR_MODE_3_RN ADDR_MODE_2_RN
#define ADDR_MODE_3_RM ADDR_MODE_2_RM
#define ADDR_MODE_3_IMMEDIATE ADDR_MODE_2_IMMEDIATE
#define ADDR_MODE_3_INDEX(U_OP, M) ADDR_MODE_2_INDEX(U_OP, M)
#define ADDR_MODE_3_WRITEBACK(ADDR) ADDR_MODE_2_WRITEBACK(ADDR)
#define DEFINE_INSTRUCTION_EX_ARM(NAME, COND, COND_BODY, BODY) \
static void _ARMInstruction ## NAME ## COND (struct ARMCore* cpu, uint32_t opcode) { \
if (!COND_BODY) { \
@ -193,27 +212,44 @@ inline void ARMCycle(struct ARMCore* cpu) {
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, , _immediate, BODY, POST_BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## SI, S_BODY, _immediate, BODY, POST_BODY)
#define DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, BODY) \
DEFINE_INSTRUCTION_ARM(NAME ## ADDRESS, \
BODY;)
#define DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, WRITEBACK, BODY) \
DEFINE_INSTRUCTION_ARM(NAME, \
uint32_t address; \
int rn = (opcode >> 16) & 0xF; \
int rd = (opcode >> 12) & 0xF; \
int rm = opcode & 0xF; \
address = ADDRESS; \
BODY; \
WRITEBACK;)
// TODO: shifters
#define DEFINE_LOAD_STORE_INSTRUCTION_ARM(NAME, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, W, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, U, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, UW, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, P, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, PW, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, PU, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, PUW, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, I, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IW, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IU, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IUW, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IP, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IPW, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IPU, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IPUW, BODY)
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM)), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM)), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), 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 ## IP, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \
#define DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(NAME, BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM)), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM)), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE)), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE)), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IP, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), , BODY) \
DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \
// Begin ALU definitions
@ -289,14 +325,14 @@ DEFINE_INSTRUCTION_ARM(UMULLS,)
// Begin load/store definitions
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRH,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRSB,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRSH,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRH,)
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, cpu->gprs[rd] = cpu->memory->load32(cpu->memory, address))
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory->loadU8(cpu->memory, address))
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory->loadU16(cpu->memory, address))
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = cpu->memory->load8(cpu->memory, address))
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = cpu->memory->load16(cpu->memory, address))
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, cpu->memory->store32(cpu->memory, address, cpu->gprs[rd]))
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, cpu->memory->store8(cpu->memory, address, cpu->gprs[rd]))
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory->store16(cpu->memory, address, cpu->gprs[rd]))
DEFINE_INSTRUCTION_ARM(SWP,)
DEFINE_INSTRUCTION_ARM(SWPB,)
@ -342,6 +378,23 @@ DEFINE_INSTRUCTION_ARM(MRSI,)
DO_8(DECLARE_INSTRUCTION_ARM(COND, NAME ## I ## P ## U ## W)) \
DO_8(DECLARE_INSTRUCTION_ARM(COND, NAME ## I ## P ## U ## W))
#define LDRHW ILL
#define LDRSBW ILL
#define LDRSHW ILL
#define LDRHIW ILL
#define LDRSBIW ILL
#define LDRSHIW ILL
#define LDRHUW ILL
#define LDRSBUW ILL
#define LDRSHUW ILL
#define LDRHIUW ILL
#define LDRSBIUW ILL
#define LDRSHIUW ILL
#define STRHIW ILL
#define STRHIUW ILL
#define STRHUW ILL
#define STRHW ILL
#define DECLARE_COND_BLOCK(COND) \
DECLARE_ARM_ALU_BLOCK(COND, AND, MUL, STRH, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(COND, ANDS, MULS, LDRH, LDRSB, LDRSH), \
@ -407,38 +460,38 @@ DEFINE_INSTRUCTION_ARM(MRSI,)
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(COND, BICS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(COND, MVN), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(COND, MVNS)//, \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, ), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, W), \
// DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, W), \
// DECLARE_ARM_LOAD_STORE_BLOCK(COND, STR, , , ), \
// DECLARE_ARM_LOAD_STORE_BLOCK(COND, LDR, , , ), \
// DECLARE_ARM_LOAD_STORE_BLOCK(COND, STR, , , W), \

View File

@ -64,6 +64,10 @@ struct ARMMemory {
uint16_t (*loadU16)(struct ARMMemory*, uint32_t address);
int8_t (*load8)(struct ARMMemory*, uint32_t address);
uint8_t (*loadU8)(struct ARMMemory*, uint32_t address);
void (*store32)(struct ARMMemory*, uint32_t address, int32_t value);
void (*store16)(struct ARMMemory*, uint32_t address, int16_t value);
void (*store8)(struct ARMMemory*, uint32_t address, int8_t value);
};
struct ARMBoard {