mirror of https://github.com/mgba-emu/mgba.git
Use branchType instead of branches in decoder for more expressive branch decoding
This commit is contained in:
parent
e7bd5f9ade
commit
f7b1cee66e
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue