summaryrefslogtreecommitdiff
path: root/src/core/arm/disassembler
diff options
context:
space:
mode:
authorGravatar aroulin2015-08-10 14:45:22 +0200
committerGravatar aroulin2015-08-11 12:48:23 +0200
commit4a1db13072764f464db5217c6481b87074963d87 (patch)
treeac8da28cb9b8271b1d0546ceda21ffa34003e49d /src/core/arm/disassembler
parentarm_disasm: ARMv6 reversal media instructions (diff)
downloadyuzu-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.cpp129
-rw-r--r--src/core/arm/disassembler/arm_disasm.h38
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
808std::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
735std::string ARM_Disasm::DisassemblePKH(uint32_t insn) 818std::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
1169Opcode 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
1086Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) { 1212Opcode 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);