From 0be8e1bfb6a7fb37ddc1bdbbc410362b5e5c009e Mon Sep 17 00:00:00 2001 From: aroulin Date: Sun, 9 Aug 2015 13:52:51 +0200 Subject: arm_disasm: ARMv6 reversal media instructions REV, REV16, REVSH Only their ARM encoding, Thumb encoding is still missing. --- src/core/arm/disassembler/arm_disasm.cpp | 22 ++++++++++++++++++++++ src/core/arm/disassembler/arm_disasm.h | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index d73495fe..a03f113b 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp @@ -69,6 +69,9 @@ static const char *opcode_names[] = { "orr", "pkh", "pld", + "rev", + "rev16", + "revsh", "rsb", "rsc", "sbc", @@ -259,6 +262,10 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) return DisassemblePKH(insn); case OP_PLD: return DisassemblePLD(insn); + case OP_REV: + case OP_REV16: + case OP_REVSH: + return DisassembleREV(opcode, insn); case OP_SEL: return DisassembleSEL(insn); case OP_SSAT: @@ -772,6 +779,15 @@ std::string ARM_Disasm::DisassemblePLD(uint32_t insn) } } +std::string ARM_Disasm::DisassembleREV(Opcode opcode, uint32_t insn) { + uint32_t cond = BITS(insn, 28, 31); + uint32_t rd = BITS(insn, 12, 15); + uint32_t rm = BITS(insn, 0, 3); + + return Common::StringFromFormat("%s%s\tr%u, r%u", opcode_names[opcode], cond_to_str(cond), + rd, rm); +} + std::string ARM_Disasm::DisassembleREX(Opcode opcode, uint32_t insn) { uint32_t rn = BITS(insn, 16, 19); uint32_t rd = BITS(insn, 12, 15); @@ -1094,12 +1110,16 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { return OP_SXTB; break; case 0x3: + if (op2 == 0x1) + return OP_REV; if (BIT(op2, 0) == 0) return OP_SSAT; if (op2 == 0x3 && a != 0xf) return OP_SXTAH; if (op2 == 0x3 && a == 0xf) return OP_SXTH; + if (op2 == 0x5) + return OP_REV16; break; case 0x4: if (op2 == 0x3 && a != 0xf) @@ -1124,6 +1144,8 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { return OP_UXTAH; if (op2 == 0x3 && a == 0xf) return OP_UXTH; + if (op2 == 0x5) + return OP_REVSH; break; default: break; diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h index d8d4faf9..a6b34dae 100644 --- a/src/core/arm/disassembler/arm_disasm.h +++ b/src/core/arm/disassembler/arm_disasm.h @@ -50,6 +50,9 @@ enum Opcode { OP_ORR, OP_PKH, OP_PLD, + OP_REV, + OP_REV16, + OP_REVSH, OP_RSB, OP_RSC, OP_SBC, @@ -174,6 +177,7 @@ class ARM_Disasm { static std::string DisassembleNoOperands(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); 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); -- cgit v1.2.3