mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 22:00:05 +00:00 
			
		
		
		
	arm_disasm: ARMv6 parallel add/sub media instructions
{S, U, Q, UQ, SH, UH}{ADD16, ASX, SAX, SUB16, ADD8, SUB8}
			
			
This commit is contained in:
		
							parent
							
								
									0be8e1bfb6
								
							
						
					
					
						commit
						4a1db13072
					
				
					 2 changed files with 167 additions and 0 deletions
				
			
		|  | @ -69,18 +69,36 @@ static const char *opcode_names[] = { | |||
|     "orr", | ||||
|     "pkh", | ||||
|     "pld", | ||||
|     "qadd16", | ||||
|     "qadd8", | ||||
|     "qasx", | ||||
|     "qsax", | ||||
|     "qsub16", | ||||
|     "qsub8", | ||||
|     "rev", | ||||
|     "rev16", | ||||
|     "revsh", | ||||
|     "rsb", | ||||
|     "rsc", | ||||
|     "sadd16", | ||||
|     "sadd8", | ||||
|     "sasx", | ||||
|     "sbc", | ||||
|     "sel", | ||||
|     "sev", | ||||
|     "shadd16", | ||||
|     "shadd8", | ||||
|     "shasx", | ||||
|     "shsax", | ||||
|     "shsub16", | ||||
|     "shsub8", | ||||
|     "smlal", | ||||
|     "smull", | ||||
|     "ssat", | ||||
|     "ssat16", | ||||
|     "ssax", | ||||
|     "ssub16", | ||||
|     "ssub8", | ||||
|     "stc", | ||||
|     "stm", | ||||
|     "str", | ||||
|  | @ -104,10 +122,28 @@ static const char *opcode_names[] = { | |||
|     "sxth", | ||||
|     "teq", | ||||
|     "tst", | ||||
|     "uadd16", | ||||
|     "uadd8", | ||||
|     "uasx", | ||||
|     "uhadd16", | ||||
|     "uhadd8", | ||||
|     "uhasx", | ||||
|     "uhsax", | ||||
|     "uhsub16", | ||||
|     "uhsub8", | ||||
|     "umlal", | ||||
|     "umull", | ||||
|     "uqadd16", | ||||
|     "uqadd8", | ||||
|     "uqasx", | ||||
|     "uqsax", | ||||
|     "uqsub16", | ||||
|     "uqsub8", | ||||
|     "usat", | ||||
|     "usat16", | ||||
|     "usax", | ||||
|     "usub16", | ||||
|     "usub8", | ||||
|     "uxtab", | ||||
|     "uxtab16", | ||||
|     "uxtah", | ||||
|  | @ -262,6 +298,43 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) | |||
|             return DisassemblePKH(insn); | ||||
|         case OP_PLD: | ||||
|             return DisassemblePLD(insn); | ||||
|         case OP_QADD16: | ||||
|         case OP_QADD8: | ||||
|         case OP_QASX: | ||||
|         case OP_QSAX: | ||||
|         case OP_QSUB16: | ||||
|         case OP_QSUB8: | ||||
|         case OP_SADD16: | ||||
|         case OP_SADD8: | ||||
|         case OP_SASX: | ||||
|         case OP_SHADD16: | ||||
|         case OP_SHADD8: | ||||
|         case OP_SHASX: | ||||
|         case OP_SHSAX: | ||||
|         case OP_SHSUB16: | ||||
|         case OP_SHSUB8: | ||||
|         case OP_SSAX: | ||||
|         case OP_SSUB16: | ||||
|         case OP_SSUB8: | ||||
|         case OP_UADD16: | ||||
|         case OP_UADD8: | ||||
|         case OP_UASX: | ||||
|         case OP_UHADD16: | ||||
|         case OP_UHADD8: | ||||
|         case OP_UHASX: | ||||
|         case OP_UHSAX: | ||||
|         case OP_UHSUB16: | ||||
|         case OP_UHSUB8: | ||||
|         case OP_UQADD16: | ||||
|         case OP_UQADD8: | ||||
|         case OP_UQASX: | ||||
|         case OP_UQSAX: | ||||
|         case OP_UQSUB16: | ||||
|         case OP_UQSUB8: | ||||
|         case OP_USAX: | ||||
|         case OP_USUB16: | ||||
|         case OP_USUB8: | ||||
|             return DisassembleParallelAddSub(opcode, insn); | ||||
|         case OP_REV: | ||||
|         case OP_REV16: | ||||
|         case OP_REVSH: | ||||
|  | @ -732,6 +805,16 @@ std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, uint32_t insn) | |||
|     return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); | ||||
| } | ||||
| 
 | ||||
| std::string ARM_Disasm::DisassembleParallelAddSub(Opcode opcode, uint32_t insn) { | ||||
|     uint32_t cond = BITS(insn, 28, 31); | ||||
|     uint32_t rn = BITS(insn, 16, 19); | ||||
|     uint32_t rd = BITS(insn, 12, 15); | ||||
|     uint32_t rm = BITS(insn, 0, 3); | ||||
| 
 | ||||
|     return Common::StringFromFormat("%s%s\tr%u, r%u, r%u", opcode_names[opcode], cond_to_str(cond), | ||||
|                                     rd, rn, rm); | ||||
| } | ||||
| 
 | ||||
| std::string ARM_Disasm::DisassemblePKH(uint32_t insn) | ||||
| { | ||||
|     uint32_t cond = BITS(insn, 28, 31); | ||||
|  | @ -1083,6 +1166,49 @@ Opcode ARM_Disasm::DecodeSyncPrimitive(uint32_t insn) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| Opcode ARM_Disasm::DecodeParallelAddSub(uint32_t insn) { | ||||
|     uint32_t op1 = BITS(insn, 20, 21); | ||||
|     uint32_t op2 = BITS(insn, 5, 7); | ||||
|     uint32_t is_unsigned = BIT(insn, 22); | ||||
| 
 | ||||
|     if (op1 == 0x0 || op2 == 0x5 || op2 == 0x6) | ||||
|         return OP_UNDEFINED; | ||||
| 
 | ||||
|     // change op1 range from [1, 3] to range [0, 2]
 | ||||
|     op1--; | ||||
| 
 | ||||
|     // change op2 range from [0, 4] U {7} to range [0, 5]
 | ||||
|     if (op2 == 0x7) | ||||
|         op2 = 0x5; | ||||
| 
 | ||||
|     static std::vector<Opcode> opcodes = { | ||||
|         // op1 = 0
 | ||||
|         OP_SADD16, OP_UADD16, | ||||
|         OP_SASX, OP_UASX, | ||||
|         OP_SSAX, OP_USAX, | ||||
|         OP_SSUB16, OP_USUB16, | ||||
|         OP_SADD8, OP_UADD8, | ||||
|         OP_SSUB8, OP_USUB8, | ||||
|         // op1 = 1
 | ||||
|         OP_QADD16, OP_UQADD16, | ||||
|         OP_QASX, OP_UQASX, | ||||
|         OP_QSAX, OP_UQSAX, | ||||
|         OP_QSUB16, OP_UQSUB16, | ||||
|         OP_QADD8, OP_UQADD8, | ||||
|         OP_QSUB8, OP_UQSUB8, | ||||
|         // op1 = 2
 | ||||
|         OP_SHADD16, OP_UHADD16, | ||||
|         OP_SHASX, OP_UHASX, | ||||
|         OP_SHSAX, OP_UHSAX, | ||||
|         OP_SHSUB16, OP_UHSUB16, | ||||
|         OP_SHADD8, OP_UHADD8, | ||||
|         OP_SHSUB8, OP_UHSUB8 | ||||
|     }; | ||||
| 
 | ||||
|     uint32_t opcode_index = op1 * 12 + op2 * 2 + is_unsigned; | ||||
|     return opcodes[opcode_index]; | ||||
| } | ||||
| 
 | ||||
| Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { | ||||
|     uint32_t op1 = BITS(insn, 20, 22); | ||||
|     uint32_t a = BITS(insn, 16, 19); | ||||
|  | @ -1220,6 +1346,9 @@ Opcode ARM_Disasm::DecodeMedia(uint32_t insn) { | |||
|     uint32_t rn = BITS(insn, 0, 3); | ||||
| 
 | ||||
|     switch (BITS(op1, 3, 4)) { | ||||
|         case 0x0: | ||||
|             // unsigned and signed parallel addition and subtraction
 | ||||
|             return DecodeParallelAddSub(insn); | ||||
|         case 0x1: | ||||
|             // Packing, unpacking, saturation, and reversal
 | ||||
|             return DecodePackingSaturationReversal(insn); | ||||
|  |  | |||
|  | @ -50,18 +50,36 @@ enum Opcode { | |||
|     OP_ORR, | ||||
|     OP_PKH, | ||||
|     OP_PLD, | ||||
|     OP_QADD16, | ||||
|     OP_QADD8, | ||||
|     OP_QASX, | ||||
|     OP_QSAX, | ||||
|     OP_QSUB16, | ||||
|     OP_QSUB8, | ||||
|     OP_REV, | ||||
|     OP_REV16, | ||||
|     OP_REVSH, | ||||
|     OP_RSB, | ||||
|     OP_RSC, | ||||
|     OP_SADD16, | ||||
|     OP_SADD8, | ||||
|     OP_SASX, | ||||
|     OP_SBC, | ||||
|     OP_SEL, | ||||
|     OP_SEV, | ||||
|     OP_SHADD16, | ||||
|     OP_SHADD8, | ||||
|     OP_SHASX, | ||||
|     OP_SHSAX, | ||||
|     OP_SHSUB16, | ||||
|     OP_SHSUB8, | ||||
|     OP_SMLAL, | ||||
|     OP_SMULL, | ||||
|     OP_SSAT, | ||||
|     OP_SSAT16, | ||||
|     OP_SSAX, | ||||
|     OP_SSUB16, | ||||
|     OP_SSUB8, | ||||
|     OP_STC, | ||||
|     OP_STM, | ||||
|     OP_STR, | ||||
|  | @ -85,10 +103,28 @@ enum Opcode { | |||
|     OP_SXTH, | ||||
|     OP_TEQ, | ||||
|     OP_TST, | ||||
|     OP_UADD16, | ||||
|     OP_UADD8, | ||||
|     OP_UASX, | ||||
|     OP_UHADD16, | ||||
|     OP_UHADD8, | ||||
|     OP_UHASX, | ||||
|     OP_UHSAX, | ||||
|     OP_UHSUB16, | ||||
|     OP_UHSUB8, | ||||
|     OP_UMLAL, | ||||
|     OP_UMULL, | ||||
|     OP_UQADD16, | ||||
|     OP_UQADD8, | ||||
|     OP_UQASX, | ||||
|     OP_UQSAX, | ||||
|     OP_UQSUB16, | ||||
|     OP_UQSUB8, | ||||
|     OP_USAT, | ||||
|     OP_USAT16, | ||||
|     OP_USAX, | ||||
|     OP_USUB16, | ||||
|     OP_USUB8, | ||||
|     OP_UXTAB, | ||||
|     OP_UXTAB16, | ||||
|     OP_UXTAH, | ||||
|  | @ -153,6 +189,7 @@ class ARM_Disasm { | |||
|   static Opcode Decode10(uint32_t insn); | ||||
|   static Opcode Decode11(uint32_t insn); | ||||
|   static Opcode DecodeSyncPrimitive(uint32_t insn); | ||||
|   static Opcode DecodeParallelAddSub(uint32_t insn); | ||||
|   static Opcode DecodePackingSaturationReversal(uint32_t insn); | ||||
|   static Opcode DecodeMUL(uint32_t insn); | ||||
|   static Opcode DecodeMSRImmAndHints(uint32_t insn); | ||||
|  | @ -175,6 +212,7 @@ class ARM_Disasm { | |||
|   static std::string DisassembleMRS(uint32_t insn); | ||||
|   static std::string DisassembleMSR(uint32_t insn); | ||||
|   static std::string DisassembleNoOperands(Opcode opcode, uint32_t insn); | ||||
|   static std::string DisassembleParallelAddSub(Opcode opcode, uint32_t insn); | ||||
|   static std::string DisassemblePKH(uint32_t insn); | ||||
|   static std::string DisassemblePLD(uint32_t insn); | ||||
|   static std::string DisassembleREV(Opcode opcode, uint32_t insn); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue