mirror of https://github.com/mgba-emu/mgba.git
ARM7: Improve decoder for memory access
This commit is contained in:
parent
4375e7029f
commit
2d1ad16e1c
|
@ -27,14 +27,14 @@
|
|||
ARM_OPERAND_REGISTER_2 | \
|
||||
ARM_OPERAND_IMMEDIATE_3;)
|
||||
|
||||
#define DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(NAME, MNEMONIC, CYCLES, WIDTH) \
|
||||
#define DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(NAME, MNEMONIC, CYCLES, WIDTH, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->memory.baseReg = (opcode >> 3) & 0x0007; \
|
||||
info->memory.offset.immediate = ((opcode >> 6) & 0x001F) * WIDTH; \
|
||||
info->memory.width = (enum ARMMemoryAccessType) WIDTH; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
ARM_OPERAND_AFFECTED_ ## AFFECTED | \
|
||||
ARM_OPERAND_MEMORY_2; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_IMMEDIATE_OFFSET; \
|
||||
|
@ -43,12 +43,12 @@
|
|||
DEFINE_IMMEDIATE_5_DECODER_DATA_THUMB(LSL1, LSL)
|
||||
DEFINE_IMMEDIATE_5_DECODER_DATA_THUMB(LSR1, LSR)
|
||||
DEFINE_IMMEDIATE_5_DECODER_DATA_THUMB(ASR1, ASR)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDR1, LDR, LOAD_CYCLES, 4)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRB1, LDR, LOAD_CYCLES, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRH1, LDR, LOAD_CYCLES, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STR1, STR, STORE_CYCLES, 4)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRB1, STR, STORE_CYCLES, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRH1, STR, STORE_CYCLES, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDR1, LDR, LOAD_CYCLES, 4, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRB1, LDR, LOAD_CYCLES, 1, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRH1, LDR, LOAD_CYCLES, 2, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STR1, STR, STORE_CYCLES, 4, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRB1, STR, STORE_CYCLES, 1, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRH1, STR, STORE_CYCLES, 2, 2)
|
||||
|
||||
#define DEFINE_DATA_FORM_1_DECODER_THUMB(NAME, MNEMONIC) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
|
@ -151,47 +151,47 @@ DEFINE_DECODER_WITH_HIGH_THUMB(MOV3, MOV, ARM_OPERAND_AFFECTED_1, 0)
|
|||
ARM_OPERAND_REGISTER_2 | \
|
||||
ARM_OPERAND_IMMEDIATE_3;)
|
||||
|
||||
#define DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(NAME, MNEMONIC, REG, CYCLES) \
|
||||
#define DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(NAME, MNEMONIC, REG, CYCLES, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 8) & 0x0007; \
|
||||
info->memory.baseReg = REG; \
|
||||
info->memory.offset.immediate = (opcode & 0x00FF) << 2; \
|
||||
info->memory.width = ARM_ACCESS_WORD; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
ARM_OPERAND_AFFECTED_ ## AFFECTED | \
|
||||
ARM_OPERAND_MEMORY_2; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_IMMEDIATE_OFFSET; \
|
||||
CYCLES;)
|
||||
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR3, LDR, ARM_PC, LOAD_CYCLES)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR4, LDR, ARM_SP, LOAD_CYCLES)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(STR3, STR, ARM_SP, STORE_CYCLES)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR3, LDR, ARM_PC, LOAD_CYCLES, 1)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR4, LDR, ARM_SP, LOAD_CYCLES, 1)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(STR3, STR, ARM_SP, STORE_CYCLES, 2)
|
||||
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_DATA_THUMB(ADD5, ADD, ARM_PC)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_DATA_THUMB(ADD6, ADD, ARM_SP)
|
||||
|
||||
#define DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(NAME, MNEMONIC, CYCLES, TYPE) \
|
||||
#define DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(NAME, MNEMONIC, CYCLES, TYPE, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->memory.offset.reg = (opcode >> 6) & 0x0007; \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->memory.baseReg = (opcode >> 3) & 0x0007; \
|
||||
info->memory.width = TYPE; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | /* TODO: Remove this for STR */ \
|
||||
ARM_OPERAND_AFFECTED_ ## AFFECTED | \
|
||||
ARM_OPERAND_MEMORY_2; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_REGISTER_OFFSET; \
|
||||
CYCLES;)
|
||||
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDR2, LDR, LOAD_CYCLES, ARM_ACCESS_WORD)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STR2, STR, STORE_CYCLES, ARM_ACCESS_WORD)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRB2, STR, STORE_CYCLES, ARM_ACCESS_BYTE)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDR2, LDR, LOAD_CYCLES, ARM_ACCESS_WORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STR2, STR, STORE_CYCLES, ARM_ACCESS_WORD, 2)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRB2, STR, STORE_CYCLES, ARM_ACCESS_BYTE, 2)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD, 2)
|
||||
|
||||
// TODO: Estimate memory cycles
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(NAME, RN, MNEMONIC, DIRECTION, ADDITIONAL_REG) \
|
||||
|
@ -201,7 +201,7 @@ DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, STR, STORE_CYCLES, ARM_ACCESS_HALFW
|
|||
if (info->op1.immediate & (1 << ARM_PC)) { \
|
||||
info->branchType = ARM_BRANCH_INDIRECT; \
|
||||
} \
|
||||
info->operandFormat = ARM_OPERAND_MEMORY_1; \
|
||||
info->operandFormat = ARM_OPERAND_MEMORY_1 | ARM_OPERAND_AFFECTED_1; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
DIRECTION;)
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#define ARM_OPERAND_SHIFT_IMMEDIATE_4 0x20000000
|
||||
#define ARM_OPERAND_4 0xFF000000
|
||||
|
||||
#define ARM_OPERAND_MEMORY (ARM_OPERAND_MEMORY_1 | ARM_OPERAND_MEMORY_2 | ARM_OPERAND_MEMORY_3 | ARM_OPERAND_MEMORY_4)
|
||||
|
||||
#define ARM_MEMORY_REGISTER_BASE 0x0001
|
||||
#define ARM_MEMORY_IMMEDIATE_OFFSET 0x0002
|
||||
|
|
Loading…
Reference in New Issue