diff --git a/src/arm/decoder-arm.c b/src/arm/decoder-arm.c index ee299369a..906289e02 100644 --- a/src/arm/decoder-arm.c +++ b/src/arm/decoder-arm.c @@ -110,7 +110,7 @@ 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 @@ 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_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_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 @@ static const ARMDecoder _armDecoderTable[0x1000] = { 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; diff --git a/src/arm/decoder-thumb.c b/src/arm/decoder-thumb.c index b3c9e1d6e..f460d4677 100644 --- a/src/arm/decoder-thumb.c +++ b/src/arm/decoder-thumb.c @@ -135,7 +135,9 @@ DEFINE_DATA_FORM_5_DECODER_THUMB(MVN, MVN, ARM_OPERAND_AFFECTED_1) 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_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, STR, STORE_CYCLES, ARM_ACCESS_HALFW 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_LOAD_STORE_MULTIPLE_THUMB(STM) 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(BL1, BLH, 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 @@ static const ThumbDecoder _thumbDecoderTable[0x400] = { 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; diff --git a/src/arm/decoder.h b/src/arm/decoder.h index 7fa702832..12ff699f7 100644 --- a/src/arm/decoder.h +++ b/src/arm/decoder.h @@ -108,6 +108,13 @@ enum ARMMemoryAccessType { 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 @@ struct ARMInstructionInfo { 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 sDataCycles : 10; - unsigned nDataCycles : 10; unsigned sInstructionCycles : 4; unsigned nInstructionCycles : 4; + unsigned sDataCycles : 10; + unsigned nDataCycles : 10; }; void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info);