summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-08-11 13:28:23 -0400
committerGravatar bunnei2015-08-11 13:28:23 -0400
commitdf25b047f870d84bf7d37ccbbaf9bfb88a2ccd7f (patch)
tree66d6b12711893aec8d769bae411490d644c60825 /src
parentMerge pull request #1026 from lioncash/disasm (diff)
parentarm_disasm: ARMv6 mul/div and abs media instructions (diff)
downloadyuzu-df25b047f870d84bf7d37ccbbaf9bfb88a2ccd7f.tar.gz
yuzu-df25b047f870d84bf7d37ccbbaf9bfb88a2ccd7f.tar.xz
yuzu-df25b047f870d84bf7d37ccbbaf9bfb88a2ccd7f.zip
Merge pull request #1028 from aroulin/arm-disas-media-instr
arm_disasm: ARMv6 media instructions
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/disassembler/arm_disasm.cpp467
-rw-r--r--src/core/arm/disassembler/arm_disasm.h79
2 files changed, 545 insertions, 1 deletions
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp
index 964e30112..1d40ae030 100644
--- a/src/core/arm/disassembler/arm_disasm.cpp
+++ b/src/core/arm/disassembler/arm_disasm.cpp
@@ -1,6 +1,7 @@
1// Copyright 2006 The Android Open Source Project 1// Copyright 2006 The Android Open Source Project
2 2
3#include <string> 3#include <string>
4#include <unordered_set>
4 5
5#include "common/string_util.h" 6#include "common/string_util.h"
6#include "core/arm/disassembler/arm_disasm.h" 7#include "core/arm/disassembler/arm_disasm.h"
@@ -66,13 +67,47 @@ static const char *opcode_names[] = {
66 "mvn", 67 "mvn",
67 "nop", 68 "nop",
68 "orr", 69 "orr",
70 "pkh",
69 "pld", 71 "pld",
72 "qadd16",
73 "qadd8",
74 "qasx",
75 "qsax",
76 "qsub16",
77 "qsub8",
78 "rev",
79 "rev16",
80 "revsh",
70 "rsb", 81 "rsb",
71 "rsc", 82 "rsc",
83 "sadd16",
84 "sadd8",
85 "sasx",
72 "sbc", 86 "sbc",
87 "sel",
73 "sev", 88 "sev",
89 "shadd16",
90 "shadd8",
91 "shasx",
92 "shsax",
93 "shsub16",
94 "shsub8",
95 "smlad",
74 "smlal", 96 "smlal",
97 "smlald",
98 "smlsd",
99 "smlsld",
100 "smmla",
101 "smmls",
102 "smmul",
103 "smuad",
75 "smull", 104 "smull",
105 "smusd",
106 "ssat",
107 "ssat16",
108 "ssax",
109 "ssub16",
110 "ssub8",
76 "stc", 111 "stc",
77 "stm", 112 "stm",
78 "str", 113 "str",
@@ -88,10 +123,44 @@ static const char *opcode_names[] = {
88 "swi", 123 "swi",
89 "swp", 124 "swp",
90 "swpb", 125 "swpb",
126 "sxtab",
127 "sxtab16",
128 "sxtah",
129 "sxtb",
130 "sxtb16",
131 "sxth",
91 "teq", 132 "teq",
92 "tst", 133 "tst",
134 "uadd16",
135 "uadd8",
136 "uasx",
137 "uhadd16",
138 "uhadd8",
139 "uhasx",
140 "uhsax",
141 "uhsub16",
142 "uhsub8",
93 "umlal", 143 "umlal",
94 "umull", 144 "umull",
145 "uqadd16",
146 "uqadd8",
147 "uqasx",
148 "uqsax",
149 "uqsub16",
150 "uqsub8",
151 "usad8",
152 "usada8",
153 "usat",
154 "usat16",
155 "usax",
156 "usub16",
157 "usub8",
158 "uxtab",
159 "uxtab16",
160 "uxtah",
161 "uxtb",
162 "uxtb16",
163 "uxth",
95 "wfe", 164 "wfe",
96 "wfi", 165 "wfi",
97 "yield", 166 "yield",
@@ -236,8 +305,70 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn)
236 case OP_WFI: 305 case OP_WFI:
237 case OP_YIELD: 306 case OP_YIELD:
238 return DisassembleNoOperands(opcode, insn); 307 return DisassembleNoOperands(opcode, insn);
308 case OP_PKH:
309 return DisassemblePKH(insn);
239 case OP_PLD: 310 case OP_PLD:
240 return DisassemblePLD(insn); 311 return DisassemblePLD(insn);
312 case OP_QADD16:
313 case OP_QADD8:
314 case OP_QASX:
315 case OP_QSAX:
316 case OP_QSUB16:
317 case OP_QSUB8:
318 case OP_SADD16:
319 case OP_SADD8:
320 case OP_SASX:
321 case OP_SHADD16:
322 case OP_SHADD8:
323 case OP_SHASX:
324 case OP_SHSAX:
325 case OP_SHSUB16:
326 case OP_SHSUB8:
327 case OP_SSAX:
328 case OP_SSUB16:
329 case OP_SSUB8:
330 case OP_UADD16:
331 case OP_UADD8:
332 case OP_UASX:
333 case OP_UHADD16:
334 case OP_UHADD8:
335 case OP_UHASX:
336 case OP_UHSAX:
337 case OP_UHSUB16:
338 case OP_UHSUB8:
339 case OP_UQADD16:
340 case OP_UQADD8:
341 case OP_UQASX:
342 case OP_UQSAX:
343 case OP_UQSUB16:
344 case OP_UQSUB8:
345 case OP_USAX:
346 case OP_USUB16:
347 case OP_USUB8:
348 return DisassembleParallelAddSub(opcode, insn);
349 case OP_REV:
350 case OP_REV16:
351 case OP_REVSH:
352 return DisassembleREV(opcode, insn);
353 case OP_SEL:
354 return DisassembleSEL(insn);
355 case OP_SMLAD:
356 case OP_SMLALD:
357 case OP_SMLSD:
358 case OP_SMLSLD:
359 case OP_SMMLA:
360 case OP_SMMLS:
361 case OP_SMMUL:
362 case OP_SMUAD:
363 case OP_SMUSD:
364 case OP_USAD8:
365 case OP_USADA8:
366 return DisassembleMediaMulDiv(opcode, insn);
367 case OP_SSAT:
368 case OP_SSAT16:
369 case OP_USAT:
370 case OP_USAT16:
371 return DisassembleSAT(opcode, insn);
241 case OP_STC: 372 case OP_STC:
242 return "stc"; 373 return "stc";
243 case OP_SWI: 374 case OP_SWI:
@@ -245,6 +376,19 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn)
245 case OP_SWP: 376 case OP_SWP:
246 case OP_SWPB: 377 case OP_SWPB:
247 return DisassembleSWP(opcode, insn); 378 return DisassembleSWP(opcode, insn);
379 case OP_SXTAB:
380 case OP_SXTAB16:
381 case OP_SXTAH:
382 case OP_SXTB:
383 case OP_SXTB16:
384 case OP_SXTH:
385 case OP_UXTAB:
386 case OP_UXTAB16:
387 case OP_UXTAH:
388 case OP_UXTB:
389 case OP_UXTB16:
390 case OP_UXTH:
391 return DisassembleXT(opcode, insn);
248 case OP_UMLAL: 392 case OP_UMLAL:
249 case OP_UMULL: 393 case OP_UMULL:
250 case OP_SMLAL: 394 case OP_SMLAL:
@@ -382,6 +526,38 @@ std::string ARM_Disasm::DisassembleCLZ(uint32_t insn)
382 return Common::StringFromFormat("clz%s\tr%d, r%d", cond_to_str(cond), rd, rm); 526 return Common::StringFromFormat("clz%s\tr%d, r%d", cond_to_str(cond), rd, rm);
383} 527}
384 528
529std::string ARM_Disasm::DisassembleMediaMulDiv(Opcode opcode, uint32_t insn) {
530 uint32_t cond = BITS(insn, 28, 31);
531 uint32_t rd = BITS(insn, 16, 19);
532 uint32_t ra = BITS(insn, 12, 15);
533 uint32_t rm = BITS(insn, 8, 11);
534 uint32_t m = BIT(insn, 5);
535 uint32_t rn = BITS(insn, 0, 3);
536
537 std::string cross = "";
538 if (m) {
539 if (opcode == OP_SMMLA || opcode == OP_SMMUL || opcode == OP_SMMLS)
540 cross = "r";
541 else
542 cross = "x";
543 }
544
545 std::string ext_reg = "";
546 std::unordered_set<Opcode, std::hash<int>> with_ext_reg = {
547 OP_SMLAD, OP_SMLSD, OP_SMMLA, OP_SMMLS, OP_USADA8
548 };
549 if (with_ext_reg.find(opcode) != with_ext_reg.end())
550 ext_reg = Common::StringFromFormat(", r%u", ra);
551
552 std::string rd_low = "";
553 if (opcode == OP_SMLALD || opcode == OP_SMLSLD)
554 rd_low = Common::StringFromFormat("r%u, ", ra);
555
556 return Common::StringFromFormat("%s%s%s\t%sr%u, r%u, r%u%s", opcode_names[opcode],
557 cross.c_str(), cond_to_str(cond), rd_low.c_str(), rd, rn, rm,
558 ext_reg.c_str());
559}
560
385std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, uint32_t insn) 561std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, uint32_t insn)
386{ 562{
387 std::string tmp_list; 563 std::string tmp_list;
@@ -684,6 +860,40 @@ std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, uint32_t insn)
684 return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); 860 return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond));
685} 861}
686 862
863std::string ARM_Disasm::DisassembleParallelAddSub(Opcode opcode, uint32_t insn) {
864 uint32_t cond = BITS(insn, 28, 31);
865 uint32_t rn = BITS(insn, 16, 19);
866 uint32_t rd = BITS(insn, 12, 15);
867 uint32_t rm = BITS(insn, 0, 3);
868
869 return Common::StringFromFormat("%s%s\tr%u, r%u, r%u", opcode_names[opcode], cond_to_str(cond),
870 rd, rn, rm);
871}
872
873std::string ARM_Disasm::DisassemblePKH(uint32_t insn)
874{
875 uint32_t cond = BITS(insn, 28, 31);
876 uint32_t rn = BITS(insn, 16, 19);
877 uint32_t rd = BITS(insn, 12, 15);
878 uint32_t imm5 = BITS(insn, 7, 11);
879 uint32_t tb = BIT(insn, 6);
880 uint32_t rm = BITS(insn, 0, 3);
881
882 std::string suffix = tb ? "tb" : "bt";
883 std::string shift = "";
884
885 if (tb && imm5 == 0)
886 imm5 = 32;
887
888 if (imm5 > 0) {
889 shift = tb ? ", ASR" : ", LSL";
890 shift += " #" + std::to_string(imm5);
891 }
892
893 return Common::StringFromFormat("pkh%s%s\tr%u, r%u, r%u%s", suffix.c_str(), cond_to_str(cond),
894 rd, rn, rm, shift.c_str());
895}
896
687std::string ARM_Disasm::DisassemblePLD(uint32_t insn) 897std::string ARM_Disasm::DisassemblePLD(uint32_t insn)
688{ 898{
689 uint8_t is_reg = (insn >> 25) & 0x1; 899 uint8_t is_reg = (insn >> 25) & 0x1;
@@ -707,6 +917,15 @@ std::string ARM_Disasm::DisassemblePLD(uint32_t insn)
707 } 917 }
708} 918}
709 919
920std::string ARM_Disasm::DisassembleREV(Opcode opcode, uint32_t insn) {
921 uint32_t cond = BITS(insn, 28, 31);
922 uint32_t rd = BITS(insn, 12, 15);
923 uint32_t rm = BITS(insn, 0, 3);
924
925 return Common::StringFromFormat("%s%s\tr%u, r%u", opcode_names[opcode], cond_to_str(cond),
926 rd, rm);
927}
928
710std::string ARM_Disasm::DisassembleREX(Opcode opcode, uint32_t insn) { 929std::string ARM_Disasm::DisassembleREX(Opcode opcode, uint32_t insn) {
711 uint32_t rn = BITS(insn, 16, 19); 930 uint32_t rn = BITS(insn, 16, 19);
712 uint32_t rd = BITS(insn, 12, 15); 931 uint32_t rd = BITS(insn, 12, 15);
@@ -737,6 +956,44 @@ std::string ARM_Disasm::DisassembleREX(Opcode opcode, uint32_t insn) {
737 } 956 }
738} 957}
739 958
959std::string ARM_Disasm::DisassembleSAT(Opcode opcode, uint32_t insn) {
960 uint32_t cond = BITS(insn, 28, 31);
961 uint32_t sat_imm = BITS(insn, 16, 20);
962 uint32_t rd = BITS(insn, 12, 15);
963 uint32_t imm5 = BITS(insn, 7, 11);
964 uint32_t sh = BIT(insn, 6);
965 uint32_t rn = BITS(insn, 0, 3);
966
967 std::string shift_part = "";
968 bool opcode_has_shift = (opcode == OP_SSAT) || (opcode == OP_USAT);
969 if (opcode_has_shift && !(sh == 0 && imm5 == 0)) {
970 if (sh == 0)
971 shift_part += ", LSL #";
972 else
973 shift_part += ", ASR #";
974
975 if (imm5 == 0)
976 imm5 = 32;
977 shift_part += std::to_string(imm5);
978 }
979
980 if (opcode == OP_SSAT || opcode == OP_SSAT16)
981 sat_imm++;
982
983 return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], cond_to_str(cond), rd,
984 sat_imm, rn, shift_part.c_str());
985}
986
987std::string ARM_Disasm::DisassembleSEL(uint32_t insn) {
988 uint32_t cond = BITS(insn, 28, 31);
989 uint32_t rn = BITS(insn, 16, 19);
990 uint32_t rd = BITS(insn, 12, 15);
991 uint32_t rm = BITS(insn, 0, 3);
992
993 return Common::StringFromFormat("%s%s\tr%u, r%u, r%u", opcode_names[OP_SEL], cond_to_str(cond),
994 rd, rn, rm);
995}
996
740std::string ARM_Disasm::DisassembleSWI(uint32_t insn) 997std::string ARM_Disasm::DisassembleSWI(uint32_t insn)
741{ 998{
742 uint8_t cond = (insn >> 28) & 0xf; 999 uint8_t cond = (insn >> 28) & 0xf;
@@ -756,6 +1013,30 @@ std::string ARM_Disasm::DisassembleSWP(Opcode opcode, uint32_t insn)
756 return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opname, cond_to_str(cond), rd, rm, rn); 1013 return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opname, cond_to_str(cond), rd, rm, rn);
757} 1014}
758 1015
1016std::string ARM_Disasm::DisassembleXT(Opcode opcode, uint32_t insn)
1017{
1018 uint32_t cond = BITS(insn, 28, 31);
1019 uint32_t rn = BITS(insn, 16, 19);
1020 uint32_t rd = BITS(insn, 12, 15);
1021 uint32_t rotate = BITS(insn, 10, 11);
1022 uint32_t rm = BITS(insn, 0, 3);
1023
1024 std::string rn_part = "";
1025 static std::unordered_set<Opcode, std::hash<int>> extend_with_add = {
1026 OP_SXTAB, OP_SXTAB16, OP_SXTAH,
1027 OP_UXTAB, OP_UXTAB16, OP_UXTAH
1028 };
1029 if (extend_with_add.find(opcode) != extend_with_add.end())
1030 rn_part = ", r" + std::to_string(rn);
1031
1032 std::string rotate_part = "";
1033 if (rotate != 0)
1034 rotate_part = ", ROR #" + std::to_string(rotate << 3);
1035
1036 return Common::StringFromFormat("%s%s\tr%u%s, r%u%s", opcode_names[opcode], cond_to_str(cond),
1037 rd, rn_part.c_str(), rm, rotate_part.c_str());
1038}
1039
759Opcode ARM_Disasm::Decode(uint32_t insn) { 1040Opcode ARM_Disasm::Decode(uint32_t insn) {
760 uint32_t bits27_26 = (insn >> 26) & 0x3; 1041 uint32_t bits27_26 = (insn >> 26) & 0x3;
761 switch (bits27_26) { 1042 switch (bits27_26) {
@@ -818,7 +1099,7 @@ Opcode ARM_Disasm::Decode01(uint32_t insn) {
818 uint8_t is_reg = (insn >> 25) & 0x1; 1099 uint8_t is_reg = (insn >> 25) & 0x1;
819 uint8_t bit4 = (insn >> 4) & 0x1; 1100 uint8_t bit4 = (insn >> 4) & 0x1;
820 if (is_reg == 1 && bit4 == 1) 1101 if (is_reg == 1 && bit4 == 1)
821 return OP_UNDEFINED; 1102 return DecodeMedia(insn);
822 uint8_t is_load = (insn >> 20) & 0x1; 1103 uint8_t is_load = (insn >> 20) & 0x1;
823 uint8_t is_byte = (insn >> 22) & 0x1; 1104 uint8_t is_byte = (insn >> 22) & 0x1;
824 if ((insn & 0xfd70f000) == 0xf550f000) { 1105 if ((insn & 0xfd70f000) == 0xf550f000) {
@@ -940,6 +1221,120 @@ Opcode ARM_Disasm::DecodeSyncPrimitive(uint32_t insn) {
940 } 1221 }
941} 1222}
942 1223
1224Opcode ARM_Disasm::DecodeParallelAddSub(uint32_t insn) {
1225 uint32_t op1 = BITS(insn, 20, 21);
1226 uint32_t op2 = BITS(insn, 5, 7);
1227 uint32_t is_unsigned = BIT(insn, 22);
1228
1229 if (op1 == 0x0 || op2 == 0x5 || op2 == 0x6)
1230 return OP_UNDEFINED;
1231
1232 // change op1 range from [1, 3] to range [0, 2]
1233 op1--;
1234
1235 // change op2 range from [0, 4] U {7} to range [0, 5]
1236 if (op2 == 0x7)
1237 op2 = 0x5;
1238
1239 static std::vector<Opcode> opcodes = {
1240 // op1 = 0
1241 OP_SADD16, OP_UADD16,
1242 OP_SASX, OP_UASX,
1243 OP_SSAX, OP_USAX,
1244 OP_SSUB16, OP_USUB16,
1245 OP_SADD8, OP_UADD8,
1246 OP_SSUB8, OP_USUB8,
1247 // op1 = 1
1248 OP_QADD16, OP_UQADD16,
1249 OP_QASX, OP_UQASX,
1250 OP_QSAX, OP_UQSAX,
1251 OP_QSUB16, OP_UQSUB16,
1252 OP_QADD8, OP_UQADD8,
1253 OP_QSUB8, OP_UQSUB8,
1254 // op1 = 2
1255 OP_SHADD16, OP_UHADD16,
1256 OP_SHASX, OP_UHASX,
1257 OP_SHSAX, OP_UHSAX,
1258 OP_SHSUB16, OP_UHSUB16,
1259 OP_SHADD8, OP_UHADD8,
1260 OP_SHSUB8, OP_UHSUB8
1261 };
1262
1263 uint32_t opcode_index = op1 * 12 + op2 * 2 + is_unsigned;
1264 return opcodes[opcode_index];
1265}
1266
1267Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) {
1268 uint32_t op1 = BITS(insn, 20, 22);
1269 uint32_t a = BITS(insn, 16, 19);
1270 uint32_t op2 = BITS(insn, 5, 7);
1271
1272 switch (op1) {
1273 case 0x0:
1274 if (BIT(op2, 0) == 0)
1275 return OP_PKH;
1276 if (op2 == 0x3 && a != 0xf)
1277 return OP_SXTAB16;
1278 if (op2 == 0x3 && a == 0xf)
1279 return OP_SXTB16;
1280 if (op2 == 0x5)
1281 return OP_SEL;
1282 break;
1283 case 0x2:
1284 if (BIT(op2, 0) == 0)
1285 return OP_SSAT;
1286 if (op2 == 0x1)
1287 return OP_SSAT16;
1288 if (op2 == 0x3 && a != 0xf)
1289 return OP_SXTAB;
1290 if (op2 == 0x3 && a == 0xf)
1291 return OP_SXTB;
1292 break;
1293 case 0x3:
1294 if (op2 == 0x1)
1295 return OP_REV;
1296 if (BIT(op2, 0) == 0)
1297 return OP_SSAT;
1298 if (op2 == 0x3 && a != 0xf)
1299 return OP_SXTAH;
1300 if (op2 == 0x3 && a == 0xf)
1301 return OP_SXTH;
1302 if (op2 == 0x5)
1303 return OP_REV16;
1304 break;
1305 case 0x4:
1306 if (op2 == 0x3 && a != 0xf)
1307 return OP_UXTAB16;
1308 if (op2 == 0x3 && a == 0xf)
1309 return OP_UXTB16;
1310 break;
1311 case 0x6:
1312 if (BIT(op2, 0) == 0)
1313 return OP_USAT;
1314 if (op2 == 0x1)
1315 return OP_USAT16;
1316 if (op2 == 0x3 && a != 0xf)
1317 return OP_UXTAB;
1318 if (op2 == 0x3 && a == 0xf)
1319 return OP_UXTB;
1320 break;
1321 case 0x7:
1322 if (BIT(op2, 0) == 0)
1323 return OP_USAT;
1324 if (op2 == 0x3 && a != 0xf)
1325 return OP_UXTAH;
1326 if (op2 == 0x3 && a == 0xf)
1327 return OP_UXTH;
1328 if (op2 == 0x5)
1329 return OP_REVSH;
1330 break;
1331 default:
1332 break;
1333 }
1334
1335 return OP_UNDEFINED;
1336}
1337
943Opcode ARM_Disasm::DecodeMUL(uint32_t insn) { 1338Opcode ARM_Disasm::DecodeMUL(uint32_t insn) {
944 uint8_t bit24 = (insn >> 24) & 0x1; 1339 uint8_t bit24 = (insn >> 24) & 0x1;
945 if (bit24 != 0) { 1340 if (bit24 != 0) {
@@ -999,6 +1394,76 @@ Opcode ARM_Disasm::DecodeMSRImmAndHints(uint32_t insn) {
999 return OP_MSR; 1394 return OP_MSR;
1000} 1395}
1001 1396
1397Opcode ARM_Disasm::DecodeMediaMulDiv(uint32_t insn) {
1398 uint32_t op1 = BITS(insn, 20, 22);
1399 uint32_t op2_h = BITS(insn, 6, 7);
1400 uint32_t a = BITS(insn, 12, 15);
1401
1402 switch (op1) {
1403 case 0x0:
1404 if (op2_h == 0x0) {
1405 if (a != 0xf)
1406 return OP_SMLAD;
1407 else
1408 return OP_SMUAD;
1409 } else if (op2_h == 0x1) {
1410 if (a != 0xf)
1411 return OP_SMLSD;
1412 else
1413 return OP_SMUSD;
1414 }
1415 break;
1416 case 0x4:
1417 if (op2_h == 0x0)
1418 return OP_SMLALD;
1419 else if (op2_h == 0x1)
1420 return OP_SMLSLD;
1421 break;
1422 case 0x5:
1423 if (op2_h == 0x0) {
1424 if (a != 0xf)
1425 return OP_SMMLA;
1426 else
1427 return OP_SMMUL;
1428 } else if (op2_h == 0x3) {
1429 return OP_SMMLS;
1430 }
1431 break;
1432 default:
1433 break;
1434 }
1435
1436 return OP_UNDEFINED;
1437}
1438
1439Opcode ARM_Disasm::DecodeMedia(uint32_t insn) {
1440 uint32_t op1 = BITS(insn, 20, 24);
1441 uint32_t rd = BITS(insn, 12, 15);
1442 uint32_t op2 = BITS(insn, 5, 7);
1443
1444 switch (BITS(op1, 3, 4)) {
1445 case 0x0:
1446 // unsigned and signed parallel addition and subtraction
1447 return DecodeParallelAddSub(insn);
1448 case 0x1:
1449 // Packing, unpacking, saturation, and reversal
1450 return DecodePackingSaturationReversal(insn);
1451 case 0x2:
1452 // Signed multiply, signed and unsigned divide
1453 return DecodeMediaMulDiv(insn);
1454 case 0x3:
1455 if (op2 == 0 && rd == 0xf)
1456 return OP_USAD8;
1457 if (op2 == 0 && rd != 0xf)
1458 return OP_USADA8;
1459 break;
1460 default:
1461 break;
1462 }
1463
1464 return OP_UNDEFINED;
1465}
1466
1002Opcode ARM_Disasm::DecodeLDRH(uint32_t insn) { 1467Opcode ARM_Disasm::DecodeLDRH(uint32_t insn) {
1003 uint8_t is_load = (insn >> 20) & 0x1; 1468 uint8_t is_load = (insn >> 20) & 0x1;
1004 uint8_t bits_65 = (insn >> 5) & 0x3; 1469 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 d04fd21eb..259a77861 100644
--- a/src/core/arm/disassembler/arm_disasm.h
+++ b/src/core/arm/disassembler/arm_disasm.h
@@ -48,13 +48,47 @@ enum Opcode {
48 OP_MVN, 48 OP_MVN,
49 OP_NOP, 49 OP_NOP,
50 OP_ORR, 50 OP_ORR,
51 OP_PKH,
51 OP_PLD, 52 OP_PLD,
53 OP_QADD16,
54 OP_QADD8,
55 OP_QASX,
56 OP_QSAX,
57 OP_QSUB16,
58 OP_QSUB8,
59 OP_REV,
60 OP_REV16,
61 OP_REVSH,
52 OP_RSB, 62 OP_RSB,
53 OP_RSC, 63 OP_RSC,
64 OP_SADD16,
65 OP_SADD8,
66 OP_SASX,
54 OP_SBC, 67 OP_SBC,
68 OP_SEL,
55 OP_SEV, 69 OP_SEV,
70 OP_SHADD16,
71 OP_SHADD8,
72 OP_SHASX,
73 OP_SHSAX,
74 OP_SHSUB16,
75 OP_SHSUB8,
76 OP_SMLAD,
56 OP_SMLAL, 77 OP_SMLAL,
78 OP_SMLALD,
79 OP_SMLSD,
80 OP_SMLSLD,
81 OP_SMMLA,
82 OP_SMMLS,
83 OP_SMMUL,
84 OP_SMUAD,
57 OP_SMULL, 85 OP_SMULL,
86 OP_SMUSD,
87 OP_SSAT,
88 OP_SSAT16,
89 OP_SSAX,
90 OP_SSUB16,
91 OP_SSUB8,
58 OP_STC, 92 OP_STC,
59 OP_STM, 93 OP_STM,
60 OP_STR, 94 OP_STR,
@@ -70,10 +104,44 @@ enum Opcode {
70 OP_SWI, 104 OP_SWI,
71 OP_SWP, 105 OP_SWP,
72 OP_SWPB, 106 OP_SWPB,
107 OP_SXTAB,
108 OP_SXTAB16,
109 OP_SXTAH,
110 OP_SXTB,
111 OP_SXTB16,
112 OP_SXTH,
73 OP_TEQ, 113 OP_TEQ,
74 OP_TST, 114 OP_TST,
115 OP_UADD16,
116 OP_UADD8,
117 OP_UASX,
118 OP_UHADD16,
119 OP_UHADD8,
120 OP_UHASX,
121 OP_UHSAX,
122 OP_UHSUB16,
123 OP_UHSUB8,
75 OP_UMLAL, 124 OP_UMLAL,
76 OP_UMULL, 125 OP_UMULL,
126 OP_UQADD16,
127 OP_UQADD8,
128 OP_UQASX,
129 OP_UQSAX,
130 OP_UQSUB16,
131 OP_UQSUB8,
132 OP_USAD8,
133 OP_USADA8,
134 OP_USAT,
135 OP_USAT16,
136 OP_USAX,
137 OP_USUB16,
138 OP_USUB8,
139 OP_UXTAB,
140 OP_UXTAB16,
141 OP_UXTAH,
142 OP_UXTB,
143 OP_UXTB16,
144 OP_UXTH,
77 OP_WFE, 145 OP_WFE,
78 OP_WFI, 146 OP_WFI,
79 OP_YIELD, 147 OP_YIELD,
@@ -132,8 +200,12 @@ class ARM_Disasm {
132 static Opcode Decode10(uint32_t insn); 200 static Opcode Decode10(uint32_t insn);
133 static Opcode Decode11(uint32_t insn); 201 static Opcode Decode11(uint32_t insn);
134 static Opcode DecodeSyncPrimitive(uint32_t insn); 202 static Opcode DecodeSyncPrimitive(uint32_t insn);
203 static Opcode DecodeParallelAddSub(uint32_t insn);
204 static Opcode DecodePackingSaturationReversal(uint32_t insn);
135 static Opcode DecodeMUL(uint32_t insn); 205 static Opcode DecodeMUL(uint32_t insn);
136 static Opcode DecodeMSRImmAndHints(uint32_t insn); 206 static Opcode DecodeMSRImmAndHints(uint32_t insn);
207 static Opcode DecodeMediaMulDiv(uint32_t insn);
208 static Opcode DecodeMedia(uint32_t insn);
137 static Opcode DecodeLDRH(uint32_t insn); 209 static Opcode DecodeLDRH(uint32_t insn);
138 static Opcode DecodeALU(uint32_t insn); 210 static Opcode DecodeALU(uint32_t insn);
139 211
@@ -142,6 +214,7 @@ class ARM_Disasm {
142 static std::string DisassembleBX(uint32_t insn); 214 static std::string DisassembleBX(uint32_t insn);
143 static std::string DisassembleBKPT(uint32_t insn); 215 static std::string DisassembleBKPT(uint32_t insn);
144 static std::string DisassembleCLZ(uint32_t insn); 216 static std::string DisassembleCLZ(uint32_t insn);
217 static std::string DisassembleMediaMulDiv(Opcode opcode, uint32_t insn);
145 static std::string DisassembleMemblock(Opcode opcode, uint32_t insn); 218 static std::string DisassembleMemblock(Opcode opcode, uint32_t insn);
146 static std::string DisassembleMem(uint32_t insn); 219 static std::string DisassembleMem(uint32_t insn);
147 static std::string DisassembleMemHalf(uint32_t insn); 220 static std::string DisassembleMemHalf(uint32_t insn);
@@ -152,8 +225,14 @@ class ARM_Disasm {
152 static std::string DisassembleMRS(uint32_t insn); 225 static std::string DisassembleMRS(uint32_t insn);
153 static std::string DisassembleMSR(uint32_t insn); 226 static std::string DisassembleMSR(uint32_t insn);
154 static std::string DisassembleNoOperands(Opcode opcode, uint32_t insn); 227 static std::string DisassembleNoOperands(Opcode opcode, uint32_t insn);
228 static std::string DisassembleParallelAddSub(Opcode opcode, uint32_t insn);
229 static std::string DisassemblePKH(uint32_t insn);
155 static std::string DisassemblePLD(uint32_t insn); 230 static std::string DisassemblePLD(uint32_t insn);
231 static std::string DisassembleREV(Opcode opcode, uint32_t insn);
156 static std::string DisassembleREX(Opcode opcode, uint32_t insn); 232 static std::string DisassembleREX(Opcode opcode, uint32_t insn);
233 static std::string DisassembleSAT(Opcode opcode, uint32_t insn);
234 static std::string DisassembleSEL(uint32_t insn);
157 static std::string DisassembleSWI(uint32_t insn); 235 static std::string DisassembleSWI(uint32_t insn);
158 static std::string DisassembleSWP(Opcode opcode, uint32_t insn); 236 static std::string DisassembleSWP(Opcode opcode, uint32_t insn);
237 static std::string DisassembleXT(Opcode opcode, uint32_t insn);
159}; 238};