diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.cpp | 49 | ||||
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.h | 7 | 
2 files changed, 56 insertions, 0 deletions
| diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index f6d44d85a..bb87043a4 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; diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h index f94bd4669..a4e4adf2f 100644 --- a/src/core/arm/disassembler/arm_disasm.h +++ b/src/core/arm/disassembler/arm_disasm.h @@ -41,11 +41,13 @@ enum Opcode {      OP_MSR,      OP_MUL,      OP_MVN, +    OP_NOP,      OP_ORR,      OP_PLD,      OP_RSB,      OP_RSC,      OP_SBC, +    OP_SEV,      OP_SMLAL,      OP_SMULL,      OP_STC, @@ -63,6 +65,9 @@ enum Opcode {      OP_TST,      OP_UMLAL,      OP_UMULL, +    OP_WFE, +    OP_WFI, +    OP_YIELD,      // Define thumb opcodes      OP_THUMB_UNDEFINED, @@ -118,6 +123,7 @@ class ARM_Disasm {    static Opcode Decode10(uint32_t insn);    static Opcode Decode11(uint32_t insn);    static Opcode DecodeMUL(uint32_t insn); +  static Opcode DecodeMSRImmAndHints(uint32_t insn);    static Opcode DecodeLDRH(uint32_t insn);    static Opcode DecodeALU(uint32_t insn); @@ -135,6 +141,7 @@ class ARM_Disasm {    static std::string DisassembleMUL(Opcode opcode, uint32_t insn);    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 DisassemblePLD(uint32_t insn);    static std::string DisassembleSWI(uint32_t insn);    static std::string DisassembleSWP(Opcode opcode, uint32_t insn); | 
