Use branchType instead of branches in decoder for more expressive branch decoding

This commit is contained in:
Jeffrey Pfau 2014-10-21 00:45:06 -07:00
parent e7bd5f9ade
commit f7b1cee66e
3 changed files with 32 additions and 19 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);