aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar aroulin <andy.roulin@epfl.ch>2015-08-09 13:52:51 +0200
committerGravatar aroulin <andy.roulin@epfl.ch>2015-08-09 13:52:51 +0200
commit0be8e1bfb6a7fb37ddc1bdbbc410362b5e5c009e (patch)
tree67d73cc48af49eb2c6c0583f76f93d13efd91aa5
parente4ff2442885e42ed5cfecb1ceadebf99da2cd2cf (diff)
arm_disasm: ARMv6 reversal media instructions
REV, REV16, REVSH Only their ARM encoding, Thumb encoding is still missing.
-rw-r--r--src/core/arm/disassembler/arm_disasm.cpp22
-rw-r--r--src/core/arm/disassembler/arm_disasm.h4
2 files changed, 26 insertions, 0 deletions
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);