diff options
| author | 2015-08-10 14:45:22 +0200 | |
|---|---|---|
| committer | 2015-08-11 12:48:23 +0200 | |
| commit | 4a1db13072764f464db5217c6481b87074963d87 (patch) | |
| tree | ac8da28cb9b8271b1d0546ceda21ffa34003e49d /src/core/arm/disassembler | |
| parent | arm_disasm: ARMv6 reversal media instructions (diff) | |
| download | yuzu-4a1db13072764f464db5217c6481b87074963d87.tar.gz yuzu-4a1db13072764f464db5217c6481b87074963d87.tar.xz yuzu-4a1db13072764f464db5217c6481b87074963d87.zip | |
arm_disasm: ARMv6 parallel add/sub media instructions
{S, U, Q, UQ, SH, UH}{ADD16, ASX, SAX, SUB16, ADD8, SUB8}
Diffstat (limited to 'src/core/arm/disassembler')
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.cpp | 129 | ||||
| -rw-r--r-- | src/core/arm/disassembler/arm_disasm.h | 38 |
2 files changed, 167 insertions, 0 deletions
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index a03f113bc..59a714c44 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp | |||
| @@ -69,18 +69,36 @@ static const char *opcode_names[] = { | |||
| 69 | "orr", | 69 | "orr", |
| 70 | "pkh", | 70 | "pkh", |
| 71 | "pld", | 71 | "pld", |
| 72 | "qadd16", | ||
| 73 | "qadd8", | ||
| 74 | "qasx", | ||
| 75 | "qsax", | ||
| 76 | "qsub16", | ||
| 77 | "qsub8", | ||
| 72 | "rev", | 78 | "rev", |
| 73 | "rev16", | 79 | "rev16", |
| 74 | "revsh", | 80 | "revsh", |
| 75 | "rsb", | 81 | "rsb", |
| 76 | "rsc", | 82 | "rsc", |
| 83 | "sadd16", | ||
| 84 | "sadd8", | ||
| 85 | "sasx", | ||
| 77 | "sbc", | 86 | "sbc", |
| 78 | "sel", | 87 | "sel", |
| 79 | "sev", | 88 | "sev", |
| 89 | "shadd16", | ||
| 90 | "shadd8", | ||
| 91 | "shasx", | ||
| 92 | "shsax", | ||
| 93 | "shsub16", | ||
| 94 | "shsub8", | ||
| 80 | "smlal", | 95 | "smlal", |
| 81 | "smull", | 96 | "smull", |
| 82 | "ssat", | 97 | "ssat", |
| 83 | "ssat16", | 98 | "ssat16", |
| 99 | "ssax", | ||
| 100 | "ssub16", | ||
| 101 | "ssub8", | ||
| 84 | "stc", | 102 | "stc", |
| 85 | "stm", | 103 | "stm", |
| 86 | "str", | 104 | "str", |
| @@ -104,10 +122,28 @@ static const char *opcode_names[] = { | |||
| 104 | "sxth", | 122 | "sxth", |
| 105 | "teq", | 123 | "teq", |
| 106 | "tst", | 124 | "tst", |
| 125 | "uadd16", | ||
| 126 | "uadd8", | ||
| 127 | "uasx", | ||
| 128 | "uhadd16", | ||
| 129 | "uhadd8", | ||
| 130 | "uhasx", | ||
| 131 | "uhsax", | ||
| 132 | "uhsub16", | ||
| 133 | "uhsub8", | ||
| 107 | "umlal", | 134 | "umlal", |
| 108 | "umull", | 135 | "umull", |
| 136 | "uqadd16", | ||
| 137 | "uqadd8", | ||
| 138 | "uqasx", | ||
| 139 | "uqsax", | ||
| 140 | "uqsub16", | ||
| 141 | "uqsub8", | ||
| 109 | "usat", | 142 | "usat", |
| 110 | "usat16", | 143 | "usat16", |
| 144 | "usax", | ||
| 145 | "usub16", | ||
| 146 | "usub8", | ||
| 111 | "uxtab", | 147 | "uxtab", |
| 112 | "uxtab16", | 148 | "uxtab16", |
| 113 | "uxtah", | 149 | "uxtah", |
| @@ -262,6 +298,43 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn) | |||
| 262 | return DisassemblePKH(insn); | 298 | return DisassemblePKH(insn); |
| 263 | case OP_PLD: | 299 | case OP_PLD: |
| 264 | return DisassemblePLD(insn); | 300 | return DisassemblePLD(insn); |
| 301 | case OP_QADD16: | ||
| 302 | case OP_QADD8: | ||
| 303 | case OP_QASX: | ||
| 304 | case OP_QSAX: | ||
| 305 | case OP_QSUB16: | ||
| 306 | case OP_QSUB8: | ||
| 307 | case OP_SADD16: | ||
| 308 | case OP_SADD8: | ||
| 309 | case OP_SASX: | ||
| 310 | case OP_SHADD16: | ||
| 311 | case OP_SHADD8: | ||
| 312 | case OP_SHASX: | ||
| 313 | case OP_SHSAX: | ||
| 314 | case OP_SHSUB16: | ||
| 315 | case OP_SHSUB8: | ||
| 316 | case OP_SSAX: | ||
| 317 | case OP_SSUB16: | ||
| 318 | case OP_SSUB8: | ||
| 319 | case OP_UADD16: | ||
| 320 | case OP_UADD8: | ||
| 321 | case OP_UASX: | ||
| 322 | case OP_UHADD16: | ||
| 323 | case OP_UHADD8: | ||
| 324 | case OP_UHASX: | ||
| 325 | case OP_UHSAX: | ||
| 326 | case OP_UHSUB16: | ||
| 327 | case OP_UHSUB8: | ||
| 328 | case OP_UQADD16: | ||
| 329 | case OP_UQADD8: | ||
| 330 | case OP_UQASX: | ||
| 331 | case OP_UQSAX: | ||
| 332 | case OP_UQSUB16: | ||
| 333 | case OP_UQSUB8: | ||
| 334 | case OP_USAX: | ||
| 335 | case OP_USUB16: | ||
| 336 | case OP_USUB8: | ||
| 337 | return DisassembleParallelAddSub(opcode, insn); | ||
| 265 | case OP_REV: | 338 | case OP_REV: |
| 266 | case OP_REV16: | 339 | case OP_REV16: |
| 267 | case OP_REVSH: | 340 | case OP_REVSH: |
| @@ -732,6 +805,16 @@ std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, uint32_t insn) | |||
| 732 | return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); | 805 | return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); |
| 733 | } | 806 | } |
| 734 | 807 | ||
| 808 | std::string ARM_Disasm::DisassembleParallelAddSub(Opcode opcode, uint32_t insn) { | ||
| 809 | uint32_t cond = BITS(insn, 28, 31); | ||
| 810 | uint32_t rn = BITS(insn, 16, 19); | ||
| 811 | uint32_t rd = BITS(insn, 12, 15); | ||
| 812 | uint32_t rm = BITS(insn, 0, 3); | ||
| 813 | |||
| 814 | return Common::StringFromFormat("%s%s\tr%u, r%u, r%u", opcode_names[opcode], cond_to_str(cond), | ||
| 815 | rd, rn, rm); | ||
| 816 | } | ||
| 817 | |||
| 735 | std::string ARM_Disasm::DisassemblePKH(uint32_t insn) | 818 | std::string ARM_Disasm::DisassemblePKH(uint32_t insn) |
| 736 | { | 819 | { |
| 737 | uint32_t cond = BITS(insn, 28, 31); | 820 | uint32_t cond = BITS(insn, 28, 31); |
| @@ -1083,6 +1166,49 @@ Opcode ARM_Disasm::DecodeSyncPrimitive(uint32_t insn) { | |||
| 1083 | } | 1166 | } |
| 1084 | } | 1167 | } |
| 1085 | 1168 | ||
| 1169 | Opcode ARM_Disasm::DecodeParallelAddSub(uint32_t insn) { | ||
| 1170 | uint32_t op1 = BITS(insn, 20, 21); | ||
| 1171 | uint32_t op2 = BITS(insn, 5, 7); | ||
| 1172 | uint32_t is_unsigned = BIT(insn, 22); | ||
| 1173 | |||
| 1174 | if (op1 == 0x0 || op2 == 0x5 || op2 == 0x6) | ||
| 1175 | return OP_UNDEFINED; | ||
| 1176 | |||
| 1177 | // change op1 range from [1, 3] to range [0, 2] | ||
| 1178 | op1--; | ||
| 1179 | |||
| 1180 | // change op2 range from [0, 4] U {7} to range [0, 5] | ||
| 1181 | if (op2 == 0x7) | ||
| 1182 | op2 = 0x5; | ||
| 1183 | |||
| 1184 | static std::vector<Opcode> opcodes = { | ||
| 1185 | // op1 = 0 | ||
| 1186 | OP_SADD16, OP_UADD16, | ||
| 1187 | OP_SASX, OP_UASX, | ||
| 1188 | OP_SSAX, OP_USAX, | ||
| 1189 | OP_SSUB16, OP_USUB16, | ||
| 1190 | OP_SADD8, OP_UADD8, | ||
| 1191 | OP_SSUB8, OP_USUB8, | ||
| 1192 | // op1 = 1 | ||
| 1193 | OP_QADD16, OP_UQADD16, | ||
| 1194 | OP_QASX, OP_UQASX, | ||
| 1195 | OP_QSAX, OP_UQSAX, | ||
| 1196 | OP_QSUB16, OP_UQSUB16, | ||
| 1197 | OP_QADD8, OP_UQADD8, | ||
| 1198 | OP_QSUB8, OP_UQSUB8, | ||
| 1199 | // op1 = 2 | ||
| 1200 | OP_SHADD16, OP_UHADD16, | ||
| 1201 | OP_SHASX, OP_UHASX, | ||
| 1202 | OP_SHSAX, OP_UHSAX, | ||
| 1203 | OP_SHSUB16, OP_UHSUB16, | ||
| 1204 | OP_SHADD8, OP_UHADD8, | ||
| 1205 | OP_SHSUB8, OP_UHSUB8 | ||
| 1206 | }; | ||
| 1207 | |||
| 1208 | uint32_t opcode_index = op1 * 12 + op2 * 2 + is_unsigned; | ||
| 1209 | return opcodes[opcode_index]; | ||
| 1210 | } | ||
| 1211 | |||
| 1086 | Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { | 1212 | Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { |
| 1087 | uint32_t op1 = BITS(insn, 20, 22); | 1213 | uint32_t op1 = BITS(insn, 20, 22); |
| 1088 | uint32_t a = BITS(insn, 16, 19); | 1214 | uint32_t a = BITS(insn, 16, 19); |
| @@ -1220,6 +1346,9 @@ Opcode ARM_Disasm::DecodeMedia(uint32_t insn) { | |||
| 1220 | uint32_t rn = BITS(insn, 0, 3); | 1346 | uint32_t rn = BITS(insn, 0, 3); |
| 1221 | 1347 | ||
| 1222 | switch (BITS(op1, 3, 4)) { | 1348 | switch (BITS(op1, 3, 4)) { |
| 1349 | case 0x0: | ||
| 1350 | // unsigned and signed parallel addition and subtraction | ||
| 1351 | return DecodeParallelAddSub(insn); | ||
| 1223 | case 0x1: | 1352 | case 0x1: |
| 1224 | // Packing, unpacking, saturation, and reversal | 1353 | // Packing, unpacking, saturation, and reversal |
| 1225 | return DecodePackingSaturationReversal(insn); | 1354 | return DecodePackingSaturationReversal(insn); |
diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h index a6b34daeb..c1bd1b948 100644 --- a/src/core/arm/disassembler/arm_disasm.h +++ b/src/core/arm/disassembler/arm_disasm.h | |||
| @@ -50,18 +50,36 @@ enum Opcode { | |||
| 50 | OP_ORR, | 50 | OP_ORR, |
| 51 | OP_PKH, | 51 | OP_PKH, |
| 52 | OP_PLD, | 52 | OP_PLD, |
| 53 | OP_QADD16, | ||
| 54 | OP_QADD8, | ||
| 55 | OP_QASX, | ||
| 56 | OP_QSAX, | ||
| 57 | OP_QSUB16, | ||
| 58 | OP_QSUB8, | ||
| 53 | OP_REV, | 59 | OP_REV, |
| 54 | OP_REV16, | 60 | OP_REV16, |
| 55 | OP_REVSH, | 61 | OP_REVSH, |
| 56 | OP_RSB, | 62 | OP_RSB, |
| 57 | OP_RSC, | 63 | OP_RSC, |
| 64 | OP_SADD16, | ||
| 65 | OP_SADD8, | ||
| 66 | OP_SASX, | ||
| 58 | OP_SBC, | 67 | OP_SBC, |
| 59 | OP_SEL, | 68 | OP_SEL, |
| 60 | OP_SEV, | 69 | OP_SEV, |
| 70 | OP_SHADD16, | ||
| 71 | OP_SHADD8, | ||
| 72 | OP_SHASX, | ||
| 73 | OP_SHSAX, | ||
| 74 | OP_SHSUB16, | ||
| 75 | OP_SHSUB8, | ||
| 61 | OP_SMLAL, | 76 | OP_SMLAL, |
| 62 | OP_SMULL, | 77 | OP_SMULL, |
| 63 | OP_SSAT, | 78 | OP_SSAT, |
| 64 | OP_SSAT16, | 79 | OP_SSAT16, |
| 80 | OP_SSAX, | ||
| 81 | OP_SSUB16, | ||
| 82 | OP_SSUB8, | ||
| 65 | OP_STC, | 83 | OP_STC, |
| 66 | OP_STM, | 84 | OP_STM, |
| 67 | OP_STR, | 85 | OP_STR, |
| @@ -85,10 +103,28 @@ enum Opcode { | |||
| 85 | OP_SXTH, | 103 | OP_SXTH, |
| 86 | OP_TEQ, | 104 | OP_TEQ, |
| 87 | OP_TST, | 105 | OP_TST, |
| 106 | OP_UADD16, | ||
| 107 | OP_UADD8, | ||
| 108 | OP_UASX, | ||
| 109 | OP_UHADD16, | ||
| 110 | OP_UHADD8, | ||
| 111 | OP_UHASX, | ||
| 112 | OP_UHSAX, | ||
| 113 | OP_UHSUB16, | ||
| 114 | OP_UHSUB8, | ||
| 88 | OP_UMLAL, | 115 | OP_UMLAL, |
| 89 | OP_UMULL, | 116 | OP_UMULL, |
| 117 | OP_UQADD16, | ||
| 118 | OP_UQADD8, | ||
| 119 | OP_UQASX, | ||
| 120 | OP_UQSAX, | ||
| 121 | OP_UQSUB16, | ||
| 122 | OP_UQSUB8, | ||
| 90 | OP_USAT, | 123 | OP_USAT, |
| 91 | OP_USAT16, | 124 | OP_USAT16, |
| 125 | OP_USAX, | ||
| 126 | OP_USUB16, | ||
| 127 | OP_USUB8, | ||
| 92 | OP_UXTAB, | 128 | OP_UXTAB, |
| 93 | OP_UXTAB16, | 129 | OP_UXTAB16, |
| 94 | OP_UXTAH, | 130 | OP_UXTAH, |
| @@ -153,6 +189,7 @@ class ARM_Disasm { | |||
| 153 | static Opcode Decode10(uint32_t insn); | 189 | static Opcode Decode10(uint32_t insn); |
| 154 | static Opcode Decode11(uint32_t insn); | 190 | static Opcode Decode11(uint32_t insn); |
| 155 | static Opcode DecodeSyncPrimitive(uint32_t insn); | 191 | static Opcode DecodeSyncPrimitive(uint32_t insn); |
| 192 | static Opcode DecodeParallelAddSub(uint32_t insn); | ||
| 156 | static Opcode DecodePackingSaturationReversal(uint32_t insn); | 193 | static Opcode DecodePackingSaturationReversal(uint32_t insn); |
| 157 | static Opcode DecodeMUL(uint32_t insn); | 194 | static Opcode DecodeMUL(uint32_t insn); |
| 158 | static Opcode DecodeMSRImmAndHints(uint32_t insn); | 195 | static Opcode DecodeMSRImmAndHints(uint32_t insn); |
| @@ -175,6 +212,7 @@ class ARM_Disasm { | |||
| 175 | static std::string DisassembleMRS(uint32_t insn); | 212 | static std::string DisassembleMRS(uint32_t insn); |
| 176 | static std::string DisassembleMSR(uint32_t insn); | 213 | static std::string DisassembleMSR(uint32_t insn); |
| 177 | static std::string DisassembleNoOperands(Opcode opcode, uint32_t insn); | 214 | static std::string DisassembleNoOperands(Opcode opcode, uint32_t insn); |
| 215 | static std::string DisassembleParallelAddSub(Opcode opcode, uint32_t insn); | ||
| 178 | static std::string DisassemblePKH(uint32_t insn); | 216 | static std::string DisassemblePKH(uint32_t insn); |
| 179 | static std::string DisassemblePLD(uint32_t insn); | 217 | static std::string DisassemblePLD(uint32_t insn); |
| 180 | static std::string DisassembleREV(Opcode opcode, uint32_t insn); | 218 | static std::string DisassembleREV(Opcode opcode, uint32_t insn); |