Pārlūkot izejas kodu

Disassembler: ARMv6K hint instructions

aroulin 11 gadi atpakaļ
vecāks
revīzija
5d81a2fd48

+ 49 - 0
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;

+ 7 - 0
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);