summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Lioncash2015-07-27 23:45:24 -0400
committerGravatar Lioncash2015-07-28 02:27:57 -0400
commit89540ea7618fbaca1c9cd332b24aff7f2865d324 (patch)
treed5e25da76e20be36e3016beb363b2c25071d9c36
parentdyncom: Remove code duplication regarding thumb instructions (diff)
downloadyuzu-89540ea7618fbaca1c9cd332b24aff7f2865d324.tar.gz
yuzu-89540ea7618fbaca1c9cd332b24aff7f2865d324.tar.xz
yuzu-89540ea7618fbaca1c9cd332b24aff7f2865d324.zip
dyncom: Use enum class for instruction decoding results
Diffstat (limited to '')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp19
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h10
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp19
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp20
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h13
5 files changed, 40 insertions, 41 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 3ab9f2c17..48fc1c683 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -414,14 +414,13 @@ const ISEITEM arm_exclusion_code[] = {
414 { "invalid", 0, INVALID, { 0 }} 414 { "invalid", 0, INVALID, { 0 }}
415}; 415};
416 416
417int decode_arm_instr(u32 instr, s32* idx) { 417ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) {
418 int n = 0; 418 int n = 0;
419 int base = 0; 419 int base = 0;
420 int ret = DECODE_FAILURE;
421 int i = 0;
422 int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); 420 int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
421 ARMDecodeStatus ret = ARMDecodeStatus::FAILURE;
423 422
424 for (i = 0; i < instr_slots; i++) { 423 for (int i = 0; i < instr_slots; i++) {
425 n = arm_instruction[i].attribute_value; 424 n = arm_instruction[i].attribute_value;
426 base = 0; 425 base = 0;
427 426
@@ -438,11 +437,11 @@ int decode_arm_instr(u32 instr, s32* idx) {
438 n--; 437 n--;
439 } 438 }
440 439
441 // All conditions is satisfied. 440 // All conditions are satisfied.
442 if (n == 0) 441 if (n == 0)
443 ret = DECODE_SUCCESS; 442 ret = ARMDecodeStatus::SUCCESS;
444 443
445 if (ret == DECODE_SUCCESS) { 444 if (ret == ARMDecodeStatus::SUCCESS) {
446 n = arm_exclusion_code[i].attribute_value; 445 n = arm_exclusion_code[i].attribute_value;
447 if (n != 0) { 446 if (n != 0) {
448 base = 0; 447 base = 0;
@@ -454,13 +453,13 @@ int decode_arm_instr(u32 instr, s32* idx) {
454 n--; 453 n--;
455 } 454 }
456 455
457 // All conditions is satisfied. 456 // All conditions are satisfied.
458 if (n == 0) 457 if (n == 0)
459 ret = DECODE_FAILURE; 458 ret = ARMDecodeStatus::FAILURE;
460 } 459 }
461 } 460 }
462 461
463 if (ret == DECODE_SUCCESS) { 462 if (ret == ARMDecodeStatus::SUCCESS) {
464 *idx = i; 463 *idx = i;
465 return ret; 464 return ret;
466 } 465 }
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
index 5f6279627..80d910218 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -6,13 +6,13 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9int decode_arm_instr(u32 instr, s32* idx); 9enum class ARMDecodeStatus {
10 10 SUCCESS,
11enum DECODE_STATUS { 11 FAILURE
12 DECODE_SUCCESS,
13 DECODE_FAILURE
14}; 12};
15 13
14ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx);
15
16struct instruction_set_encoding_item { 16struct instruction_set_encoding_item {
17 const char *name; 17 const char *name;
18 int attribute_value; 18 int attribute_value;
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index cdef72be6..d022546ed 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -3468,10 +3468,10 @@ enum {
3468 FETCH_FAILURE 3468 FETCH_FAILURE
3469}; 3469};
3470 3470
3471static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { 3471static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) {
3472 // Check if in Thumb mode 3472 // Check if in Thumb mode
3473 tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); 3473 ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
3474 if (ret == t_branch) { 3474 if (ret == ThumbDecodeStatus::BRANCH) {
3475 int inst_index; 3475 int inst_index;
3476 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); 3476 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
3477 u32 tinstr = GetThumbInstruction(inst, addr); 3477 u32 tinstr = GetThumbInstruction(inst, addr);
@@ -3509,7 +3509,7 @@ static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_s
3509 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); 3509 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3510 break; 3510 break;
3511 default: 3511 default:
3512 ret = t_undefined; 3512 ret = ThumbDecodeStatus::UNDEFINED;
3513 break; 3513 break;
3514 } 3514 }
3515 } 3515 }
@@ -3542,20 +3542,19 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
3542 inst = Memory::Read32(phys_addr & 0xFFFFFFFC); 3542 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
3543 3543
3544 size++; 3544 size++;
3545 // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction 3545 // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction
3546 if (cpu->TFlag) { 3546 if (cpu->TFlag) {
3547 uint32_t arm_inst; 3547 uint32_t arm_inst;
3548 tdstate state = decode_thumb_instr(inst, phys_addr, &arm_inst, &inst_size, &inst_base); 3548 ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
3549 3549
3550 // We have translated the branch instruction of thumb in thumb decoder 3550 // We have translated the Thumb branch instruction in the Thumb decoder
3551 if(state == t_branch){ 3551 if (state == ThumbDecodeStatus::BRANCH) {
3552 goto translated; 3552 goto translated;
3553 } 3553 }
3554 inst = arm_inst; 3554 inst = arm_inst;
3555 } 3555 }
3556 3556
3557 ret = decode_arm_instr(inst, &idx); 3557 if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
3558 if (ret == DECODE_FAILURE) {
3559 std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); 3558 std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst);
3560 LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); 3559 LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst);
3561 LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); 3560 LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index 6eb03fb5a..29272fd5d 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -12,8 +12,8 @@
12// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions 12// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
13// allows easier simulation of the special dual BL instruction. 13// allows easier simulation of the special dual BL instruction.
14 14
15tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { 15ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
16 tdstate valid = t_uninitialized; 16 ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED;
17 u32 tinstr = GetThumbInstruction(instr, addr); 17 u32 tinstr = GetThumbInstruction(instr, addr);
18 18
19 *ainstr = 0xDEADC0DE; // Debugging to catch non updates 19 *ainstr = 0xDEADC0DE; // Debugging to catch non updates
@@ -351,21 +351,21 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
351 else 351 else
352 *ainstr |= (tinstr & 0x00FF); 352 *ainstr |= (tinstr & 0x00FF);
353 } else if ((tinstr & 0x0F00) != 0x0E00) 353 } else if ((tinstr & 0x0F00) != 0x0E00)
354 valid = t_branch; 354 valid = ThumbDecodeStatus::BRANCH;
355 else // UNDEFINED : cc=1110(AL) uses different format 355 else // UNDEFINED : cc=1110(AL) uses different format
356 valid = t_undefined; 356 valid = ThumbDecodeStatus::UNDEFINED;
357 357
358 break; 358 break;
359 359
360 case 28: // B 360 case 28: // B
361 valid = t_branch; 361 valid = ThumbDecodeStatus::BRANCH;
362 break; 362 break;
363 363
364 case 29: 364 case 29:
365 if(tinstr & 0x1) 365 if (tinstr & 0x1)
366 valid = t_undefined; 366 valid = ThumbDecodeStatus::UNDEFINED;
367 else 367 else
368 valid = t_branch; 368 valid = ThumbDecodeStatus::BRANCH;
369 break; 369 break;
370 370
371 case 30: // BL instruction 1 371 case 30: // BL instruction 1
@@ -374,7 +374,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
374 // simulation simple (from the user perspective) we check if the following instruction is 374 // simulation simple (from the user perspective) we check if the following instruction is
375 // the second half of this BL, and if it is we simulate it immediately 375 // the second half of this BL, and if it is we simulate it immediately
376 376
377 valid = t_branch; 377 valid = ThumbDecodeStatus::BRANCH;
378 break; 378 break;
379 379
380 case 31: // BL instruction 2 380 case 31: // BL instruction 2
@@ -383,7 +383,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
383 // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the 383 // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the
384 // simulation of it on its own, with undefined results if r14 is not suitably initialised. 384 // simulation of it on its own, with undefined results if r14 is not suitably initialised.
385 385
386 valid = t_branch; 386 valid = ThumbDecodeStatus::BRANCH;
387 break; 387 break;
388 } 388 }
389 389
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index 74e69e13a..447974363 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -28,14 +28,15 @@
28 28
29#include "common/common_types.h" 29#include "common/common_types.h"
30 30
31enum tdstate { 31enum class ThumbDecodeStatus {
32 t_undefined, // Undefined Thumb instruction 32 UNDEFINED, // Undefined Thumb instruction
33 t_decoded, // Instruction decoded to ARM equivalent 33 DECODED, // Instruction decoded to ARM equivalent
34 t_branch, // Thumb branch (already processed) 34 BRANCH, // Thumb branch (already processed)
35 t_uninitialized, 35 UNINITIALIZED,
36}; 36};
37 37
38tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size); 38// Translates a Thumb mode instruction into its ARM equivalent.
39ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size);
39 40
40static inline u32 GetThumbInstruction(u32 instr, u32 address) { 41static inline u32 GetThumbInstruction(u32 instr, u32 address) {
41 // Normally you would need to handle instruction endianness, 42 // Normally you would need to handle instruction endianness,