From ffbe2ea2460d9471f6d0cca5c754f19b4a00868e Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 11 May 2016 23:10:40 -0700 Subject: [PATCH] ARM7: Improve decoder for memory access --- src/arm/decoder-thumb.c | 48 ++++++++++++++++++++--------------------- src/arm/decoder.h | 1 + 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/arm/decoder-thumb.c b/src/arm/decoder-thumb.c index da0b156cd..bfd8fc942 100644 --- a/src/arm/decoder-thumb.c +++ b/src/arm/decoder-thumb.c @@ -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;) diff --git a/src/arm/decoder.h b/src/arm/decoder.h index a1dd59dbc..6ca478046 100644 --- a/src/arm/decoder.h +++ b/src/arm/decoder.h @@ -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