mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	dyncom: Use enum class for instruction decoding results
This commit is contained in:
		
							parent
							
								
									7e4fb4db19
								
							
						
					
					
						commit
						89540ea761
					
				
					 5 changed files with 40 additions and 41 deletions
				
			
		|  | @ -414,14 +414,13 @@ const ISEITEM arm_exclusion_code[] = { | |||
|     { "invalid", 0, INVALID,     { 0 }} | ||||
| }; | ||||
| 
 | ||||
| int decode_arm_instr(u32 instr, s32* idx) { | ||||
| ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) { | ||||
|     int n = 0; | ||||
|     int base = 0; | ||||
|     int ret = DECODE_FAILURE; | ||||
|     int i = 0; | ||||
|     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; | ||||
|         base = 0; | ||||
| 
 | ||||
|  | @ -438,11 +437,11 @@ int decode_arm_instr(u32 instr, s32* idx) { | |||
|             n--; | ||||
|         } | ||||
| 
 | ||||
|         // All conditions is satisfied.
 | ||||
|         // All conditions are satisfied.
 | ||||
|         if (n == 0) | ||||
|             ret = DECODE_SUCCESS; | ||||
|             ret = ARMDecodeStatus::SUCCESS; | ||||
| 
 | ||||
|         if (ret == DECODE_SUCCESS) { | ||||
|         if (ret == ARMDecodeStatus::SUCCESS) { | ||||
|             n = arm_exclusion_code[i].attribute_value; | ||||
|             if (n != 0) { | ||||
|                 base = 0; | ||||
|  | @ -454,13 +453,13 @@ int decode_arm_instr(u32 instr, s32* idx) { | |||
|                     n--; | ||||
|                 } | ||||
| 
 | ||||
|                 // All conditions is satisfied.
 | ||||
|                 // All conditions are satisfied.
 | ||||
|                 if (n == 0) | ||||
|                     ret = DECODE_FAILURE; | ||||
|                     ret = ARMDecodeStatus::FAILURE; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (ret == DECODE_SUCCESS) { | ||||
|         if (ret == ARMDecodeStatus::SUCCESS) { | ||||
|             *idx = i; | ||||
|             return ret; | ||||
|         } | ||||
|  |  | |||
|  | @ -6,13 +6,13 @@ | |||
| 
 | ||||
| #include "common/common_types.h" | ||||
| 
 | ||||
| int decode_arm_instr(u32 instr, s32* idx); | ||||
| 
 | ||||
| enum DECODE_STATUS { | ||||
|     DECODE_SUCCESS, | ||||
|     DECODE_FAILURE | ||||
| enum class ARMDecodeStatus { | ||||
|     SUCCESS, | ||||
|     FAILURE | ||||
| }; | ||||
| 
 | ||||
| ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx); | ||||
| 
 | ||||
| struct instruction_set_encoding_item { | ||||
|     const char *name; | ||||
|     int attribute_value; | ||||
|  |  | |||
|  | @ -3468,10 +3468,10 @@ enum { | |||
|     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
 | ||||
|     tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); | ||||
|     if (ret == t_branch) { | ||||
|     ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size); | ||||
|     if (ret == ThumbDecodeStatus::BRANCH) { | ||||
|         int inst_index; | ||||
|         int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); | ||||
|         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); | ||||
|             break; | ||||
|         default: | ||||
|             ret = t_undefined; | ||||
|             ret = ThumbDecodeStatus::UNDEFINED; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | @ -3542,20 +3542,19 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { | |||
|         inst = Memory::Read32(phys_addr & 0xFFFFFFFC); | ||||
| 
 | ||||
|         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) { | ||||
|             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
 | ||||
|             if(state == t_branch){ | ||||
|             // We have translated the Thumb branch instruction in the Thumb decoder
 | ||||
|             if (state == ThumbDecodeStatus::BRANCH) { | ||||
|                 goto translated; | ||||
|             } | ||||
|             inst = arm_inst; | ||||
|         } | ||||
| 
 | ||||
|         ret = decode_arm_instr(inst, &idx); | ||||
|         if (ret == DECODE_FAILURE) { | ||||
|         if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) { | ||||
|             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, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | ||||
|  |  | |||
|  | @ -12,8 +12,8 @@ | |||
| // 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.
 | ||||
| 
 | ||||
| tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | ||||
|     tdstate valid = t_uninitialized; | ||||
| ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | ||||
|     ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED; | ||||
|     u32 tinstr = GetThumbInstruction(instr, addr); | ||||
| 
 | ||||
|     *ainstr = 0xDEADC0DE; // Debugging to catch non updates
 | ||||
|  | @ -351,21 +351,21 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
|             else | ||||
|                 *ainstr |= (tinstr & 0x00FF); | ||||
|         } else if ((tinstr & 0x0F00) != 0x0E00) | ||||
|             valid = t_branch; | ||||
|             valid = ThumbDecodeStatus::BRANCH; | ||||
|         else //  UNDEFINED : cc=1110(AL) uses different format
 | ||||
|             valid = t_undefined; | ||||
|             valid = ThumbDecodeStatus::UNDEFINED; | ||||
| 
 | ||||
|         break; | ||||
| 
 | ||||
|     case 28: // B
 | ||||
|         valid = t_branch; | ||||
|         valid = ThumbDecodeStatus::BRANCH; | ||||
|         break; | ||||
| 
 | ||||
|     case 29: | ||||
|         if (tinstr & 0x1) | ||||
|             valid = t_undefined; | ||||
|             valid = ThumbDecodeStatus::UNDEFINED; | ||||
|         else | ||||
|             valid = t_branch; | ||||
|             valid = ThumbDecodeStatus::BRANCH; | ||||
|         break; | ||||
| 
 | ||||
|     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
 | ||||
|         // the second half of this BL, and if it is we simulate it immediately
 | ||||
| 
 | ||||
|         valid = t_branch; | ||||
|         valid = ThumbDecodeStatus::BRANCH; | ||||
|         break; | ||||
| 
 | ||||
|     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
 | ||||
|         // simulation of it on its own, with undefined results if r14 is not suitably initialised.
 | ||||
| 
 | ||||
|         valid = t_branch; | ||||
|         valid = ThumbDecodeStatus::BRANCH; | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,14 +28,15 @@ | |||
| 
 | ||||
| #include "common/common_types.h" | ||||
| 
 | ||||
| enum tdstate { | ||||
|     t_undefined,    // Undefined Thumb instruction
 | ||||
|     t_decoded,      // Instruction decoded to ARM equivalent
 | ||||
|     t_branch,       // Thumb branch (already processed)
 | ||||
|     t_uninitialized, | ||||
| enum class ThumbDecodeStatus { | ||||
|     UNDEFINED,    // Undefined Thumb instruction
 | ||||
|     DECODED,      // Instruction decoded to ARM equivalent
 | ||||
|     BRANCH,       // Thumb branch (already processed)
 | ||||
|     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) { | ||||
|     // Normally you would need to handle instruction endianness,
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue