all repos — mgba @ f7b1cee66ee5438db8d483911b48acacd8ebefd9

mGBA Game Boy Advance Emulator

Use branchType instead of branches in decoder for more expressive branch decoding
Jeffrey Pfau jeffrey@endrift.com
Tue, 21 Oct 2014 00:45:06 -0700
commit

f7b1cee66ee5438db8d483911b48acacd8ebefd9

parent

e7bd5f9ade967c2bea151633b9336144b246576b

3 files changed, 32 insertions(+), 19 deletions(-)

jump to
M src/arm/decoder-arm.csrc/arm/decoder-arm.c

@@ -110,7 +110,7 @@ } else if (SKIPPED == 2) { \

info->operandFormat &= ~ARM_OPERAND_2; \ } \ if (info->op1.reg == ARM_PC) { \ - info->branches = 1; \ + info->branchType = ARM_BRANCH_INDIRECT; \ }) #define DEFINE_ALU_DECODER_ARM(NAME, SKIPPED) \

@@ -157,7 +157,7 @@ ARM_OPERAND_REGISTER_3 | \

OTHER_AFFECTED; \ info->affectsCPSR = S; \ if (info->op1.reg == ARM_PC) { \ - info->branches = 1; \ + info->branchType = ARM_BRANCH_INDIRECT; \ }) #define DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S) \

@@ -174,7 +174,7 @@ ARM_OPERAND_REGISTER_3 | \

ARM_OPERAND_REGISTER_4; \ info->affectsCPSR = S; \ if (info->op1.reg == ARM_PC) { \ - info->branches = 1; \ + info->branchType = ARM_BRANCH_INDIRECT; \ }) #define DEFINE_MULTIPLY_DECODER_ARM(NAME, OTHER_AFFECTED) \

@@ -255,7 +255,9 @@ #define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION, WRITEBACK) \

DEFINE_DECODER_ARM(NAME, MNEMONIC, \ info->memory.baseReg = (opcode >> 16) & 0xF; \ info->op1.immediate = opcode & 0x0000FFFF; \ - info->branches = info->op1.immediate & (1 << ARM_PC); \ + if (info->op1.immediate & (1 << ARM_PC)) { \ + info->branchType = ARM_BRANCH_INDIRECT; \ + } \ info->operandFormat = ARM_OPERAND_MEMORY_1; \ info->memory.format = ARM_MEMORY_REGISTER_BASE | \ ARM_MEMORY_WRITEBACK | \

@@ -348,18 +350,18 @@ DEFINE_DECODER_ARM(B, B,

int32_t offset = opcode << 8; info->op1.immediate = offset >> 6; info->operandFormat = ARM_OPERAND_IMMEDIATE_1; - info->branches = 1;) + info->branchType = ARM_BRANCH;) DEFINE_DECODER_ARM(BL, BL, int32_t offset = opcode << 8; info->op1.immediate = offset >> 6; info->operandFormat = ARM_OPERAND_IMMEDIATE_1; - info->branches = 1;) + info->branchType = ARM_BRANCH_LINKED;) DEFINE_DECODER_ARM(BX, BX, info->op1.reg = opcode & 0x0000000F; info->operandFormat = ARM_OPERAND_REGISTER_1; - info->branches = 1;) + info->branchType = ARM_BRANCH_INDIRECT;) // End branch definitions

@@ -441,7 +443,7 @@

void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info) { info->execMode = MODE_ARM; info->opcode = opcode; - info->branches = 0; + info->branchType = ARM_BRANCH_NONE; info->traps = 0; info->affectsCPSR = 0; info->condition = opcode >> 28;
M src/arm/decoder-thumb.csrc/arm/decoder-thumb.c

@@ -135,7 +135,9 @@ #define DEFINE_DECODER_WITH_HIGH_EX_THUMB(NAME, H1, H2, MNEMONIC, AFFECTED, CPSR) \

DEFINE_THUMB_DECODER(NAME, MNEMONIC, \ info->op1.reg = (opcode & 0x0007) | H1; \ info->op2.reg = ((opcode >> 3) & 0x0007) | H2; \ - info->branches = info->op1.reg == ARM_PC; \ + if (info->op1.reg == ARM_PC) { \ + info->branchType = ARM_BRANCH_INDIRECT; \ + } \ info->affectsCPSR = CPSR; \ info->operandFormat = ARM_OPERAND_REGISTER_1 | \ AFFECTED | \

@@ -221,7 +223,9 @@ #define DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(NAME, RN, MNEMONIC, DIRECTION, ADDITIONAL_REG) \

DEFINE_THUMB_DECODER(NAME, MNEMONIC, \ info->memory.baseReg = RN; \ info->op1.immediate = (opcode & 0xFF) | ADDITIONAL_REG; \ - info->branches = info->op1.immediate & (1 << ARM_PC); \ + if (info->op1.immediate & (1 << ARM_PC)) { \ + info->branchType = ARM_BRANCH_INDIRECT; \ + } \ info->operandFormat = ARM_OPERAND_MEMORY_1; \ info->memory.format = ARM_MEMORY_REGISTER_BASE | \ ARM_MEMORY_WRITEBACK | \

@@ -237,7 +241,7 @@ #define DEFINE_CONDITIONAL_BRANCH_THUMB(COND) \

DEFINE_THUMB_DECODER(B ## COND, B, \ int8_t immediate = opcode; \ info->op1.immediate = immediate << 1; \ - info->branches = 1; \ + info->branchType = ARM_BRANCH; \ info->condition = ARM_CONDITION_ ## COND; \ info->operandFormat = ARM_OPERAND_IMMEDIATE_1;)

@@ -279,7 +283,7 @@ DEFINE_THUMB_DECODER(B, B,

int16_t immediate = (opcode & 0x07FF) << 5; info->op1.immediate = (((int32_t) immediate) >> 4); info->operandFormat = ARM_OPERAND_IMMEDIATE_1; - info->branches = 1;) + info->branchType = ARM_BRANCH;) DEFINE_THUMB_DECODER(BL1, BLH, int16_t immediate = (opcode & 0x07FF) << 5;

@@ -289,12 +293,12 @@

DEFINE_THUMB_DECODER(BL2, BL, info->op1.immediate = (opcode & 0x07FF) << 1; info->operandFormat = ARM_OPERAND_IMMEDIATE_1; - info->branches = 1;) + info->branchType = ARM_BRANCH_LINKED;) DEFINE_THUMB_DECODER(BX, BX, info->op1.reg = (opcode >> 3) & 0xF; info->operandFormat = ARM_OPERAND_REGISTER_1; - info->branches = 1;) + info->branchType = ARM_BRANCH_INDIRECT;) DEFINE_THUMB_DECODER(SWI, SWI, info->op1.immediate = opcode & 0xFF;

@@ -310,7 +314,7 @@

void ARMDecodeThumb(uint16_t opcode, struct ARMInstructionInfo* info) { info->execMode = MODE_THUMB; info->opcode = opcode; - info->branches = 0; + info->branchType = ARM_BRANCH_NONE; info->traps = 0; info->affectsCPSR = 0; info->condition = ARM_CONDITION_AL;
M src/arm/decoder.hsrc/arm/decoder.h

@@ -108,6 +108,13 @@ ARM_ACCESS_TRANSLATED_WORD = 20,

ARM_ACCESS_TRANSLATED_BYTE = 17 }; +enum ARMBranchType { + ARM_BRANCH_NONE = 0, + ARM_BRANCH = 1, + ARM_BRANCH_INDIRECT = 2, + ARM_BRANCH_LINKED = 4 +}; + struct ARMMemoryAccess { uint8_t baseReg; uint8_t width;

@@ -175,17 +182,17 @@ union ARMOperand op4;

struct ARMMemoryAccess memory; int operandFormat; unsigned execMode : 1; - bool branches : 1; bool traps : 1; bool affectsCPSR : 1; + unsigned branchType : 3; unsigned condition : 4; unsigned mnemonic : 6; - unsigned iCycles : 2; + unsigned iCycles : 3; unsigned cCycles : 4; + unsigned sInstructionCycles : 4; + unsigned nInstructionCycles : 4; unsigned sDataCycles : 10; unsigned nDataCycles : 10; - unsigned sInstructionCycles : 4; - unsigned nInstructionCycles : 4; }; void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info);