arm_disasm: ARMv6 saturation media instructions
SSAT, SSAT16, USAT, USAT16
This commit is contained in:
		| @@ -76,6 +76,8 @@ static const char *opcode_names[] = { | ||||
|     "sev", | ||||
|     "smlal", | ||||
|     "smull", | ||||
|     "ssat", | ||||
|     "ssat16", | ||||
|     "stc", | ||||
|     "stm", | ||||
|     "str", | ||||
| @@ -101,6 +103,8 @@ static const char *opcode_names[] = { | ||||
|     "tst", | ||||
|     "umlal", | ||||
|     "umull", | ||||
|     "usat", | ||||
|     "usat16", | ||||
|     "uxtab", | ||||
|     "uxtab16", | ||||
|     "uxtah", | ||||
| @@ -257,6 +261,11 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) | ||||
|             return DisassemblePLD(insn); | ||||
|         case OP_SEL: | ||||
|             return DisassembleSEL(insn); | ||||
|         case OP_SSAT: | ||||
|         case OP_SSAT16: | ||||
|         case OP_USAT: | ||||
|         case OP_USAT16: | ||||
|             return DisassembleSAT(opcode, insn); | ||||
|         case OP_STC: | ||||
|             return "stc"; | ||||
|         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 rn = BITS(insn, 16, 19); | ||||
|     uint32_t rd = BITS(insn, 12, 15); | ||||
| @@ -1048,12 +1084,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { | ||||
|                 return OP_SEL; | ||||
|             break; | ||||
|         case 0x2: | ||||
|             if (BIT(op2, 0) == 0) | ||||
|                 return OP_SSAT; | ||||
|             if (op2 == 0x1) | ||||
|                 return OP_SSAT16; | ||||
|             if (op2 == 0x3 && a != 0xf) | ||||
|                 return OP_SXTAB; | ||||
|             if (op2 == 0x3 && a == 0xf) | ||||
|                 return OP_SXTB; | ||||
|             break; | ||||
|         case 0x3: | ||||
|             if (BIT(op2, 0) == 0) | ||||
|                 return OP_SSAT; | ||||
|             if (op2 == 0x3 && a != 0xf) | ||||
|                 return OP_SXTAH; | ||||
|             if (op2 == 0x3 && a == 0xf) | ||||
| @@ -1066,12 +1108,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { | ||||
|                 return OP_UXTB16; | ||||
|             break; | ||||
|         case 0x6: | ||||
|             if (BIT(op2, 0) == 0) | ||||
|                 return OP_USAT; | ||||
|             if (op2 == 0x1) | ||||
|                 return OP_USAT16; | ||||
|             if (op2 == 0x3 && a != 0xf) | ||||
|                 return OP_UXTAB; | ||||
|             if (op2 == 0x3 && a == 0xf) | ||||
|                 return OP_UXTB; | ||||
|             break; | ||||
|         case 0x7: | ||||
|             if (BIT(op2, 0) == 0) | ||||
|                 return OP_USAT; | ||||
|             if (op2 == 0x3 && a != 0xf) | ||||
|                 return OP_UXTAH; | ||||
|             if (op2 == 0x3 && a == 0xf) | ||||
|   | ||||
| @@ -57,6 +57,8 @@ enum Opcode { | ||||
|     OP_SEV, | ||||
|     OP_SMLAL, | ||||
|     OP_SMULL, | ||||
|     OP_SSAT, | ||||
|     OP_SSAT16, | ||||
|     OP_STC, | ||||
|     OP_STM, | ||||
|     OP_STR, | ||||
| @@ -82,6 +84,8 @@ enum Opcode { | ||||
|     OP_TST, | ||||
|     OP_UMLAL, | ||||
|     OP_UMULL, | ||||
|     OP_USAT, | ||||
|     OP_USAT16, | ||||
|     OP_UXTAB, | ||||
|     OP_UXTAB16, | ||||
|     OP_UXTAH, | ||||
| @@ -171,6 +175,7 @@ class ARM_Disasm { | ||||
|   static std::string DisassemblePKH(uint32_t insn); | ||||
|   static std::string DisassemblePLD(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 DisassembleSWI(uint32_t insn); | ||||
|   static std::string DisassembleSWP(Opcode opcode, uint32_t insn); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user