diff options
| author | 2015-08-05 12:12:24 +0200 | |
|---|---|---|
| committer | 2015-08-06 15:25:08 +0200 | |
| commit | 5d81a2fd48cdd3138698beb1da56fa7064f6c5c5 (patch) | |
| tree | 808a97ca2ba4d05f1d850cacfaa368e898649036 /src/core/arm/disassembler | |
| parent | Merge pull request #1018 from bbarenblat/master (diff) | |
| download | yuzu-5d81a2fd48cdd3138698beb1da56fa7064f6c5c5.tar.gz yuzu-5d81a2fd48cdd3138698beb1da56fa7064f6c5c5.tar.xz yuzu-5d81a2fd48cdd3138698beb1da56fa7064f6c5c5.zip | |
Disassembler: ARMv6K hint instructions
Diffstat (limited to 'src/core/arm/disassembler')
| -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 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/string_util.h" | 5 | #include "common/string_util.h" |
| 6 | #include "core/arm/disassembler/arm_disasm.h" | 6 | #include "core/arm/disassembler/arm_disasm.h" |
| 7 | #include "core/arm/skyeye_common/armsupp.h" | ||
| 7 | 8 | ||
| 8 | static const char *cond_names[] = { | 9 | static const char *cond_names[] = { |
| 9 | "eq", | 10 | "eq", |
| @@ -58,11 +59,13 @@ static const char *opcode_names[] = { | |||
| 58 | "msr", | 59 | "msr", |
| 59 | "mul", | 60 | "mul", |
| 60 | "mvn", | 61 | "mvn", |
| 62 | "nop", | ||
| 61 | "orr", | 63 | "orr", |
| 62 | "pld", | 64 | "pld", |
| 63 | "rsb", | 65 | "rsb", |
| 64 | "rsc", | 66 | "rsc", |
| 65 | "sbc", | 67 | "sbc", |
| 68 | "sev", | ||
| 66 | "smlal", | 69 | "smlal", |
| 67 | "smull", | 70 | "smull", |
| 68 | "stc", | 71 | "stc", |
| @@ -80,6 +83,9 @@ static const char *opcode_names[] = { | |||
| 80 | "tst", | 83 | "tst", |
| 81 | "umlal", | 84 | "umlal", |
| 82 | "umull", | 85 | "umull", |
| 86 | "wfe", | ||
| 87 | "wfi", | ||
| 88 | "yield", | ||
| 83 | 89 | ||
| 84 | "undefined", | 90 | "undefined", |
| 85 | "adc", | 91 | "adc", |
| @@ -204,6 +210,12 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) | |||
| 204 | return DisassembleMSR(insn); | 210 | return DisassembleMSR(insn); |
| 205 | case OP_MUL: | 211 | case OP_MUL: |
| 206 | return DisassembleMUL(opcode, insn); | 212 | return DisassembleMUL(opcode, insn); |
| 213 | case OP_NOP: | ||
| 214 | case OP_SEV: | ||
| 215 | case OP_WFE: | ||
| 216 | case OP_WFI: | ||
| 217 | case OP_YIELD: | ||
| 218 | return DisassembleNoOperands(opcode, insn); | ||
| 207 | case OP_PLD: | 219 | case OP_PLD: |
| 208 | return DisassemblePLD(insn); | 220 | return DisassemblePLD(insn); |
| 209 | case OP_STC: | 221 | case OP_STC: |
| @@ -646,6 +658,12 @@ std::string ARM_Disasm::DisassembleMSR(uint32_t insn) | |||
| 646 | cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm); | 658 | cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm); |
| 647 | } | 659 | } |
| 648 | 660 | ||
| 661 | std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, uint32_t insn) | ||
| 662 | { | ||
| 663 | uint32_t cond = BITS(insn, 28, 31); | ||
| 664 | return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); | ||
| 665 | } | ||
| 666 | |||
| 649 | std::string ARM_Disasm::DisassemblePLD(uint32_t insn) | 667 | std::string ARM_Disasm::DisassemblePLD(uint32_t insn) |
| 650 | { | 668 | { |
| 651 | uint8_t is_reg = (insn >> 25) & 0x1; | 669 | uint8_t is_reg = (insn >> 25) & 0x1; |
| @@ -739,6 +757,12 @@ Opcode ARM_Disasm::Decode00(uint32_t insn) { | |||
| 739 | } | 757 | } |
| 740 | } | 758 | } |
| 741 | 759 | ||
| 760 | uint32_t op1 = BITS(insn, 20, 24); | ||
| 761 | if (bit25 && (op1 == 0x12 || op1 == 0x16)) { | ||
| 762 | // One of the MSR (immediate) and hints instructions | ||
| 763 | return DecodeMSRImmAndHints(insn); | ||
| 764 | } | ||
| 765 | |||
| 742 | // One of the data processing instructions | 766 | // One of the data processing instructions |
| 743 | return DecodeALU(insn); | 767 | return DecodeALU(insn); |
| 744 | } | 768 | } |
| @@ -878,6 +902,31 @@ Opcode ARM_Disasm::DecodeMUL(uint32_t insn) { | |||
| 878 | return OP_SMLAL; | 902 | return OP_SMLAL; |
| 879 | } | 903 | } |
| 880 | 904 | ||
| 905 | Opcode ARM_Disasm::DecodeMSRImmAndHints(uint32_t insn) { | ||
| 906 | uint32_t op = BIT(insn, 22); | ||
| 907 | uint32_t op1 = BITS(insn, 16, 19); | ||
| 908 | uint32_t op2 = BITS(insn, 0, 7); | ||
| 909 | |||
| 910 | if (op == 0 && op1 == 0) { | ||
| 911 | switch (op2) { | ||
| 912 | case 0x0: | ||
| 913 | return OP_NOP; | ||
| 914 | case 0x1: | ||
| 915 | return OP_YIELD; | ||
| 916 | case 0x2: | ||
| 917 | return OP_WFE; | ||
| 918 | case 0x3: | ||
| 919 | return OP_WFI; | ||
| 920 | case 0x4: | ||
| 921 | return OP_SEV; | ||
| 922 | default: | ||
| 923 | return OP_UNDEFINED; | ||
| 924 | } | ||
| 925 | } | ||
| 926 | |||
| 927 | return OP_MSR; | ||
| 928 | } | ||
| 929 | |||
| 881 | Opcode ARM_Disasm::DecodeLDRH(uint32_t insn) { | 930 | Opcode ARM_Disasm::DecodeLDRH(uint32_t insn) { |
| 882 | uint8_t is_load = (insn >> 20) & 0x1; | 931 | uint8_t is_load = (insn >> 20) & 0x1; |
| 883 | uint8_t bits_65 = (insn >> 5) & 0x3; | 932 | 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 { | |||
| 41 | OP_MSR, | 41 | OP_MSR, |
| 42 | OP_MUL, | 42 | OP_MUL, |
| 43 | OP_MVN, | 43 | OP_MVN, |
| 44 | OP_NOP, | ||
| 44 | OP_ORR, | 45 | OP_ORR, |
| 45 | OP_PLD, | 46 | OP_PLD, |
| 46 | OP_RSB, | 47 | OP_RSB, |
| 47 | OP_RSC, | 48 | OP_RSC, |
| 48 | OP_SBC, | 49 | OP_SBC, |
| 50 | OP_SEV, | ||
| 49 | OP_SMLAL, | 51 | OP_SMLAL, |
| 50 | OP_SMULL, | 52 | OP_SMULL, |
| 51 | OP_STC, | 53 | OP_STC, |
| @@ -63,6 +65,9 @@ enum Opcode { | |||
| 63 | OP_TST, | 65 | OP_TST, |
| 64 | OP_UMLAL, | 66 | OP_UMLAL, |
| 65 | OP_UMULL, | 67 | OP_UMULL, |
| 68 | OP_WFE, | ||
| 69 | OP_WFI, | ||
| 70 | OP_YIELD, | ||
| 66 | 71 | ||
| 67 | // Define thumb opcodes | 72 | // Define thumb opcodes |
| 68 | OP_THUMB_UNDEFINED, | 73 | OP_THUMB_UNDEFINED, |
| @@ -118,6 +123,7 @@ class ARM_Disasm { | |||
| 118 | static Opcode Decode10(uint32_t insn); | 123 | static Opcode Decode10(uint32_t insn); |
| 119 | static Opcode Decode11(uint32_t insn); | 124 | static Opcode Decode11(uint32_t insn); |
| 120 | static Opcode DecodeMUL(uint32_t insn); | 125 | static Opcode DecodeMUL(uint32_t insn); |
| 126 | static Opcode DecodeMSRImmAndHints(uint32_t insn); | ||
| 121 | static Opcode DecodeLDRH(uint32_t insn); | 127 | static Opcode DecodeLDRH(uint32_t insn); |
| 122 | static Opcode DecodeALU(uint32_t insn); | 128 | static Opcode DecodeALU(uint32_t insn); |
| 123 | 129 | ||
| @@ -135,6 +141,7 @@ class ARM_Disasm { | |||
| 135 | static std::string DisassembleMUL(Opcode opcode, uint32_t insn); | 141 | static std::string DisassembleMUL(Opcode opcode, uint32_t insn); |
| 136 | static std::string DisassembleMRS(uint32_t insn); | 142 | static std::string DisassembleMRS(uint32_t insn); |
| 137 | static std::string DisassembleMSR(uint32_t insn); | 143 | static std::string DisassembleMSR(uint32_t insn); |
| 144 | static std::string DisassembleNoOperands(Opcode opcode, uint32_t insn); | ||
| 138 | static std::string DisassemblePLD(uint32_t insn); | 145 | static std::string DisassemblePLD(uint32_t insn); |
| 139 | static std::string DisassembleSWI(uint32_t insn); | 146 | static std::string DisassembleSWI(uint32_t insn); |
| 140 | static std::string DisassembleSWP(Opcode opcode, uint32_t insn); | 147 | static std::string DisassembleSWP(Opcode opcode, uint32_t insn); |