From 5d81a2fd48cdd3138698beb1da56fa7064f6c5c5 Mon Sep 17 00:00:00 2001 From: aroulin Date: Wed, 5 Aug 2015 12:12:24 +0200 Subject: Disassembler: ARMv6K hint instructions --- src/core/arm/disassembler/arm_disasm.cpp | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'src/core/arm/disassembler/arm_disasm.cpp') diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index f6d44d85..bb87043a 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp @@ -4,6 +4,7 @@ #include "common/string_util.h" #include "core/arm/disassembler/arm_disasm.h" +#include "core/arm/skyeye_common/armsupp.h" static const char *cond_names[] = { "eq", @@ -58,11 +59,13 @@ static const char *opcode_names[] = { "msr", "mul", "mvn", + "nop", "orr", "pld", "rsb", "rsc", "sbc", + "sev", "smlal", "smull", "stc", @@ -80,6 +83,9 @@ static const char *opcode_names[] = { "tst", "umlal", "umull", + "wfe", + "wfi", + "yield", "undefined", "adc", @@ -204,6 +210,12 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) return DisassembleMSR(insn); case OP_MUL: return DisassembleMUL(opcode, insn); + case OP_NOP: + case OP_SEV: + case OP_WFE: + case OP_WFI: + case OP_YIELD: + return DisassembleNoOperands(opcode, insn); case OP_PLD: return DisassemblePLD(insn); case OP_STC: @@ -646,6 +658,12 @@ std::string ARM_Disasm::DisassembleMSR(uint32_t insn) cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm); } +std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, uint32_t insn) +{ + uint32_t cond = BITS(insn, 28, 31); + return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); +} + std::string ARM_Disasm::DisassemblePLD(uint32_t insn) { uint8_t is_reg = (insn >> 25) & 0x1; @@ -739,6 +757,12 @@ Opcode ARM_Disasm::Decode00(uint32_t insn) { } } + uint32_t op1 = BITS(insn, 20, 24); + if (bit25 && (op1 == 0x12 || op1 == 0x16)) { + // One of the MSR (immediate) and hints instructions + return DecodeMSRImmAndHints(insn); + } + // One of the data processing instructions return DecodeALU(insn); } @@ -878,6 +902,31 @@ Opcode ARM_Disasm::DecodeMUL(uint32_t insn) { return OP_SMLAL; } +Opcode ARM_Disasm::DecodeMSRImmAndHints(uint32_t insn) { + uint32_t op = BIT(insn, 22); + uint32_t op1 = BITS(insn, 16, 19); + uint32_t op2 = BITS(insn, 0, 7); + + if (op == 0 && op1 == 0) { + switch (op2) { + case 0x0: + return OP_NOP; + case 0x1: + return OP_YIELD; + case 0x2: + return OP_WFE; + case 0x3: + return OP_WFI; + case 0x4: + return OP_SEV; + default: + return OP_UNDEFINED; + } + } + + return OP_MSR; +} + Opcode ARM_Disasm::DecodeLDRH(uint32_t insn) { uint8_t is_load = (insn >> 20) & 0x1; uint8_t bits_65 = (insn >> 5) & 0x3; -- cgit v1.2.3