mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	arm_disasm: ARMv6 saturation media instructions
SSAT, SSAT16, USAT, USAT16
This commit is contained in:
		
							parent
							
								
									47657a1817
								
							
						
					
					
						commit
						e4ff244288
					
				
					 2 changed files with 55 additions and 2 deletions
				
			
		|  | @ -76,6 +76,8 @@ static const char *opcode_names[] = { | ||||||
|     "sev", |     "sev", | ||||||
|     "smlal", |     "smlal", | ||||||
|     "smull", |     "smull", | ||||||
|  |     "ssat", | ||||||
|  |     "ssat16", | ||||||
|     "stc", |     "stc", | ||||||
|     "stm", |     "stm", | ||||||
|     "str", |     "str", | ||||||
|  | @ -101,6 +103,8 @@ static const char *opcode_names[] = { | ||||||
|     "tst", |     "tst", | ||||||
|     "umlal", |     "umlal", | ||||||
|     "umull", |     "umull", | ||||||
|  |     "usat", | ||||||
|  |     "usat16", | ||||||
|     "uxtab", |     "uxtab", | ||||||
|     "uxtab16", |     "uxtab16", | ||||||
|     "uxtah", |     "uxtah", | ||||||
|  | @ -257,6 +261,11 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) | ||||||
|             return DisassemblePLD(insn); |             return DisassemblePLD(insn); | ||||||
|         case OP_SEL: |         case OP_SEL: | ||||||
|             return DisassembleSEL(insn); |             return DisassembleSEL(insn); | ||||||
|  |         case OP_SSAT: | ||||||
|  |         case OP_SSAT16: | ||||||
|  |         case OP_USAT: | ||||||
|  |         case OP_USAT16: | ||||||
|  |             return DisassembleSAT(opcode, insn); | ||||||
|         case OP_STC: |         case OP_STC: | ||||||
|             return "stc"; |             return "stc"; | ||||||
|         case OP_SWI: |         case OP_SWI: | ||||||
|  | @ -793,8 +802,35 @@ std::string ARM_Disasm::DisassembleREX(Opcode opcode, uint32_t insn) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string ARM_Disasm::DisassembleSEL(uint32_t insn) | std::string ARM_Disasm::DisassembleSAT(Opcode opcode, uint32_t insn) { | ||||||
| { |     uint32_t cond = BITS(insn, 28, 31); | ||||||
|  |     uint32_t sat_imm = BITS(insn, 16, 20); | ||||||
|  |     uint32_t rd = BITS(insn, 12, 15); | ||||||
|  |     uint32_t imm5 = BITS(insn, 7, 11); | ||||||
|  |     uint32_t sh = BIT(insn, 6); | ||||||
|  |     uint32_t rn = BITS(insn, 0, 3); | ||||||
|  | 
 | ||||||
|  |     std::string shift_part = ""; | ||||||
|  |     bool opcode_has_shift = (opcode == OP_SSAT) || (opcode == OP_USAT); | ||||||
|  |     if (opcode_has_shift && !(sh == 0 && imm5 == 0)) { | ||||||
|  |         if (sh == 0) | ||||||
|  |             shift_part += ", LSL #"; | ||||||
|  |         else | ||||||
|  |             shift_part += ", ASR #"; | ||||||
|  | 
 | ||||||
|  |         if (imm5 == 0) | ||||||
|  |             imm5 = 32; | ||||||
|  |         shift_part += std::to_string(imm5); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (opcode == OP_SSAT || opcode == OP_SSAT16) | ||||||
|  |         sat_imm++; | ||||||
|  | 
 | ||||||
|  |     return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], cond_to_str(cond), rd, | ||||||
|  |                                     sat_imm, rn, shift_part.c_str()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string ARM_Disasm::DisassembleSEL(uint32_t insn) { | ||||||
|     uint32_t cond = BITS(insn, 28, 31); |     uint32_t cond = BITS(insn, 28, 31); | ||||||
|     uint32_t rn = BITS(insn, 16, 19); |     uint32_t rn = BITS(insn, 16, 19); | ||||||
|     uint32_t rd = BITS(insn, 12, 15); |     uint32_t rd = BITS(insn, 12, 15); | ||||||
|  | @ -1048,12 +1084,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { | ||||||
|                 return OP_SEL; |                 return OP_SEL; | ||||||
|             break; |             break; | ||||||
|         case 0x2: |         case 0x2: | ||||||
|  |             if (BIT(op2, 0) == 0) | ||||||
|  |                 return OP_SSAT; | ||||||
|  |             if (op2 == 0x1) | ||||||
|  |                 return OP_SSAT16; | ||||||
|             if (op2 == 0x3 && a != 0xf) |             if (op2 == 0x3 && a != 0xf) | ||||||
|                 return OP_SXTAB; |                 return OP_SXTAB; | ||||||
|             if (op2 == 0x3 && a == 0xf) |             if (op2 == 0x3 && a == 0xf) | ||||||
|                 return OP_SXTB; |                 return OP_SXTB; | ||||||
|             break; |             break; | ||||||
|         case 0x3: |         case 0x3: | ||||||
|  |             if (BIT(op2, 0) == 0) | ||||||
|  |                 return OP_SSAT; | ||||||
|             if (op2 == 0x3 && a != 0xf) |             if (op2 == 0x3 && a != 0xf) | ||||||
|                 return OP_SXTAH; |                 return OP_SXTAH; | ||||||
|             if (op2 == 0x3 && a == 0xf) |             if (op2 == 0x3 && a == 0xf) | ||||||
|  | @ -1066,12 +1108,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { | ||||||
|                 return OP_UXTB16; |                 return OP_UXTB16; | ||||||
|             break; |             break; | ||||||
|         case 0x6: |         case 0x6: | ||||||
|  |             if (BIT(op2, 0) == 0) | ||||||
|  |                 return OP_USAT; | ||||||
|  |             if (op2 == 0x1) | ||||||
|  |                 return OP_USAT16; | ||||||
|             if (op2 == 0x3 && a != 0xf) |             if (op2 == 0x3 && a != 0xf) | ||||||
|                 return OP_UXTAB; |                 return OP_UXTAB; | ||||||
|             if (op2 == 0x3 && a == 0xf) |             if (op2 == 0x3 && a == 0xf) | ||||||
|                 return OP_UXTB; |                 return OP_UXTB; | ||||||
|             break; |             break; | ||||||
|         case 0x7: |         case 0x7: | ||||||
|  |             if (BIT(op2, 0) == 0) | ||||||
|  |                 return OP_USAT; | ||||||
|             if (op2 == 0x3 && a != 0xf) |             if (op2 == 0x3 && a != 0xf) | ||||||
|                 return OP_UXTAH; |                 return OP_UXTAH; | ||||||
|             if (op2 == 0x3 && a == 0xf) |             if (op2 == 0x3 && a == 0xf) | ||||||
|  |  | ||||||
|  | @ -57,6 +57,8 @@ enum Opcode { | ||||||
|     OP_SEV, |     OP_SEV, | ||||||
|     OP_SMLAL, |     OP_SMLAL, | ||||||
|     OP_SMULL, |     OP_SMULL, | ||||||
|  |     OP_SSAT, | ||||||
|  |     OP_SSAT16, | ||||||
|     OP_STC, |     OP_STC, | ||||||
|     OP_STM, |     OP_STM, | ||||||
|     OP_STR, |     OP_STR, | ||||||
|  | @ -82,6 +84,8 @@ enum Opcode { | ||||||
|     OP_TST, |     OP_TST, | ||||||
|     OP_UMLAL, |     OP_UMLAL, | ||||||
|     OP_UMULL, |     OP_UMULL, | ||||||
|  |     OP_USAT, | ||||||
|  |     OP_USAT16, | ||||||
|     OP_UXTAB, |     OP_UXTAB, | ||||||
|     OP_UXTAB16, |     OP_UXTAB16, | ||||||
|     OP_UXTAH, |     OP_UXTAH, | ||||||
|  | @ -171,6 +175,7 @@ class ARM_Disasm { | ||||||
|   static std::string DisassemblePKH(uint32_t insn); |   static std::string DisassemblePKH(uint32_t insn); | ||||||
|   static std::string DisassemblePLD(uint32_t insn); |   static std::string DisassemblePLD(uint32_t insn); | ||||||
|   static std::string DisassembleREX(Opcode opcode, uint32_t insn); |   static std::string DisassembleREX(Opcode opcode, uint32_t insn); | ||||||
|  |   static std::string DisassembleSAT(Opcode opcode, uint32_t insn); | ||||||
|   static std::string DisassembleSEL(uint32_t insn); |   static std::string DisassembleSEL(uint32_t insn); | ||||||
|   static std::string DisassembleSWI(uint32_t insn); |   static std::string DisassembleSWI(uint32_t insn); | ||||||
|   static std::string DisassembleSWP(Opcode opcode, uint32_t insn); |   static std::string DisassembleSWP(Opcode opcode, uint32_t insn); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue