yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

dyncom: Use enum class for instruction decoding results

This commit is contained in:
Lioncash 2015-07-27 23:45:24 -04:00
parent 7e4fb4db19
commit 89540ea761
5 changed files with 40 additions and 41 deletions

View File

@ -414,14 +414,13 @@ const ISEITEM arm_exclusion_code[] = {
{ "invalid", 0, INVALID, { 0 }} { "invalid", 0, INVALID, { 0 }}
}; };
int decode_arm_instr(u32 instr, s32* idx) { ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) {
int n = 0; int n = 0;
int base = 0; int base = 0;
int ret = DECODE_FAILURE;
int i = 0;
int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
ARMDecodeStatus ret = ARMDecodeStatus::FAILURE;
for (i = 0; i < instr_slots; i++) { for (int i = 0; i < instr_slots; i++) {
n = arm_instruction[i].attribute_value; n = arm_instruction[i].attribute_value;
base = 0; base = 0;
@ -438,11 +437,11 @@ int decode_arm_instr(u32 instr, s32* idx) {
n--; n--;
} }
// All conditions is satisfied. // All conditions are satisfied.
if (n == 0) if (n == 0)
ret = DECODE_SUCCESS; ret = ARMDecodeStatus::SUCCESS;
if (ret == DECODE_SUCCESS) { if (ret == ARMDecodeStatus::SUCCESS) {
n = arm_exclusion_code[i].attribute_value; n = arm_exclusion_code[i].attribute_value;
if (n != 0) { if (n != 0) {
base = 0; base = 0;
@ -454,13 +453,13 @@ int decode_arm_instr(u32 instr, s32* idx) {
n--; n--;
} }
// All conditions is satisfied. // All conditions are satisfied.
if (n == 0) if (n == 0)
ret = DECODE_FAILURE; ret = ARMDecodeStatus::FAILURE;
} }
} }
if (ret == DECODE_SUCCESS) { if (ret == ARMDecodeStatus::SUCCESS) {
*idx = i; *idx = i;
return ret; return ret;
} }

View File

@ -6,13 +6,13 @@
#include "common/common_types.h" #include "common/common_types.h"
int decode_arm_instr(u32 instr, s32* idx); enum class ARMDecodeStatus {
SUCCESS,
enum DECODE_STATUS { FAILURE
DECODE_SUCCESS,
DECODE_FAILURE
}; };
ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx);
struct instruction_set_encoding_item { struct instruction_set_encoding_item {
const char *name; const char *name;
int attribute_value; int attribute_value;

View File

@ -3468,10 +3468,10 @@ enum {
FETCH_FAILURE FETCH_FAILURE
}; };
static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) {
// Check if in Thumb mode // Check if in Thumb mode
tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
if (ret == t_branch) { if (ret == ThumbDecodeStatus::BRANCH) {
int inst_index; int inst_index;
int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
u32 tinstr = GetThumbInstruction(inst, addr); u32 tinstr = GetThumbInstruction(inst, addr);
@ -3509,7 +3509,7 @@ static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_s
*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
break; break;
default: default:
ret = t_undefined; ret = ThumbDecodeStatus::UNDEFINED;
break; break;
} }
} }
@ -3542,20 +3542,19 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
inst = Memory::Read32(phys_addr & 0xFFFFFFFC); inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
size++; size++;
// If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction
if (cpu->TFlag) { if (cpu->TFlag) {
uint32_t arm_inst; uint32_t arm_inst;
tdstate state = decode_thumb_instr(inst, phys_addr, &arm_inst, &inst_size, &inst_base); ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
// We have translated the branch instruction of thumb in thumb decoder // We have translated the Thumb branch instruction in the Thumb decoder
if(state == t_branch){ if (state == ThumbDecodeStatus::BRANCH) {
goto translated; goto translated;
} }
inst = arm_inst; inst = arm_inst;
} }
ret = decode_arm_instr(inst, &idx); if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
if (ret == DECODE_FAILURE) {
std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst);
LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst);
LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);

View File

@ -12,8 +12,8 @@
// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions // with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
// allows easier simulation of the special dual BL instruction. // allows easier simulation of the special dual BL instruction.
tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
tdstate valid = t_uninitialized; ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED;
u32 tinstr = GetThumbInstruction(instr, addr); u32 tinstr = GetThumbInstruction(instr, addr);
*ainstr = 0xDEADC0DE; // Debugging to catch non updates *ainstr = 0xDEADC0DE; // Debugging to catch non updates
@ -351,21 +351,21 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
else else
*ainstr |= (tinstr & 0x00FF); *ainstr |= (tinstr & 0x00FF);
} else if ((tinstr & 0x0F00) != 0x0E00) } else if ((tinstr & 0x0F00) != 0x0E00)
valid = t_branch; valid = ThumbDecodeStatus::BRANCH;
else // UNDEFINED : cc=1110(AL) uses different format else // UNDEFINED : cc=1110(AL) uses different format
valid = t_undefined; valid = ThumbDecodeStatus::UNDEFINED;
break; break;
case 28: // B case 28: // B
valid = t_branch; valid = ThumbDecodeStatus::BRANCH;
break; break;
case 29: case 29:
if(tinstr & 0x1) if (tinstr & 0x1)
valid = t_undefined; valid = ThumbDecodeStatus::UNDEFINED;
else else
valid = t_branch; valid = ThumbDecodeStatus::BRANCH;
break; break;
case 30: // BL instruction 1 case 30: // BL instruction 1
@ -374,7 +374,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
// simulation simple (from the user perspective) we check if the following instruction is // simulation simple (from the user perspective) we check if the following instruction is
// the second half of this BL, and if it is we simulate it immediately // the second half of this BL, and if it is we simulate it immediately
valid = t_branch; valid = ThumbDecodeStatus::BRANCH;
break; break;
case 31: // BL instruction 2 case 31: // BL instruction 2
@ -383,7 +383,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
// ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the
// simulation of it on its own, with undefined results if r14 is not suitably initialised. // simulation of it on its own, with undefined results if r14 is not suitably initialised.
valid = t_branch; valid = ThumbDecodeStatus::BRANCH;
break; break;
} }

View File

@ -28,14 +28,15 @@
#include "common/common_types.h" #include "common/common_types.h"
enum tdstate { enum class ThumbDecodeStatus {
t_undefined, // Undefined Thumb instruction UNDEFINED, // Undefined Thumb instruction
t_decoded, // Instruction decoded to ARM equivalent DECODED, // Instruction decoded to ARM equivalent
t_branch, // Thumb branch (already processed) BRANCH, // Thumb branch (already processed)
t_uninitialized, UNINITIALIZED,
}; };
tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size); // Translates a Thumb mode instruction into its ARM equivalent.
ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size);
static inline u32 GetThumbInstruction(u32 instr, u32 address) { static inline u32 GetThumbInstruction(u32 instr, u32 address) {
// Normally you would need to handle instruction endianness, // Normally you would need to handle instruction endianness,