clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name AArch64InstPrinter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/AArch64/MCTargetDesc -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/AArch64/MCTargetDesc -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/AArch64/MCTargetDesc -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/AArch64 -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/AArch64 -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/AArch64/MCTargetDesc/.. -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/AArch64/MCTargetDesc/.. -D NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/AArch64/MCTargetDesc -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c++ /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "AArch64InstPrinter.h" |
14 | #include "MCTargetDesc/AArch64AddressingModes.h" |
15 | #include "Utils/AArch64BaseInfo.h" |
16 | #include "llvm/ADT/STLExtras.h" |
17 | #include "llvm/ADT/StringExtras.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include "llvm/MC/MCAsmInfo.h" |
20 | #include "llvm/MC/MCExpr.h" |
21 | #include "llvm/MC/MCInst.h" |
22 | #include "llvm/MC/MCRegisterInfo.h" |
23 | #include "llvm/MC/MCSubtargetInfo.h" |
24 | #include "llvm/Support/Casting.h" |
25 | #include "llvm/Support/ErrorHandling.h" |
26 | #include "llvm/Support/Format.h" |
27 | #include "llvm/Support/MathExtras.h" |
28 | #include "llvm/Support/raw_ostream.h" |
29 | #include <cassert> |
30 | #include <cstdint> |
31 | #include <string> |
32 | |
33 | using namespace llvm; |
34 | |
35 | #define DEBUG_TYPE "asm-printer" |
36 | |
37 | #define GET_INSTRUCTION_NAME |
38 | #define PRINT_ALIAS_INSTR |
39 | #include "AArch64GenAsmWriter.inc" |
40 | #define GET_INSTRUCTION_NAME |
41 | #define PRINT_ALIAS_INSTR |
42 | #include "AArch64GenAsmWriter1.inc" |
43 | |
44 | AArch64InstPrinter::AArch64InstPrinter(const MCAsmInfo &MAI, |
45 | const MCInstrInfo &MII, |
46 | const MCRegisterInfo &MRI) |
47 | : MCInstPrinter(MAI, MII, MRI) {} |
48 | |
49 | AArch64AppleInstPrinter::AArch64AppleInstPrinter(const MCAsmInfo &MAI, |
50 | const MCInstrInfo &MII, |
51 | const MCRegisterInfo &MRI) |
52 | : AArch64InstPrinter(MAI, MII, MRI) {} |
53 | |
54 | bool AArch64InstPrinter::applyTargetSpecificCLOption(StringRef Opt) { |
55 | if (Opt == "no-aliases") { |
56 | PrintAliases = false; |
57 | return true; |
58 | } |
59 | return false; |
60 | } |
61 | |
62 | void AArch64InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { |
63 | |
64 | OS << getRegisterName(RegNo); |
65 | } |
66 | |
67 | void AArch64InstPrinter::printInst(const MCInst *MI, uint64_t Address, |
68 | StringRef Annot, const MCSubtargetInfo &STI, |
69 | raw_ostream &O) { |
70 | |
71 | |
72 | unsigned Opcode = MI->getOpcode(); |
73 | |
74 | if (Opcode == AArch64::SYSxt) |
| 1 | Assuming 'Opcode' is not equal to SYSxt | |
|
75 | if (printSysAlias(MI, STI, O)) { |
76 | printAnnotation(O, Annot); |
77 | return; |
78 | } |
79 | |
80 | |
81 | if (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri || |
| 2 | | Assuming 'Opcode' is not equal to SBFMXri | |
|
| 3 | | Assuming 'Opcode' is not equal to SBFMWri | |
|
82 | Opcode == AArch64::UBFMXri || Opcode == AArch64::UBFMWri) { |
| 4 | | Assuming 'Opcode' is not equal to UBFMXri | |
|
| 5 | | Assuming 'Opcode' is not equal to UBFMWri | |
|
83 | const MCOperand &Op0 = MI->getOperand(0); |
84 | const MCOperand &Op1 = MI->getOperand(1); |
85 | const MCOperand &Op2 = MI->getOperand(2); |
86 | const MCOperand &Op3 = MI->getOperand(3); |
87 | |
88 | bool IsSigned = (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri); |
89 | bool Is64Bit = (Opcode == AArch64::SBFMXri || Opcode == AArch64::UBFMXri); |
90 | if (Op2.isImm() && Op2.getImm() == 0 && Op3.isImm()) { |
91 | const char *AsmMnemonic = nullptr; |
92 | |
93 | switch (Op3.getImm()) { |
94 | default: |
95 | break; |
96 | case 7: |
97 | if (IsSigned) |
98 | AsmMnemonic = "sxtb"; |
99 | else if (!Is64Bit) |
100 | AsmMnemonic = "uxtb"; |
101 | break; |
102 | case 15: |
103 | if (IsSigned) |
104 | AsmMnemonic = "sxth"; |
105 | else if (!Is64Bit) |
106 | AsmMnemonic = "uxth"; |
107 | break; |
108 | case 31: |
109 | |
110 | if (Is64Bit && IsSigned) |
111 | AsmMnemonic = "sxtw"; |
112 | break; |
113 | } |
114 | |
115 | if (AsmMnemonic) { |
116 | O << '\t' << AsmMnemonic << '\t' << getRegisterName(Op0.getReg()) |
117 | << ", " << getRegisterName(getWRegFromXReg(Op1.getReg())); |
118 | printAnnotation(O, Annot); |
119 | return; |
120 | } |
121 | } |
122 | |
123 | |
124 | |
125 | |
126 | if (Op2.isImm() && Op3.isImm()) { |
127 | const char *AsmMnemonic = nullptr; |
128 | int shift = 0; |
129 | int64_t immr = Op2.getImm(); |
130 | int64_t imms = Op3.getImm(); |
131 | if (Opcode == AArch64::UBFMWri && imms != 0x1F && ((imms + 1) == immr)) { |
132 | AsmMnemonic = "lsl"; |
133 | shift = 31 - imms; |
134 | } else if (Opcode == AArch64::UBFMXri && imms != 0x3f && |
135 | ((imms + 1 == immr))) { |
136 | AsmMnemonic = "lsl"; |
137 | shift = 63 - imms; |
138 | } else if (Opcode == AArch64::UBFMWri && imms == 0x1f) { |
139 | AsmMnemonic = "lsr"; |
140 | shift = immr; |
141 | } else if (Opcode == AArch64::UBFMXri && imms == 0x3f) { |
142 | AsmMnemonic = "lsr"; |
143 | shift = immr; |
144 | } else if (Opcode == AArch64::SBFMWri && imms == 0x1f) { |
145 | AsmMnemonic = "asr"; |
146 | shift = immr; |
147 | } else if (Opcode == AArch64::SBFMXri && imms == 0x3f) { |
148 | AsmMnemonic = "asr"; |
149 | shift = immr; |
150 | } |
151 | if (AsmMnemonic) { |
152 | O << '\t' << AsmMnemonic << '\t' << getRegisterName(Op0.getReg()) |
153 | << ", " << getRegisterName(Op1.getReg()) << ", #" << shift; |
154 | printAnnotation(O, Annot); |
155 | return; |
156 | } |
157 | } |
158 | |
159 | |
160 | if (Op2.getImm() > Op3.getImm()) { |
161 | O << '\t' << (IsSigned ? "sbfiz" : "ubfiz") << '\t' |
162 | << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op1.getReg()) |
163 | << ", #" << (Is64Bit ? 64 : 32) - Op2.getImm() << ", #" << Op3.getImm() + 1; |
164 | printAnnotation(O, Annot); |
165 | return; |
166 | } |
167 | |
168 | |
169 | O << '\t' << (IsSigned ? "sbfx" : "ubfx") << '\t' |
170 | << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op1.getReg()) |
171 | << ", #" << Op2.getImm() << ", #" << Op3.getImm() - Op2.getImm() + 1; |
172 | printAnnotation(O, Annot); |
173 | return; |
174 | } |
175 | |
176 | if (Opcode == AArch64::BFMXri || Opcode == AArch64::BFMWri) { |
| 6 | | Assuming 'Opcode' is not equal to BFMXri | |
|
| 7 | | Assuming 'Opcode' is not equal to BFMWri | |
|
177 | const MCOperand &Op0 = MI->getOperand(0); |
178 | const MCOperand &Op2 = MI->getOperand(2); |
179 | int ImmR = MI->getOperand(3).getImm(); |
180 | int ImmS = MI->getOperand(4).getImm(); |
181 | |
182 | if ((Op2.getReg() == AArch64::WZR || Op2.getReg() == AArch64::XZR) && |
183 | (ImmR == 0 || ImmS < ImmR) && |
184 | STI.getFeatureBits()[AArch64::HasV8_2aOps]) { |
185 | |
186 | int BitWidth = Opcode == AArch64::BFMXri ? 64 : 32; |
187 | int LSB = (BitWidth - ImmR) % BitWidth; |
188 | int Width = ImmS + 1; |
189 | |
190 | O << "\tbfc\t" << getRegisterName(Op0.getReg()) |
191 | << ", #" << LSB << ", #" << Width; |
192 | printAnnotation(O, Annot); |
193 | return; |
194 | } else if (ImmS < ImmR) { |
195 | |
196 | int BitWidth = Opcode == AArch64::BFMXri ? 64 : 32; |
197 | int LSB = (BitWidth - ImmR) % BitWidth; |
198 | int Width = ImmS + 1; |
199 | |
200 | O << "\tbfi\t" << getRegisterName(Op0.getReg()) << ", " |
201 | << getRegisterName(Op2.getReg()) << ", #" << LSB << ", #" << Width; |
202 | printAnnotation(O, Annot); |
203 | return; |
204 | } |
205 | |
206 | int LSB = ImmR; |
207 | int Width = ImmS - ImmR + 1; |
208 | |
209 | O << "\tbfxil\t" |
210 | << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op2.getReg()) |
211 | << ", #" << LSB << ", #" << Width; |
212 | printAnnotation(O, Annot); |
213 | return; |
214 | } |
215 | |
216 | |
217 | |
218 | |
219 | if ((Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi || |
| 8 | | Assuming 'Opcode' is not equal to MOVZXi | |
|
| 9 | | Assuming 'Opcode' is not equal to MOVZWi | |
|
220 | Opcode == AArch64::MOVNXi || Opcode == AArch64::MOVNWi) && |
| 10 | | Assuming 'Opcode' is not equal to MOVNXi | |
|
| 11 | | Assuming 'Opcode' is not equal to MOVNWi | |
|
221 | MI->getOperand(1).isExpr()) { |
222 | if (Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi) |
223 | O << "\tmovz\t"; |
224 | else |
225 | O << "\tmovn\t"; |
226 | |
227 | O << getRegisterName(MI->getOperand(0).getReg()) << ", #"; |
228 | MI->getOperand(1).getExpr()->print(O, &MAI); |
229 | return; |
230 | } |
231 | |
232 | if ((Opcode == AArch64::MOVKXi || Opcode == AArch64::MOVKWi) && |
| 12 | | Assuming 'Opcode' is not equal to MOVKXi | |
|
| 13 | | Assuming 'Opcode' is not equal to MOVKWi | |
|
233 | MI->getOperand(2).isExpr()) { |
234 | O << "\tmovk\t" << getRegisterName(MI->getOperand(0).getReg()) << ", #"; |
235 | MI->getOperand(2).getExpr()->print(O, &MAI); |
236 | return; |
237 | } |
238 | |
239 | |
240 | |
241 | |
242 | |
243 | |
244 | if ((Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi) && |
245 | MI->getOperand(1).isImm() && MI->getOperand(2).isImm()) { |
246 | int RegWidth = Opcode == AArch64::MOVZXi ? 64 : 32; |
247 | int Shift = MI->getOperand(2).getImm(); |
248 | uint64_t Value = (uint64_t)MI->getOperand(1).getImm() << Shift; |
249 | |
250 | if (AArch64_AM::isMOVZMovAlias(Value, Shift, |
251 | Opcode == AArch64::MOVZXi ? 64 : 32)) { |
252 | O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg()) << ", #" |
253 | << formatImm(SignExtend64(Value, RegWidth)); |
254 | return; |
255 | } |
256 | } |
257 | |
258 | if ((Opcode == AArch64::MOVNXi || Opcode == AArch64::MOVNWi) && |
259 | MI->getOperand(1).isImm() && MI->getOperand(2).isImm()) { |
260 | int RegWidth = Opcode == AArch64::MOVNXi ? 64 : 32; |
261 | int Shift = MI->getOperand(2).getImm(); |
262 | uint64_t Value = ~((uint64_t)MI->getOperand(1).getImm() << Shift); |
263 | if (RegWidth == 32) |
264 | Value = Value & 0xffffffff; |
265 | |
266 | if (AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth)) { |
267 | O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg()) << ", #" |
268 | << formatImm(SignExtend64(Value, RegWidth)); |
269 | return; |
270 | } |
271 | } |
272 | |
273 | if ((Opcode == AArch64::ORRXri || Opcode == AArch64::ORRWri) && |
| 14 | | Assuming 'Opcode' is equal to ORRXri | |
|
274 | (MI->getOperand(1).getReg() == AArch64::XZR || |
| 15 | | Assuming the condition is true | |
|
275 | MI->getOperand(1).getReg() == AArch64::WZR) && |
276 | MI->getOperand(2).isImm()) { |
277 | int RegWidth = Opcode == AArch64::ORRXri ? 64 : 32; |
| |
| |
278 | uint64_t Value = AArch64_AM::decodeLogicalImmediate( |
| 18 | | Calling 'decodeLogicalImmediate' | |
|
279 | MI->getOperand(2).getImm(), RegWidth); |
280 | if (!AArch64_AM::isAnyMOVWMovAlias(Value, RegWidth)) { |
281 | O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg()) << ", #" |
282 | << formatImm(SignExtend64(Value, RegWidth)); |
283 | return; |
284 | } |
285 | } |
286 | |
287 | if (Opcode == AArch64::CompilerBarrier) { |
288 | O << '\t' << MAI.getCommentString() << " COMPILER BARRIER"; |
289 | printAnnotation(O, Annot); |
290 | return; |
291 | } |
292 | |
293 | if (Opcode == AArch64::SPACE) { |
294 | O << '\t' << MAI.getCommentString() << " SPACE " |
295 | << MI->getOperand(1).getImm(); |
296 | printAnnotation(O, Annot); |
297 | return; |
298 | } |
299 | |
300 | |
301 | |
302 | if (Opcode == AArch64::TSB) { |
303 | O << "\ttsb\tcsync"; |
304 | return; |
305 | } |
306 | |
307 | if (!PrintAliases || !printAliasInstr(MI, Address, STI, O)) |
308 | printInstruction(MI, Address, STI, O); |
309 | |
310 | printAnnotation(O, Annot); |
311 | |
312 | if (atomicBarrierDroppedOnZero(Opcode) && |
313 | (MI->getOperand(0).getReg() == AArch64::XZR || |
314 | MI->getOperand(0).getReg() == AArch64::WZR)) { |
315 | printAnnotation(O, "acquire semantics dropped since destination is zero"); |
316 | } |
317 | } |
318 | |
319 | static bool isTblTbxInstruction(unsigned Opcode, StringRef &Layout, |
320 | bool &IsTbx) { |
321 | switch (Opcode) { |
322 | case AArch64::TBXv8i8One: |
323 | case AArch64::TBXv8i8Two: |
324 | case AArch64::TBXv8i8Three: |
325 | case AArch64::TBXv8i8Four: |
326 | IsTbx = true; |
327 | Layout = ".8b"; |
328 | return true; |
329 | case AArch64::TBLv8i8One: |
330 | case AArch64::TBLv8i8Two: |
331 | case AArch64::TBLv8i8Three: |
332 | case AArch64::TBLv8i8Four: |
333 | IsTbx = false; |
334 | Layout = ".8b"; |
335 | return true; |
336 | case AArch64::TBXv16i8One: |
337 | case AArch64::TBXv16i8Two: |
338 | case AArch64::TBXv16i8Three: |
339 | case AArch64::TBXv16i8Four: |
340 | IsTbx = true; |
341 | Layout = ".16b"; |
342 | return true; |
343 | case AArch64::TBLv16i8One: |
344 | case AArch64::TBLv16i8Two: |
345 | case AArch64::TBLv16i8Three: |
346 | case AArch64::TBLv16i8Four: |
347 | IsTbx = false; |
348 | Layout = ".16b"; |
349 | return true; |
350 | default: |
351 | return false; |
352 | } |
353 | } |
354 | |
355 | struct LdStNInstrDesc { |
356 | unsigned Opcode; |
357 | const char *Mnemonic; |
358 | const char *Layout; |
359 | int ListOperand; |
360 | bool HasLane; |
361 | int NaturalOffset; |
362 | }; |
363 | |
364 | static const LdStNInstrDesc LdStNInstInfo[] = { |
365 | { AArch64::LD1i8, "ld1", ".b", 1, true, 0 }, |
366 | { AArch64::LD1i16, "ld1", ".h", 1, true, 0 }, |
367 | { AArch64::LD1i32, "ld1", ".s", 1, true, 0 }, |
368 | { AArch64::LD1i64, "ld1", ".d", 1, true, 0 }, |
369 | { AArch64::LD1i8_POST, "ld1", ".b", 2, true, 1 }, |
370 | { AArch64::LD1i16_POST, "ld1", ".h", 2, true, 2 }, |
371 | { AArch64::LD1i32_POST, "ld1", ".s", 2, true, 4 }, |
372 | { AArch64::LD1i64_POST, "ld1", ".d", 2, true, 8 }, |
373 | { AArch64::LD1Rv16b, "ld1r", ".16b", 0, false, 0 }, |
374 | { AArch64::LD1Rv8h, "ld1r", ".8h", 0, false, 0 }, |
375 | { AArch64::LD1Rv4s, "ld1r", ".4s", 0, false, 0 }, |
376 | { AArch64::LD1Rv2d, "ld1r", ".2d", 0, false, 0 }, |
377 | { AArch64::LD1Rv8b, "ld1r", ".8b", 0, false, 0 }, |
378 | { AArch64::LD1Rv4h, "ld1r", ".4h", 0, false, 0 }, |
379 | { AArch64::LD1Rv2s, "ld1r", ".2s", 0, false, 0 }, |
380 | { AArch64::LD1Rv1d, "ld1r", ".1d", 0, false, 0 }, |
381 | { AArch64::LD1Rv16b_POST, "ld1r", ".16b", 1, false, 1 }, |
382 | { AArch64::LD1Rv8h_POST, "ld1r", ".8h", 1, false, 2 }, |
383 | { AArch64::LD1Rv4s_POST, "ld1r", ".4s", 1, false, 4 }, |
384 | { AArch64::LD1Rv2d_POST, "ld1r", ".2d", 1, false, 8 }, |
385 | { AArch64::LD1Rv8b_POST, "ld1r", ".8b", 1, false, 1 }, |
386 | { AArch64::LD1Rv4h_POST, "ld1r", ".4h", 1, false, 2 }, |
387 | { AArch64::LD1Rv2s_POST, "ld1r", ".2s", 1, false, 4 }, |
388 | { AArch64::LD1Rv1d_POST, "ld1r", ".1d", 1, false, 8 }, |
389 | { AArch64::LD1Onev16b, "ld1", ".16b", 0, false, 0 }, |
390 | { AArch64::LD1Onev8h, "ld1", ".8h", 0, false, 0 }, |
391 | { AArch64::LD1Onev4s, "ld1", ".4s", 0, false, 0 }, |
392 | { AArch64::LD1Onev2d, "ld1", ".2d", 0, false, 0 }, |
393 | { AArch64::LD1Onev8b, "ld1", ".8b", 0, false, 0 }, |
394 | { AArch64::LD1Onev4h, "ld1", ".4h", 0, false, 0 }, |
395 | { AArch64::LD1Onev2s, "ld1", ".2s", 0, false, 0 }, |
396 | { AArch64::LD1Onev1d, "ld1", ".1d", 0, false, 0 }, |
397 | { AArch64::LD1Onev16b_POST, "ld1", ".16b", 1, false, 16 }, |
398 | { AArch64::LD1Onev8h_POST, "ld1", ".8h", 1, false, 16 }, |
399 | { AArch64::LD1Onev4s_POST, "ld1", ".4s", 1, false, 16 }, |
400 | { AArch64::LD1Onev2d_POST, "ld1", ".2d", 1, false, 16 }, |
401 | { AArch64::LD1Onev8b_POST, "ld1", ".8b", 1, false, 8 }, |
402 | { AArch64::LD1Onev4h_POST, "ld1", ".4h", 1, false, 8 }, |
403 | { AArch64::LD1Onev2s_POST, "ld1", ".2s", 1, false, 8 }, |
404 | { AArch64::LD1Onev1d_POST, "ld1", ".1d", 1, false, 8 }, |
405 | { AArch64::LD1Twov16b, "ld1", ".16b", 0, false, 0 }, |
406 | { AArch64::LD1Twov8h, "ld1", ".8h", 0, false, 0 }, |
407 | { AArch64::LD1Twov4s, "ld1", ".4s", 0, false, 0 }, |
408 | { AArch64::LD1Twov2d, "ld1", ".2d", 0, false, 0 }, |
409 | { AArch64::LD1Twov8b, "ld1", ".8b", 0, false, 0 }, |
410 | { AArch64::LD1Twov4h, "ld1", ".4h", 0, false, 0 }, |
411 | { AArch64::LD1Twov2s, "ld1", ".2s", 0, false, 0 }, |
412 | { AArch64::LD1Twov1d, "ld1", ".1d", 0, false, 0 }, |
413 | { AArch64::LD1Twov16b_POST, "ld1", ".16b", 1, false, 32 }, |
414 | { AArch64::LD1Twov8h_POST, "ld1", ".8h", 1, false, 32 }, |
415 | { AArch64::LD1Twov4s_POST, "ld1", ".4s", 1, false, 32 }, |
416 | { AArch64::LD1Twov2d_POST, "ld1", ".2d", 1, false, 32 }, |
417 | { AArch64::LD1Twov8b_POST, "ld1", ".8b", 1, false, 16 }, |
418 | { AArch64::LD1Twov4h_POST, "ld1", ".4h", 1, false, 16 }, |
419 | { AArch64::LD1Twov2s_POST, "ld1", ".2s", 1, false, 16 }, |
420 | { AArch64::LD1Twov1d_POST, "ld1", ".1d", 1, false, 16 }, |
421 | { AArch64::LD1Threev16b, "ld1", ".16b", 0, false, 0 }, |
422 | { AArch64::LD1Threev8h, "ld1", ".8h", 0, false, 0 }, |
423 | { AArch64::LD1Threev4s, "ld1", ".4s", 0, false, 0 }, |
424 | { AArch64::LD1Threev2d, "ld1", ".2d", 0, false, 0 }, |
425 | { AArch64::LD1Threev8b, "ld1", ".8b", 0, false, 0 }, |
426 | { AArch64::LD1Threev4h, "ld1", ".4h", 0, false, 0 }, |
427 | { AArch64::LD1Threev2s, "ld1", ".2s", 0, false, 0 }, |
428 | { AArch64::LD1Threev1d, "ld1", ".1d", 0, false, 0 }, |
429 | { AArch64::LD1Threev16b_POST, "ld1", ".16b", 1, false, 48 }, |
430 | { AArch64::LD1Threev8h_POST, "ld1", ".8h", 1, false, 48 }, |
431 | { AArch64::LD1Threev4s_POST, "ld1", ".4s", 1, false, 48 }, |
432 | { AArch64::LD1Threev2d_POST, "ld1", ".2d", 1, false, 48 }, |
433 | { AArch64::LD1Threev8b_POST, "ld1", ".8b", 1, false, 24 }, |
434 | { AArch64::LD1Threev4h_POST, "ld1", ".4h", 1, false, 24 }, |
435 | { AArch64::LD1Threev2s_POST, "ld1", ".2s", 1, false, 24 }, |
436 | { AArch64::LD1Threev1d_POST, "ld1", ".1d", 1, false, 24 }, |
437 | { AArch64::LD1Fourv16b, "ld1", ".16b", 0, false, 0 }, |
438 | { AArch64::LD1Fourv8h, "ld1", ".8h", 0, false, 0 }, |
439 | { AArch64::LD1Fourv4s, "ld1", ".4s", 0, false, 0 }, |
440 | { AArch64::LD1Fourv2d, "ld1", ".2d", 0, false, 0 }, |
441 | { AArch64::LD1Fourv8b, "ld1", ".8b", 0, false, 0 }, |
442 | { AArch64::LD1Fourv4h, "ld1", ".4h", 0, false, 0 }, |
443 | { AArch64::LD1Fourv2s, "ld1", ".2s", 0, false, 0 }, |
444 | { AArch64::LD1Fourv1d, "ld1", ".1d", 0, false, 0 }, |
445 | { AArch64::LD1Fourv16b_POST, "ld1", ".16b", 1, false, 64 }, |
446 | { AArch64::LD1Fourv8h_POST, "ld1", ".8h", 1, false, 64 }, |
447 | { AArch64::LD1Fourv4s_POST, "ld1", ".4s", 1, false, 64 }, |
448 | { AArch64::LD1Fourv2d_POST, "ld1", ".2d", 1, false, 64 }, |
449 | { AArch64::LD1Fourv8b_POST, "ld1", ".8b", 1, false, 32 }, |
450 | { AArch64::LD1Fourv4h_POST, "ld1", ".4h", 1, false, 32 }, |
451 | { AArch64::LD1Fourv2s_POST, "ld1", ".2s", 1, false, 32 }, |
452 | { AArch64::LD1Fourv1d_POST, "ld1", ".1d", 1, false, 32 }, |
453 | { AArch64::LD2i8, "ld2", ".b", 1, true, 0 }, |
454 | { AArch64::LD2i16, "ld2", ".h", 1, true, 0 }, |
455 | { AArch64::LD2i32, "ld2", ".s", 1, true, 0 }, |
456 | { AArch64::LD2i64, "ld2", ".d", 1, true, 0 }, |
457 | { AArch64::LD2i8_POST, "ld2", ".b", 2, true, 2 }, |
458 | { AArch64::LD2i16_POST, "ld2", ".h", 2, true, 4 }, |
459 | { AArch64::LD2i32_POST, "ld2", ".s", 2, true, 8 }, |
460 | { AArch64::LD2i64_POST, "ld2", ".d", 2, true, 16 }, |
461 | { AArch64::LD2Rv16b, "ld2r", ".16b", 0, false, 0 }, |
462 | { AArch64::LD2Rv8h, "ld2r", ".8h", 0, false, 0 }, |
463 | { AArch64::LD2Rv4s, "ld2r", ".4s", 0, false, 0 }, |
464 | { AArch64::LD2Rv2d, "ld2r", ".2d", 0, false, 0 }, |
465 | { AArch64::LD2Rv8b, "ld2r", ".8b", 0, false, 0 }, |
466 | { AArch64::LD2Rv4h, "ld2r", ".4h", 0, false, 0 }, |
467 | { AArch64::LD2Rv2s, "ld2r", ".2s", 0, false, 0 }, |
468 | { AArch64::LD2Rv1d, "ld2r", ".1d", 0, false, 0 }, |
469 | { AArch64::LD2Rv16b_POST, "ld2r", ".16b", 1, false, 2 }, |
470 | { AArch64::LD2Rv8h_POST, "ld2r", ".8h", 1, false, 4 }, |
471 | { AArch64::LD2Rv4s_POST, "ld2r", ".4s", 1, false, 8 }, |
472 | { AArch64::LD2Rv2d_POST, "ld2r", ".2d", 1, false, 16 }, |
473 | { AArch64::LD2Rv8b_POST, "ld2r", ".8b", 1, false, 2 }, |
474 | { AArch64::LD2Rv4h_POST, "ld2r", ".4h", 1, false, 4 }, |
475 | { AArch64::LD2Rv2s_POST, "ld2r", ".2s", 1, false, 8 }, |
476 | { AArch64::LD2Rv1d_POST, "ld2r", ".1d", 1, false, 16 }, |
477 | { AArch64::LD2Twov16b, "ld2", ".16b", 0, false, 0 }, |
478 | { AArch64::LD2Twov8h, "ld2", ".8h", 0, false, 0 }, |
479 | { AArch64::LD2Twov4s, "ld2", ".4s", 0, false, 0 }, |
480 | { AArch64::LD2Twov2d, "ld2", ".2d", 0, false, 0 }, |
481 | { AArch64::LD2Twov8b, "ld2", ".8b", 0, false, 0 }, |
482 | { AArch64::LD2Twov4h, "ld2", ".4h", 0, false, 0 }, |
483 | { AArch64::LD2Twov2s, "ld2", ".2s", 0, false, 0 }, |
484 | { AArch64::LD2Twov16b_POST, "ld2", ".16b", 1, false, 32 }, |
485 | { AArch64::LD2Twov8h_POST, "ld2", ".8h", 1, false, 32 }, |
486 | { AArch64::LD2Twov4s_POST, "ld2", ".4s", 1, false, 32 }, |
487 | { AArch64::LD2Twov2d_POST, "ld2", ".2d", 1, false, 32 }, |
488 | { AArch64::LD2Twov8b_POST, "ld2", ".8b", 1, false, 16 }, |
489 | { AArch64::LD2Twov4h_POST, "ld2", ".4h", 1, false, 16 }, |
490 | { AArch64::LD2Twov2s_POST, "ld2", ".2s", 1, false, 16 }, |
491 | { AArch64::LD3i8, "ld3", ".b", 1, true, 0 }, |
492 | { AArch64::LD3i16, "ld3", ".h", 1, true, 0 }, |
493 | { AArch64::LD3i32, "ld3", ".s", 1, true, 0 }, |
494 | { AArch64::LD3i64, "ld3", ".d", 1, true, 0 }, |
495 | { AArch64::LD3i8_POST, "ld3", ".b", 2, true, 3 }, |
496 | { AArch64::LD3i16_POST, "ld3", ".h", 2, true, 6 }, |
497 | { AArch64::LD3i32_POST, "ld3", ".s", 2, true, 12 }, |
498 | { AArch64::LD3i64_POST, "ld3", ".d", 2, true, 24 }, |
499 | { AArch64::LD3Rv16b, "ld3r", ".16b", 0, false, 0 }, |
500 | { AArch64::LD3Rv8h, "ld3r", ".8h", 0, false, 0 }, |
501 | { AArch64::LD3Rv4s, "ld3r", ".4s", 0, false, 0 }, |
502 | { AArch64::LD3Rv2d, "ld3r", ".2d", 0, false, 0 }, |
503 | { AArch64::LD3Rv8b, "ld3r", ".8b", 0, false, 0 }, |
504 | { AArch64::LD3Rv4h, "ld3r", ".4h", 0, false, 0 }, |
505 | { AArch64::LD3Rv2s, "ld3r", ".2s", 0, false, 0 }, |
506 | { AArch64::LD3Rv1d, "ld3r", ".1d", 0, false, 0 }, |
507 | { AArch64::LD3Rv16b_POST, "ld3r", ".16b", 1, false, 3 }, |
508 | { AArch64::LD3Rv8h_POST, "ld3r", ".8h", 1, false, 6 }, |
509 | { AArch64::LD3Rv4s_POST, "ld3r", ".4s", 1, false, 12 }, |
510 | { AArch64::LD3Rv2d_POST, "ld3r", ".2d", 1, false, 24 }, |
511 | { AArch64::LD3Rv8b_POST, "ld3r", ".8b", 1, false, 3 }, |
512 | { AArch64::LD3Rv4h_POST, "ld3r", ".4h", 1, false, 6 }, |
513 | { AArch64::LD3Rv2s_POST, "ld3r", ".2s", 1, false, 12 }, |
514 | { AArch64::LD3Rv1d_POST, "ld3r", ".1d", 1, false, 24 }, |
515 | { AArch64::LD3Threev16b, "ld3", ".16b", 0, false, 0 }, |
516 | { AArch64::LD3Threev8h, "ld3", ".8h", 0, false, 0 }, |
517 | { AArch64::LD3Threev4s, "ld3", ".4s", 0, false, 0 }, |
518 | { AArch64::LD3Threev2d, "ld3", ".2d", 0, false, 0 }, |
519 | { AArch64::LD3Threev8b, "ld3", ".8b", 0, false, 0 }, |
520 | { AArch64::LD3Threev4h, "ld3", ".4h", 0, false, 0 }, |
521 | { AArch64::LD3Threev2s, "ld3", ".2s", 0, false, 0 }, |
522 | { AArch64::LD3Threev16b_POST, "ld3", ".16b", 1, false, 48 }, |
523 | { AArch64::LD3Threev8h_POST, "ld3", ".8h", 1, false, 48 }, |
524 | { AArch64::LD3Threev4s_POST, "ld3", ".4s", 1, false, 48 }, |
525 | { AArch64::LD3Threev2d_POST, "ld3", ".2d", 1, false, 48 }, |
526 | { AArch64::LD3Threev8b_POST, "ld3", ".8b", 1, false, 24 }, |
527 | { AArch64::LD3Threev4h_POST, "ld3", ".4h", 1, false, 24 }, |
528 | { AArch64::LD3Threev2s_POST, "ld3", ".2s", 1, false, 24 }, |
529 | { AArch64::LD4i8, "ld4", ".b", 1, true, 0 }, |
530 | { AArch64::LD4i16, "ld4", ".h", 1, true, 0 }, |
531 | { AArch64::LD4i32, "ld4", ".s", 1, true, 0 }, |
532 | { AArch64::LD4i64, "ld4", ".d", 1, true, 0 }, |
533 | { AArch64::LD4i8_POST, "ld4", ".b", 2, true, 4 }, |
534 | { AArch64::LD4i16_POST, "ld4", ".h", 2, true, 8 }, |
535 | { AArch64::LD4i32_POST, "ld4", ".s", 2, true, 16 }, |
536 | { AArch64::LD4i64_POST, "ld4", ".d", 2, true, 32 }, |
537 | { AArch64::LD4Rv16b, "ld4r", ".16b", 0, false, 0 }, |
538 | { AArch64::LD4Rv8h, "ld4r", ".8h", 0, false, 0 }, |
539 | { AArch64::LD4Rv4s, "ld4r", ".4s", 0, false, 0 }, |
540 | { AArch64::LD4Rv2d, "ld4r", ".2d", 0, false, 0 }, |
541 | { AArch64::LD4Rv8b, "ld4r", ".8b", 0, false, 0 }, |
542 | { AArch64::LD4Rv4h, "ld4r", ".4h", 0, false, 0 }, |
543 | { AArch64::LD4Rv2s, "ld4r", ".2s", 0, false, 0 }, |
544 | { AArch64::LD4Rv1d, "ld4r", ".1d", 0, false, 0 }, |
545 | { AArch64::LD4Rv16b_POST, "ld4r", ".16b", 1, false, 4 }, |
546 | { AArch64::LD4Rv8h_POST, "ld4r", ".8h", 1, false, 8 }, |
547 | { AArch64::LD4Rv4s_POST, "ld4r", ".4s", 1, false, 16 }, |
548 | { AArch64::LD4Rv2d_POST, "ld4r", ".2d", 1, false, 32 }, |
549 | { AArch64::LD4Rv8b_POST, "ld4r", ".8b", 1, false, 4 }, |
550 | { AArch64::LD4Rv4h_POST, "ld4r", ".4h", 1, false, 8 }, |
551 | { AArch64::LD4Rv2s_POST, "ld4r", ".2s", 1, false, 16 }, |
552 | { AArch64::LD4Rv1d_POST, "ld4r", ".1d", 1, false, 32 }, |
553 | { AArch64::LD4Fourv16b, "ld4", ".16b", 0, false, 0 }, |
554 | { AArch64::LD4Fourv8h, "ld4", ".8h", 0, false, 0 }, |
555 | { AArch64::LD4Fourv4s, "ld4", ".4s", 0, false, 0 }, |
556 | { AArch64::LD4Fourv2d, "ld4", ".2d", 0, false, 0 }, |
557 | { AArch64::LD4Fourv8b, "ld4", ".8b", 0, false, 0 }, |
558 | { AArch64::LD4Fourv4h, "ld4", ".4h", 0, false, 0 }, |
559 | { AArch64::LD4Fourv2s, "ld4", ".2s", 0, false, 0 }, |
560 | { AArch64::LD4Fourv16b_POST, "ld4", ".16b", 1, false, 64 }, |
561 | { AArch64::LD4Fourv8h_POST, "ld4", ".8h", 1, false, 64 }, |
562 | { AArch64::LD4Fourv4s_POST, "ld4", ".4s", 1, false, 64 }, |
563 | { AArch64::LD4Fourv2d_POST, "ld4", ".2d", 1, false, 64 }, |
564 | { AArch64::LD4Fourv8b_POST, "ld4", ".8b", 1, false, 32 }, |
565 | { AArch64::LD4Fourv4h_POST, "ld4", ".4h", 1, false, 32 }, |
566 | { AArch64::LD4Fourv2s_POST, "ld4", ".2s", 1, false, 32 }, |
567 | { AArch64::ST1i8, "st1", ".b", 0, true, 0 }, |
568 | { AArch64::ST1i16, "st1", ".h", 0, true, 0 }, |
569 | { AArch64::ST1i32, "st1", ".s", 0, true, 0 }, |
570 | { AArch64::ST1i64, "st1", ".d", 0, true, 0 }, |
571 | { AArch64::ST1i8_POST, "st1", ".b", 1, true, 1 }, |
572 | { AArch64::ST1i16_POST, "st1", ".h", 1, true, 2 }, |
573 | { AArch64::ST1i32_POST, "st1", ".s", 1, true, 4 }, |
574 | { AArch64::ST1i64_POST, "st1", ".d", 1, true, 8 }, |
575 | { AArch64::ST1Onev16b, "st1", ".16b", 0, false, 0 }, |
576 | { AArch64::ST1Onev8h, "st1", ".8h", 0, false, 0 }, |
577 | { AArch64::ST1Onev4s, "st1", ".4s", 0, false, 0 }, |
578 | { AArch64::ST1Onev2d, "st1", ".2d", 0, false, 0 }, |
579 | { AArch64::ST1Onev8b, "st1", ".8b", 0, false, 0 }, |
580 | { AArch64::ST1Onev4h, "st1", ".4h", 0, false, 0 }, |
581 | { AArch64::ST1Onev2s, "st1", ".2s", 0, false, 0 }, |
582 | { AArch64::ST1Onev1d, "st1", ".1d", 0, false, 0 }, |
583 | { AArch64::ST1Onev16b_POST, "st1", ".16b", 1, false, 16 }, |
584 | { AArch64::ST1Onev8h_POST, "st1", ".8h", 1, false, 16 }, |
585 | { AArch64::ST1Onev4s_POST, "st1", ".4s", 1, false, 16 }, |
586 | { AArch64::ST1Onev2d_POST, "st1", ".2d", 1, false, 16 }, |
587 | { AArch64::ST1Onev8b_POST, "st1", ".8b", 1, false, 8 }, |
588 | { AArch64::ST1Onev4h_POST, "st1", ".4h", 1, false, 8 }, |
589 | { AArch64::ST1Onev2s_POST, "st1", ".2s", 1, false, 8 }, |
590 | { AArch64::ST1Onev1d_POST, "st1", ".1d", 1, false, 8 }, |
591 | { AArch64::ST1Twov16b, "st1", ".16b", 0, false, 0 }, |
592 | { AArch64::ST1Twov8h, "st1", ".8h", 0, false, 0 }, |
593 | { AArch64::ST1Twov4s, "st1", ".4s", 0, false, 0 }, |
594 | { AArch64::ST1Twov2d, "st1", ".2d", 0, false, 0 }, |
595 | { AArch64::ST1Twov8b, "st1", ".8b", 0, false, 0 }, |
596 | { AArch64::ST1Twov4h, "st1", ".4h", 0, false, 0 }, |
597 | { AArch64::ST1Twov2s, "st1", ".2s", 0, false, 0 }, |
598 | { AArch64::ST1Twov1d, "st1", ".1d", 0, false, 0 }, |
599 | { AArch64::ST1Twov16b_POST, "st1", ".16b", 1, false, 32 }, |
600 | { AArch64::ST1Twov8h_POST, "st1", ".8h", 1, false, 32 }, |
601 | { AArch64::ST1Twov4s_POST, "st1", ".4s", 1, false, 32 }, |
602 | { AArch64::ST1Twov2d_POST, "st1", ".2d", 1, false, 32 }, |
603 | { AArch64::ST1Twov8b_POST, "st1", ".8b", 1, false, 16 }, |
604 | { AArch64::ST1Twov4h_POST, "st1", ".4h", 1, false, 16 }, |
605 | { AArch64::ST1Twov2s_POST, "st1", ".2s", 1, false, 16 }, |
606 | { AArch64::ST1Twov1d_POST, "st1", ".1d", 1, false, 16 }, |
607 | { AArch64::ST1Threev16b, "st1", ".16b", 0, false, 0 }, |
608 | { AArch64::ST1Threev8h, "st1", ".8h", 0, false, 0 }, |
609 | { AArch64::ST1Threev4s, "st1", ".4s", 0, false, 0 }, |
610 | { AArch64::ST1Threev2d, "st1", ".2d", 0, false, 0 }, |
611 | { AArch64::ST1Threev8b, "st1", ".8b", 0, false, 0 }, |
612 | { AArch64::ST1Threev4h, "st1", ".4h", 0, false, 0 }, |
613 | { AArch64::ST1Threev2s, "st1", ".2s", 0, false, 0 }, |
614 | { AArch64::ST1Threev1d, "st1", ".1d", 0, false, 0 }, |
615 | { AArch64::ST1Threev16b_POST, "st1", ".16b", 1, false, 48 }, |
616 | { AArch64::ST1Threev8h_POST, "st1", ".8h", 1, false, 48 }, |
617 | { AArch64::ST1Threev4s_POST, "st1", ".4s", 1, false, 48 }, |
618 | { AArch64::ST1Threev2d_POST, "st1", ".2d", 1, false, 48 }, |
619 | { AArch64::ST1Threev8b_POST, "st1", ".8b", 1, false, 24 }, |
620 | { AArch64::ST1Threev4h_POST, "st1", ".4h", 1, false, 24 }, |
621 | { AArch64::ST1Threev2s_POST, "st1", ".2s", 1, false, 24 }, |
622 | { AArch64::ST1Threev1d_POST, "st1", ".1d", 1, false, 24 }, |
623 | { AArch64::ST1Fourv16b, "st1", ".16b", 0, false, 0 }, |
624 | { AArch64::ST1Fourv8h, "st1", ".8h", 0, false, 0 }, |
625 | { AArch64::ST1Fourv4s, "st1", ".4s", 0, false, 0 }, |
626 | { AArch64::ST1Fourv2d, "st1", ".2d", 0, false, 0 }, |
627 | { AArch64::ST1Fourv8b, "st1", ".8b", 0, false, 0 }, |
628 | { AArch64::ST1Fourv4h, "st1", ".4h", 0, false, 0 }, |
629 | { AArch64::ST1Fourv2s, "st1", ".2s", 0, false, 0 }, |
630 | { AArch64::ST1Fourv1d, "st1", ".1d", 0, false, 0 }, |
631 | { AArch64::ST1Fourv16b_POST, "st1", ".16b", 1, false, 64 }, |
632 | { AArch64::ST1Fourv8h_POST, "st1", ".8h", 1, false, 64 }, |
633 | { AArch64::ST1Fourv4s_POST, "st1", ".4s", 1, false, 64 }, |
634 | { AArch64::ST1Fourv2d_POST, "st1", ".2d", 1, false, 64 }, |
635 | { AArch64::ST1Fourv8b_POST, "st1", ".8b", 1, false, 32 }, |
636 | { AArch64::ST1Fourv4h_POST, "st1", ".4h", 1, false, 32 }, |
637 | { AArch64::ST1Fourv2s_POST, "st1", ".2s", 1, false, 32 }, |
638 | { AArch64::ST1Fourv1d_POST, "st1", ".1d", 1, false, 32 }, |
639 | { AArch64::ST2i8, "st2", ".b", 0, true, 0 }, |
640 | { AArch64::ST2i16, "st2", ".h", 0, true, 0 }, |
641 | { AArch64::ST2i32, "st2", ".s", 0, true, 0 }, |
642 | { AArch64::ST2i64, "st2", ".d", 0, true, 0 }, |
643 | { AArch64::ST2i8_POST, "st2", ".b", 1, true, 2 }, |
644 | { AArch64::ST2i16_POST, "st2", ".h", 1, true, 4 }, |
645 | { AArch64::ST2i32_POST, "st2", ".s", 1, true, 8 }, |
646 | { AArch64::ST2i64_POST, "st2", ".d", 1, true, 16 }, |
647 | { AArch64::ST2Twov16b, "st2", ".16b", 0, false, 0 }, |
648 | { AArch64::ST2Twov8h, "st2", ".8h", 0, false, 0 }, |
649 | { AArch64::ST2Twov4s, "st2", ".4s", 0, false, 0 }, |
650 | { AArch64::ST2Twov2d, "st2", ".2d", 0, false, 0 }, |
651 | { AArch64::ST2Twov8b, "st2", ".8b", 0, false, 0 }, |
652 | { AArch64::ST2Twov4h, "st2", ".4h", 0, false, 0 }, |
653 | { AArch64::ST2Twov2s, "st2", ".2s", 0, false, 0 }, |
654 | { AArch64::ST2Twov16b_POST, "st2", ".16b", 1, false, 32 }, |
655 | { AArch64::ST2Twov8h_POST, "st2", ".8h", 1, false, 32 }, |
656 | { AArch64::ST2Twov4s_POST, "st2", ".4s", 1, false, 32 }, |
657 | { AArch64::ST2Twov2d_POST, "st2", ".2d", 1, false, 32 }, |
658 | { AArch64::ST2Twov8b_POST, "st2", ".8b", 1, false, 16 }, |
659 | { AArch64::ST2Twov4h_POST, "st2", ".4h", 1, false, 16 }, |
660 | { AArch64::ST2Twov2s_POST, "st2", ".2s", 1, false, 16 }, |
661 | { AArch64::ST3i8, "st3", ".b", 0, true, 0 }, |
662 | { AArch64::ST3i16, "st3", ".h", 0, true, 0 }, |
663 | { AArch64::ST3i32, "st3", ".s", 0, true, 0 }, |
664 | { AArch64::ST3i64, "st3", ".d", 0, true, 0 }, |
665 | { AArch64::ST3i8_POST, "st3", ".b", 1, true, 3 }, |
666 | { AArch64::ST3i16_POST, "st3", ".h", 1, true, 6 }, |
667 | { AArch64::ST3i32_POST, "st3", ".s", 1, true, 12 }, |
668 | { AArch64::ST3i64_POST, "st3", ".d", 1, true, 24 }, |
669 | { AArch64::ST3Threev16b, "st3", ".16b", 0, false, 0 }, |
670 | { AArch64::ST3Threev8h, "st3", ".8h", 0, false, 0 }, |
671 | { AArch64::ST3Threev4s, "st3", ".4s", 0, false, 0 }, |
672 | { AArch64::ST3Threev2d, "st3", ".2d", 0, false, 0 }, |
673 | { AArch64::ST3Threev8b, "st3", ".8b", 0, false, 0 }, |
674 | { AArch64::ST3Threev4h, "st3", ".4h", 0, false, 0 }, |
675 | { AArch64::ST3Threev2s, "st3", ".2s", 0, false, 0 }, |
676 | { AArch64::ST3Threev16b_POST, "st3", ".16b", 1, false, 48 }, |
677 | { AArch64::ST3Threev8h_POST, "st3", ".8h", 1, false, 48 }, |
678 | { AArch64::ST3Threev4s_POST, "st3", ".4s", 1, false, 48 }, |
679 | { AArch64::ST3Threev2d_POST, "st3", ".2d", 1, false, 48 }, |
680 | { AArch64::ST3Threev8b_POST, "st3", ".8b", 1, false, 24 }, |
681 | { AArch64::ST3Threev4h_POST, "st3", ".4h", 1, false, 24 }, |
682 | { AArch64::ST3Threev2s_POST, "st3", ".2s", 1, false, 24 }, |
683 | { AArch64::ST4i8, "st4", ".b", 0, true, 0 }, |
684 | { AArch64::ST4i16, "st4", ".h", 0, true, 0 }, |
685 | { AArch64::ST4i32, "st4", ".s", 0, true, 0 }, |
686 | { AArch64::ST4i64, "st4", ".d", 0, true, 0 }, |
687 | { AArch64::ST4i8_POST, "st4", ".b", 1, true, 4 }, |
688 | { AArch64::ST4i16_POST, "st4", ".h", 1, true, 8 }, |
689 | { AArch64::ST4i32_POST, "st4", ".s", 1, true, 16 }, |
690 | { AArch64::ST4i64_POST, "st4", ".d", 1, true, 32 }, |
691 | { AArch64::ST4Fourv16b, "st4", ".16b", 0, false, 0 }, |
692 | { AArch64::ST4Fourv8h, "st4", ".8h", 0, false, 0 }, |
693 | { AArch64::ST4Fourv4s, "st4", ".4s", 0, false, 0 }, |
694 | { AArch64::ST4Fourv2d, "st4", ".2d", 0, false, 0 }, |
695 | { AArch64::ST4Fourv8b, "st4", ".8b", 0, false, 0 }, |
696 | { AArch64::ST4Fourv4h, "st4", ".4h", 0, false, 0 }, |
697 | { AArch64::ST4Fourv2s, "st4", ".2s", 0, false, 0 }, |
698 | { AArch64::ST4Fourv16b_POST, "st4", ".16b", 1, false, 64 }, |
699 | { AArch64::ST4Fourv8h_POST, "st4", ".8h", 1, false, 64 }, |
700 | { AArch64::ST4Fourv4s_POST, "st4", ".4s", 1, false, 64 }, |
701 | { AArch64::ST4Fourv2d_POST, "st4", ".2d", 1, false, 64 }, |
702 | { AArch64::ST4Fourv8b_POST, "st4", ".8b", 1, false, 32 }, |
703 | { AArch64::ST4Fourv4h_POST, "st4", ".4h", 1, false, 32 }, |
704 | { AArch64::ST4Fourv2s_POST, "st4", ".2s", 1, false, 32 }, |
705 | }; |
706 | |
707 | static const LdStNInstrDesc *getLdStNInstrDesc(unsigned Opcode) { |
708 | unsigned Idx; |
709 | for (Idx = 0; Idx != array_lengthof(LdStNInstInfo); ++Idx) |
710 | if (LdStNInstInfo[Idx].Opcode == Opcode) |
711 | return &LdStNInstInfo[Idx]; |
712 | |
713 | return nullptr; |
714 | } |
715 | |
716 | void AArch64AppleInstPrinter::printInst(const MCInst *MI, uint64_t Address, |
717 | StringRef Annot, |
718 | const MCSubtargetInfo &STI, |
719 | raw_ostream &O) { |
720 | unsigned Opcode = MI->getOpcode(); |
721 | StringRef Layout; |
722 | |
723 | bool IsTbx; |
724 | if (isTblTbxInstruction(MI->getOpcode(), Layout, IsTbx)) { |
725 | O << "\t" << (IsTbx ? "tbx" : "tbl") << Layout << '\t' |
726 | << getRegisterName(MI->getOperand(0).getReg(), AArch64::vreg) << ", "; |
727 | |
728 | unsigned ListOpNum = IsTbx ? 2 : 1; |
729 | printVectorList(MI, ListOpNum, STI, O, ""); |
730 | |
731 | O << ", " |
732 | << getRegisterName(MI->getOperand(ListOpNum + 1).getReg(), AArch64::vreg); |
733 | printAnnotation(O, Annot); |
734 | return; |
735 | } |
736 | |
737 | if (const LdStNInstrDesc *LdStDesc = getLdStNInstrDesc(Opcode)) { |
738 | O << "\t" << LdStDesc->Mnemonic << LdStDesc->Layout << '\t'; |
739 | |
740 | |
741 | |
742 | int OpNum = LdStDesc->ListOperand; |
743 | printVectorList(MI, OpNum++, STI, O, ""); |
744 | |
745 | if (LdStDesc->HasLane) |
746 | O << '[' << MI->getOperand(OpNum++).getImm() << ']'; |
747 | |
748 | |
749 | unsigned AddrReg = MI->getOperand(OpNum++).getReg(); |
750 | O << ", [" << getRegisterName(AddrReg) << ']'; |
751 | |
752 | |
753 | if (LdStDesc->NaturalOffset != 0) { |
754 | unsigned Reg = MI->getOperand(OpNum++).getReg(); |
755 | if (Reg != AArch64::XZR) |
756 | O << ", " << getRegisterName(Reg); |
757 | else { |
758 | assert(LdStDesc->NaturalOffset && "no offset on post-inc instruction?"); |
759 | O << ", #" << LdStDesc->NaturalOffset; |
760 | } |
761 | } |
762 | |
763 | printAnnotation(O, Annot); |
764 | return; |
765 | } |
766 | |
767 | AArch64InstPrinter::printInst(MI, Address, Annot, STI, O); |
768 | } |
769 | |
770 | bool AArch64InstPrinter::printSysAlias(const MCInst *MI, |
771 | const MCSubtargetInfo &STI, |
772 | raw_ostream &O) { |
773 | #ifndef NDEBUG |
774 | unsigned Opcode = MI->getOpcode(); |
775 | assert(Opcode == AArch64::SYSxt && "Invalid opcode for SYS alias!"); |
776 | #endif |
777 | |
778 | const MCOperand &Op1 = MI->getOperand(0); |
779 | const MCOperand &Cn = MI->getOperand(1); |
780 | const MCOperand &Cm = MI->getOperand(2); |
781 | const MCOperand &Op2 = MI->getOperand(3); |
782 | |
783 | unsigned Op1Val = Op1.getImm(); |
784 | unsigned CnVal = Cn.getImm(); |
785 | unsigned CmVal = Cm.getImm(); |
786 | unsigned Op2Val = Op2.getImm(); |
787 | |
788 | uint16_t Encoding = Op2Val; |
789 | Encoding |= CmVal << 3; |
790 | Encoding |= CnVal << 7; |
791 | Encoding |= Op1Val << 11; |
792 | |
793 | bool NeedsReg; |
794 | std::string Ins; |
795 | std::string Name; |
796 | |
797 | if (CnVal == 7) { |
798 | switch (CmVal) { |
799 | default: return false; |
800 | |
801 | case 1: |
802 | switch (Op1Val) { |
803 | default: return false; |
804 | case 0: goto Search_IC; |
805 | case 3: goto Search_PRCTX; |
806 | } |
807 | |
808 | case 3: { |
809 | Search_PRCTX: |
810 | const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByEncoding(Encoding >> 3); |
811 | if (!PRCTX || !PRCTX->haveFeatures(STI.getFeatureBits())) |
812 | return false; |
813 | |
814 | NeedsReg = PRCTX->NeedsReg; |
815 | switch (Op2Val) { |
816 | default: return false; |
817 | case 4: Ins = "cfp\t"; break; |
818 | case 5: Ins = "dvp\t"; break; |
819 | case 7: Ins = "cpp\t"; break; |
820 | } |
821 | Name = std::string(PRCTX->Name); |
822 | } |
823 | break; |
824 | |
825 | case 5: { |
826 | Search_IC: |
827 | const AArch64IC::IC *IC = AArch64IC::lookupICByEncoding(Encoding); |
828 | if (!IC || !IC->haveFeatures(STI.getFeatureBits())) |
829 | return false; |
830 | |
831 | NeedsReg = IC->NeedsReg; |
832 | Ins = "ic\t"; |
833 | Name = std::string(IC->Name); |
834 | } |
835 | break; |
836 | |
837 | case 4: case 6: case 10: case 11: case 12: case 13: case 14: |
838 | { |
839 | const AArch64DC::DC *DC = AArch64DC::lookupDCByEncoding(Encoding); |
840 | if (!DC || !DC->haveFeatures(STI.getFeatureBits())) |
841 | return false; |
842 | |
843 | NeedsReg = true; |
844 | Ins = "dc\t"; |
845 | Name = std::string(DC->Name); |
846 | } |
847 | break; |
848 | |
849 | case 8: case 9: { |
850 | const AArch64AT::AT *AT = AArch64AT::lookupATByEncoding(Encoding); |
851 | if (!AT || !AT->haveFeatures(STI.getFeatureBits())) |
852 | return false; |
853 | |
854 | NeedsReg = true; |
855 | Ins = "at\t"; |
856 | Name = std::string(AT->Name); |
857 | } |
858 | break; |
859 | } |
860 | } else if (CnVal == 8 || CnVal == 9) { |
861 | |
862 | const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByEncoding(Encoding); |
863 | if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits())) |
864 | return false; |
865 | |
866 | NeedsReg = TLBI->NeedsReg; |
867 | Ins = "tlbi\t"; |
868 | Name = std::string(TLBI->Name); |
869 | } |
870 | else |
871 | return false; |
872 | |
873 | std::string Str = Ins + Name; |
874 | std::transform(Str.begin(), Str.end(), Str.begin(), ::tolower); |
875 | |
876 | O << '\t' << Str; |
877 | if (NeedsReg) |
878 | O << ", " << getRegisterName(MI->getOperand(4).getReg()); |
879 | |
880 | return true; |
881 | } |
882 | |
883 | template <int EltSize> |
884 | void AArch64InstPrinter::printMatrix(const MCInst *MI, unsigned OpNum, |
885 | const MCSubtargetInfo &STI, |
886 | raw_ostream &O) { |
887 | const MCOperand &RegOp = MI->getOperand(OpNum); |
888 | assert(RegOp.isReg() && "Unexpected operand type!"); |
889 | |
890 | O << getRegisterName(RegOp.getReg()); |
891 | switch (EltSize) { |
892 | case 0: |
893 | break; |
894 | case 8: |
895 | O << ".b"; |
896 | break; |
897 | case 16: |
898 | O << ".h"; |
899 | break; |
900 | case 32: |
901 | O << ".s"; |
902 | break; |
903 | case 64: |
904 | O << ".d"; |
905 | break; |
906 | case 128: |
907 | O << ".q"; |
908 | break; |
909 | default: |
910 | llvm_unreachable("Unsupported element size"); |
911 | } |
912 | } |
913 | |
914 | template <bool IsVertical> |
915 | void AArch64InstPrinter::printMatrixTileVector(const MCInst *MI, unsigned OpNum, |
916 | const MCSubtargetInfo &STI, |
917 | raw_ostream &O) { |
918 | const MCOperand &RegOp = MI->getOperand(OpNum); |
919 | assert(RegOp.isReg() && "Unexpected operand type!"); |
920 | StringRef RegName = getRegisterName(RegOp.getReg()); |
921 | |
922 | |
923 | StringRef Base, Suffix; |
924 | std::tie(Base, Suffix) = RegName.split('.'); |
925 | O << Base << (IsVertical ? "v" : "h") << '.' << Suffix; |
926 | } |
927 | |
928 | void AArch64InstPrinter::printMatrixTile(const MCInst *MI, unsigned OpNum, |
929 | const MCSubtargetInfo &STI, |
930 | raw_ostream &O) { |
931 | const MCOperand &RegOp = MI->getOperand(OpNum); |
932 | assert(RegOp.isReg() && "Unexpected operand type!"); |
933 | O << getRegisterName(RegOp.getReg()); |
934 | } |
935 | |
936 | void AArch64InstPrinter::printSVCROp(const MCInst *MI, unsigned OpNum, |
937 | const MCSubtargetInfo &STI, |
938 | raw_ostream &O) { |
939 | const MCOperand &MO = MI->getOperand(OpNum); |
940 | assert(MO.isImm() && "Unexpected operand type!"); |
941 | unsigned svcrop = MO.getImm(); |
942 | const auto *SVCR = AArch64SVCR::lookupSVCRByEncoding(svcrop); |
943 | assert(SVCR && "Unexpected SVCR operand!"); |
944 | O << SVCR->Name; |
945 | } |
946 | |
947 | void AArch64InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, |
948 | const MCSubtargetInfo &STI, |
949 | raw_ostream &O) { |
950 | const MCOperand &Op = MI->getOperand(OpNo); |
951 | if (Op.isReg()) { |
952 | unsigned Reg = Op.getReg(); |
953 | O << getRegisterName(Reg); |
954 | } else if (Op.isImm()) { |
955 | printImm(MI, OpNo, STI, O); |
956 | } else { |
957 | assert(Op.isExpr() && "unknown operand kind in printOperand"); |
958 | Op.getExpr()->print(O, &MAI); |
959 | } |
960 | } |
961 | |
962 | void AArch64InstPrinter::printImm(const MCInst *MI, unsigned OpNo, |
963 | const MCSubtargetInfo &STI, |
964 | raw_ostream &O) { |
965 | const MCOperand &Op = MI->getOperand(OpNo); |
966 | O << "#" << formatImm(Op.getImm()); |
967 | } |
968 | |
969 | void AArch64InstPrinter::printImmHex(const MCInst *MI, unsigned OpNo, |
970 | const MCSubtargetInfo &STI, |
971 | raw_ostream &O) { |
972 | const MCOperand &Op = MI->getOperand(OpNo); |
973 | O << format("#%#llx", Op.getImm()); |
974 | } |
975 | |
976 | template<int Size> |
977 | void AArch64InstPrinter::printSImm(const MCInst *MI, unsigned OpNo, |
978 | const MCSubtargetInfo &STI, |
979 | raw_ostream &O) { |
980 | const MCOperand &Op = MI->getOperand(OpNo); |
981 | if (Size == 8) |
982 | O << "#" << formatImm((signed char)Op.getImm()); |
983 | else if (Size == 16) |
984 | O << "#" << formatImm((signed short)Op.getImm()); |
985 | else |
986 | O << "#" << formatImm(Op.getImm()); |
987 | } |
988 | |
989 | void AArch64InstPrinter::printPostIncOperand(const MCInst *MI, unsigned OpNo, |
990 | unsigned Imm, raw_ostream &O) { |
991 | const MCOperand &Op = MI->getOperand(OpNo); |
992 | if (Op.isReg()) { |
993 | unsigned Reg = Op.getReg(); |
994 | if (Reg == AArch64::XZR) |
995 | O << "#" << Imm; |
996 | else |
997 | O << getRegisterName(Reg); |
998 | } else |
999 | llvm_unreachable("unknown operand kind in printPostIncOperand64"); |
1000 | } |
1001 | |
1002 | void AArch64InstPrinter::printVRegOperand(const MCInst *MI, unsigned OpNo, |
1003 | const MCSubtargetInfo &STI, |
1004 | raw_ostream &O) { |
1005 | const MCOperand &Op = MI->getOperand(OpNo); |
1006 | assert(Op.isReg() && "Non-register vreg operand!"); |
1007 | unsigned Reg = Op.getReg(); |
1008 | O << getRegisterName(Reg, AArch64::vreg); |
1009 | } |
1010 | |
1011 | void AArch64InstPrinter::printSysCROperand(const MCInst *MI, unsigned OpNo, |
1012 | const MCSubtargetInfo &STI, |
1013 | raw_ostream &O) { |
1014 | const MCOperand &Op = MI->getOperand(OpNo); |
1015 | assert(Op.isImm() && "System instruction C[nm] operands must be immediates!"); |
1016 | O << "c" << Op.getImm(); |
1017 | } |
1018 | |
1019 | void AArch64InstPrinter::printAddSubImm(const MCInst *MI, unsigned OpNum, |
1020 | const MCSubtargetInfo &STI, |
1021 | raw_ostream &O) { |
1022 | const MCOperand &MO = MI->getOperand(OpNum); |
1023 | if (MO.isImm()) { |
1024 | unsigned Val = (MO.getImm() & 0xfff); |
1025 | assert(Val == MO.getImm() && "Add/sub immediate out of range!"); |
1026 | unsigned Shift = |
1027 | AArch64_AM::getShiftValue(MI->getOperand(OpNum + 1).getImm()); |
1028 | O << '#' << formatImm(Val); |
1029 | if (Shift != 0) { |
1030 | printShifter(MI, OpNum + 1, STI, O); |
1031 | if (CommentStream) |
1032 | *CommentStream << '=' << formatImm(Val << Shift) << '\n'; |
1033 | } |
1034 | } else { |
1035 | assert(MO.isExpr() && "Unexpected operand type!"); |
1036 | MO.getExpr()->print(O, &MAI); |
1037 | printShifter(MI, OpNum + 1, STI, O); |
1038 | } |
1039 | } |
1040 | |
1041 | template <typename T> |
1042 | void AArch64InstPrinter::printLogicalImm(const MCInst *MI, unsigned OpNum, |
1043 | const MCSubtargetInfo &STI, |
1044 | raw_ostream &O) { |
1045 | uint64_t Val = MI->getOperand(OpNum).getImm(); |
1046 | O << "#0x"; |
1047 | O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 8 * sizeof(T))); |
1048 | } |
1049 | |
1050 | void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum, |
1051 | const MCSubtargetInfo &STI, |
1052 | raw_ostream &O) { |
1053 | unsigned Val = MI->getOperand(OpNum).getImm(); |
1054 | |
1055 | if (AArch64_AM::getShiftType(Val) == AArch64_AM::LSL && |
1056 | AArch64_AM::getShiftValue(Val) == 0) |
1057 | return; |
1058 | O << ", " << AArch64_AM::getShiftExtendName(AArch64_AM::getShiftType(Val)) |
1059 | << " #" << AArch64_AM::getShiftValue(Val); |
1060 | } |
1061 | |
1062 | void AArch64InstPrinter::printShiftedRegister(const MCInst *MI, unsigned OpNum, |
1063 | const MCSubtargetInfo &STI, |
1064 | raw_ostream &O) { |
1065 | O << getRegisterName(MI->getOperand(OpNum).getReg()); |
1066 | printShifter(MI, OpNum + 1, STI, O); |
1067 | } |
1068 | |
1069 | void AArch64InstPrinter::printExtendedRegister(const MCInst *MI, unsigned OpNum, |
1070 | const MCSubtargetInfo &STI, |
1071 | raw_ostream &O) { |
1072 | O << getRegisterName(MI->getOperand(OpNum).getReg()); |
1073 | printArithExtend(MI, OpNum + 1, STI, O); |
1074 | } |
1075 | |
1076 | void AArch64InstPrinter::printArithExtend(const MCInst *MI, unsigned OpNum, |
1077 | const MCSubtargetInfo &STI, |
1078 | raw_ostream &O) { |
1079 | unsigned Val = MI->getOperand(OpNum).getImm(); |
1080 | AArch64_AM::ShiftExtendType ExtType = AArch64_AM::getArithExtendType(Val); |
1081 | unsigned ShiftVal = AArch64_AM::getArithShiftValue(Val); |
1082 | |
1083 | |
1084 | |
1085 | |
1086 | if (ExtType == AArch64_AM::UXTW || ExtType == AArch64_AM::UXTX) { |
1087 | unsigned Dest = MI->getOperand(0).getReg(); |
1088 | unsigned Src1 = MI->getOperand(1).getReg(); |
1089 | if ( ((Dest == AArch64::SP || Src1 == AArch64::SP) && |
1090 | ExtType == AArch64_AM::UXTX) || |
1091 | ((Dest == AArch64::WSP || Src1 == AArch64::WSP) && |
1092 | ExtType == AArch64_AM::UXTW) ) { |
1093 | if (ShiftVal != 0) |
1094 | O << ", lsl #" << ShiftVal; |
1095 | return; |
1096 | } |
1097 | } |
1098 | O << ", " << AArch64_AM::getShiftExtendName(ExtType); |
1099 | if (ShiftVal != 0) |
1100 | O << " #" << ShiftVal; |
1101 | } |
1102 | |
1103 | static void printMemExtendImpl(bool SignExtend, bool DoShift, |
1104 | unsigned Width, char SrcRegKind, |
1105 | raw_ostream &O) { |
1106 | |
1107 | bool IsLSL = !SignExtend && SrcRegKind == 'x'; |
1108 | if (IsLSL) |
1109 | O << "lsl"; |
1110 | else |
1111 | O << (SignExtend ? 's' : 'u') << "xt" << SrcRegKind; |
1112 | |
1113 | if (DoShift || IsLSL) |
1114 | O << " #" << Log2_32(Width / 8); |
1115 | } |
1116 | |
1117 | void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum, |
1118 | raw_ostream &O, char SrcRegKind, |
1119 | unsigned Width) { |
1120 | bool SignExtend = MI->getOperand(OpNum).getImm(); |
1121 | bool DoShift = MI->getOperand(OpNum + 1).getImm(); |
1122 | printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O); |
1123 | } |
1124 | |
1125 | template <bool SignExtend, int ExtWidth, char SrcRegKind, char Suffix> |
1126 | void AArch64InstPrinter::printRegWithShiftExtend(const MCInst *MI, |
1127 | unsigned OpNum, |
1128 | const MCSubtargetInfo &STI, |
1129 | raw_ostream &O) { |
1130 | printOperand(MI, OpNum, STI, O); |
1131 | if (Suffix == 's' || Suffix == 'd') |
1132 | O << '.' << Suffix; |
1133 | else |
1134 | assert(Suffix == 0 && "Unsupported suffix size"); |
1135 | |
1136 | bool DoShift = ExtWidth != 8; |
1137 | if (SignExtend || DoShift || SrcRegKind == 'w') { |
1138 | O << ", "; |
1139 | printMemExtendImpl(SignExtend, DoShift, ExtWidth, SrcRegKind, O); |
1140 | } |
1141 | } |
1142 | |
1143 | void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum, |
1144 | const MCSubtargetInfo &STI, |
1145 | raw_ostream &O) { |
1146 | AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm(); |
1147 | O << AArch64CC::getCondCodeName(CC); |
1148 | } |
1149 | |
1150 | void AArch64InstPrinter::printInverseCondCode(const MCInst *MI, unsigned OpNum, |
1151 | const MCSubtargetInfo &STI, |
1152 | raw_ostream &O) { |
1153 | AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm(); |
1154 | O << AArch64CC::getCondCodeName(AArch64CC::getInvertedCondCode(CC)); |
1155 | } |
1156 | |
1157 | void AArch64InstPrinter::printAMNoIndex(const MCInst *MI, unsigned OpNum, |
1158 | const MCSubtargetInfo &STI, |
1159 | raw_ostream &O) { |
1160 | O << '[' << getRegisterName(MI->getOperand(OpNum).getReg()) << ']'; |
1161 | } |
1162 | |
1163 | template<int Scale> |
1164 | void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum, |
1165 | const MCSubtargetInfo &STI, |
1166 | raw_ostream &O) { |
1167 | O << '#' << formatImm(Scale * MI->getOperand(OpNum).getImm()); |
1168 | } |
1169 | |
1170 | void AArch64InstPrinter::printUImm12Offset(const MCInst *MI, unsigned OpNum, |
1171 | unsigned Scale, raw_ostream &O) { |
1172 | const MCOperand MO = MI->getOperand(OpNum); |
1173 | if (MO.isImm()) { |
1174 | O << "#" << formatImm(MO.getImm() * Scale); |
1175 | } else { |
1176 | assert(MO.isExpr() && "Unexpected operand type!"); |
1177 | MO.getExpr()->print(O, &MAI); |
1178 | } |
1179 | } |
1180 | |
1181 | void AArch64InstPrinter::printAMIndexedWB(const MCInst *MI, unsigned OpNum, |
1182 | unsigned Scale, raw_ostream &O) { |
1183 | const MCOperand MO1 = MI->getOperand(OpNum + 1); |
1184 | O << '[' << getRegisterName(MI->getOperand(OpNum).getReg()); |
1185 | if (MO1.isImm()) { |
1186 | O << ", #" << formatImm(MO1.getImm() * Scale); |
1187 | } else { |
1188 | assert(MO1.isExpr() && "Unexpected operand type!"); |
1189 | O << ", "; |
1190 | MO1.getExpr()->print(O, &MAI); |
1191 | } |
1192 | O << ']'; |
1193 | } |
1194 | |
1195 | template <bool IsSVEPrefetch> |
1196 | void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum, |
1197 | const MCSubtargetInfo &STI, |
1198 | raw_ostream &O) { |
1199 | unsigned prfop = MI->getOperand(OpNum).getImm(); |
1200 | if (IsSVEPrefetch) { |
1201 | if (auto PRFM = AArch64SVEPRFM::lookupSVEPRFMByEncoding(prfop)) { |
1202 | O << PRFM->Name; |
1203 | return; |
1204 | } |
1205 | } else if (auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop)) { |
1206 | O << PRFM->Name; |
1207 | return; |
1208 | } |
1209 | |
1210 | O << '#' << formatImm(prfop); |
1211 | } |
1212 | |
1213 | void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum, |
1214 | const MCSubtargetInfo &STI, |
1215 | raw_ostream &O) { |
1216 | unsigned psbhintop = MI->getOperand(OpNum).getImm(); |
1217 | auto PSB = AArch64PSBHint::lookupPSBByEncoding(psbhintop); |
1218 | if (PSB) |
1219 | O << PSB->Name; |
1220 | else |
1221 | O << '#' << formatImm(psbhintop); |
1222 | } |
1223 | |
1224 | void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum, |
1225 | const MCSubtargetInfo &STI, |
1226 | raw_ostream &O) { |
1227 | unsigned btihintop = MI->getOperand(OpNum).getImm() ^ 32; |
1228 | auto BTI = AArch64BTIHint::lookupBTIByEncoding(btihintop); |
1229 | if (BTI) |
1230 | O << BTI->Name; |
1231 | else |
1232 | O << '#' << formatImm(btihintop); |
1233 | } |
1234 | |
1235 | void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, |
1236 | const MCSubtargetInfo &STI, |
1237 | raw_ostream &O) { |
1238 | const MCOperand &MO = MI->getOperand(OpNum); |
1239 | float FPImm = MO.isDFPImm() ? bit_cast<double>(MO.getDFPImm()) |
1240 | : AArch64_AM::getFPImmFloat(MO.getImm()); |
1241 | |
1242 | |
1243 | O << format("#%.8f", FPImm); |
1244 | } |
1245 | |
1246 | static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1) { |
1247 | while (Stride--) { |
1248 | switch (Reg) { |
1249 | default: |
1250 | llvm_unreachable("Vector register expected!"); |
1251 | case AArch64::Q0: Reg = AArch64::Q1; break; |
1252 | case AArch64::Q1: Reg = AArch64::Q2; break; |
1253 | case AArch64::Q2: Reg = AArch64::Q3; break; |
1254 | case AArch64::Q3: Reg = AArch64::Q4; break; |
1255 | case AArch64::Q4: Reg = AArch64::Q5; break; |
1256 | case AArch64::Q5: Reg = AArch64::Q6; break; |
1257 | case AArch64::Q6: Reg = AArch64::Q7; break; |
1258 | case AArch64::Q7: Reg = AArch64::Q8; break; |
1259 | case AArch64::Q8: Reg = AArch64::Q9; break; |
1260 | case AArch64::Q9: Reg = AArch64::Q10; break; |
1261 | case AArch64::Q10: Reg = AArch64::Q11; break; |
1262 | case AArch64::Q11: Reg = AArch64::Q12; break; |
1263 | case AArch64::Q12: Reg = AArch64::Q13; break; |
1264 | case AArch64::Q13: Reg = AArch64::Q14; break; |
1265 | case AArch64::Q14: Reg = AArch64::Q15; break; |
1266 | case AArch64::Q15: Reg = AArch64::Q16; break; |
1267 | case AArch64::Q16: Reg = AArch64::Q17; break; |
1268 | case AArch64::Q17: Reg = AArch64::Q18; break; |
1269 | case AArch64::Q18: Reg = AArch64::Q19; break; |
1270 | case AArch64::Q19: Reg = AArch64::Q20; break; |
1271 | case AArch64::Q20: Reg = AArch64::Q21; break; |
1272 | case AArch64::Q21: Reg = AArch64::Q22; break; |
1273 | case AArch64::Q22: Reg = AArch64::Q23; break; |
1274 | case AArch64::Q23: Reg = AArch64::Q24; break; |
1275 | case AArch64::Q24: Reg = AArch64::Q25; break; |
1276 | case AArch64::Q25: Reg = AArch64::Q26; break; |
1277 | case AArch64::Q26: Reg = AArch64::Q27; break; |
1278 | case AArch64::Q27: Reg = AArch64::Q28; break; |
1279 | case AArch64::Q28: Reg = AArch64::Q29; break; |
1280 | case AArch64::Q29: Reg = AArch64::Q30; break; |
1281 | case AArch64::Q30: Reg = AArch64::Q31; break; |
1282 | |
1283 | case AArch64::Q31: |
1284 | Reg = AArch64::Q0; |
1285 | break; |
1286 | case AArch64::Z0: Reg = AArch64::Z1; break; |
1287 | case AArch64::Z1: Reg = AArch64::Z2; break; |
1288 | case AArch64::Z2: Reg = AArch64::Z3; break; |
1289 | case AArch64::Z3: Reg = AArch64::Z4; break; |
1290 | case AArch64::Z4: Reg = AArch64::Z5; break; |
1291 | case AArch64::Z5: Reg = AArch64::Z6; break; |
1292 | case AArch64::Z6: Reg = AArch64::Z7; break; |
1293 | case AArch64::Z7: Reg = AArch64::Z8; break; |
1294 | case AArch64::Z8: Reg = AArch64::Z9; break; |
1295 | case AArch64::Z9: Reg = AArch64::Z10; break; |
1296 | case AArch64::Z10: Reg = AArch64::Z11; break; |
1297 | case AArch64::Z11: Reg = AArch64::Z12; break; |
1298 | case AArch64::Z12: Reg = AArch64::Z13; break; |
1299 | case AArch64::Z13: Reg = AArch64::Z14; break; |
1300 | case AArch64::Z14: Reg = AArch64::Z15; break; |
1301 | case AArch64::Z15: Reg = AArch64::Z16; break; |
1302 | case AArch64::Z16: Reg = AArch64::Z17; break; |
1303 | case AArch64::Z17: Reg = AArch64::Z18; break; |
1304 | case AArch64::Z18: Reg = AArch64::Z19; break; |
1305 | case AArch64::Z19: Reg = AArch64::Z20; break; |
1306 | case AArch64::Z20: Reg = AArch64::Z21; break; |
1307 | case AArch64::Z21: Reg = AArch64::Z22; break; |
1308 | case AArch64::Z22: Reg = AArch64::Z23; break; |
1309 | case AArch64::Z23: Reg = AArch64::Z24; break; |
1310 | case AArch64::Z24: Reg = AArch64::Z25; break; |
1311 | case AArch64::Z25: Reg = AArch64::Z26; break; |
1312 | case AArch64::Z26: Reg = AArch64::Z27; break; |
1313 | case AArch64::Z27: Reg = AArch64::Z28; break; |
1314 | case AArch64::Z28: Reg = AArch64::Z29; break; |
1315 | case AArch64::Z29: Reg = AArch64::Z30; break; |
1316 | case AArch64::Z30: Reg = AArch64::Z31; break; |
1317 | |
1318 | case AArch64::Z31: |
1319 | Reg = AArch64::Z0; |
1320 | break; |
1321 | } |
1322 | } |
1323 | return Reg; |
1324 | } |
1325 | |
1326 | template<unsigned size> |
1327 | void AArch64InstPrinter::printGPRSeqPairsClassOperand(const MCInst *MI, |
1328 | unsigned OpNum, |
1329 | const MCSubtargetInfo &STI, |
1330 | raw_ostream &O) { |
1331 | static_assert(size == 64 || size == 32, |
1332 | "Template parameter must be either 32 or 64"); |
1333 | unsigned Reg = MI->getOperand(OpNum).getReg(); |
1334 | |
1335 | unsigned Sube = (size == 32) ? AArch64::sube32 : AArch64::sube64; |
1336 | unsigned Subo = (size == 32) ? AArch64::subo32 : AArch64::subo64; |
1337 | |
1338 | unsigned Even = MRI.getSubReg(Reg, Sube); |
1339 | unsigned Odd = MRI.getSubReg(Reg, Subo); |
1340 | O << getRegisterName(Even) << ", " << getRegisterName(Odd); |
1341 | } |
1342 | |
1343 | static const unsigned MatrixZADRegisterTable[] = { |
1344 | AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3, |
1345 | AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7 |
1346 | }; |
1347 | |
1348 | void AArch64InstPrinter::printMatrixTileList(const MCInst *MI, unsigned OpNum, |
1349 | const MCSubtargetInfo &STI, |
1350 | raw_ostream &O) { |
1351 | unsigned MaxRegs = 8; |
1352 | unsigned RegMask = MI->getOperand(OpNum).getImm(); |
1353 | |
1354 | unsigned NumRegs = 0; |
1355 | for (unsigned I = 0; I < MaxRegs; ++I) |
1356 | if ((RegMask & (1 << I)) != 0) |
1357 | ++NumRegs; |
1358 | |
1359 | O << "{"; |
1360 | unsigned Printed = 0; |
1361 | for (unsigned I = 0; I < MaxRegs; ++I) { |
1362 | unsigned Reg = RegMask & (1 << I); |
1363 | if (Reg == 0) |
1364 | continue; |
1365 | O << getRegisterName(MatrixZADRegisterTable[I]); |
1366 | if (Printed + 1 != NumRegs) |
1367 | O << ", "; |
1368 | ++Printed; |
1369 | } |
1370 | O << "}"; |
1371 | } |
1372 | |
1373 | void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum, |
1374 | const MCSubtargetInfo &STI, |
1375 | raw_ostream &O, |
1376 | StringRef LayoutSuffix) { |
1377 | unsigned Reg = MI->getOperand(OpNum).getReg(); |
1378 | |
1379 | O << "{ "; |
1380 | |
1381 | |
1382 | |
1383 | unsigned NumRegs = 1; |
1384 | if (MRI.getRegClass(AArch64::DDRegClassID).contains(Reg) || |
1385 | MRI.getRegClass(AArch64::ZPR2RegClassID).contains(Reg) || |
1386 | MRI.getRegClass(AArch64::QQRegClassID).contains(Reg)) |
1387 | NumRegs = 2; |
1388 | else if (MRI.getRegClass(AArch64::DDDRegClassID).contains(Reg) || |
1389 | MRI.getRegClass(AArch64::ZPR3RegClassID).contains(Reg) || |
1390 | MRI.getRegClass(AArch64::QQQRegClassID).contains(Reg)) |
1391 | NumRegs = 3; |
1392 | else if (MRI.getRegClass(AArch64::DDDDRegClassID).contains(Reg) || |
1393 | MRI.getRegClass(AArch64::ZPR4RegClassID).contains(Reg) || |
1394 | MRI.getRegClass(AArch64::QQQQRegClassID).contains(Reg)) |
1395 | NumRegs = 4; |
1396 | |
1397 | |
1398 | if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::dsub0)) |
1399 | Reg = FirstReg; |
1400 | else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::qsub0)) |
1401 | Reg = FirstReg; |
1402 | else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::zsub0)) |
1403 | Reg = FirstReg; |
1404 | |
1405 | |
1406 | |
1407 | if (MRI.getRegClass(AArch64::FPR64RegClassID).contains(Reg)) { |
1408 | const MCRegisterClass &FPR128RC = |
1409 | MRI.getRegClass(AArch64::FPR128RegClassID); |
1410 | Reg = MRI.getMatchingSuperReg(Reg, AArch64::dsub, &FPR128RC); |
1411 | } |
1412 | |
1413 | for (unsigned i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg)) { |
1414 | if (MRI.getRegClass(AArch64::ZPRRegClassID).contains(Reg)) |
1415 | O << getRegisterName(Reg) << LayoutSuffix; |
1416 | else |
1417 | O << getRegisterName(Reg, AArch64::vreg) << LayoutSuffix; |
1418 | |
1419 | if (i + 1 != NumRegs) |
1420 | O << ", "; |
1421 | } |
1422 | |
1423 | O << " }"; |
1424 | } |
1425 | |
1426 | void |
1427 | AArch64InstPrinter::printImplicitlyTypedVectorList(const MCInst *MI, |
1428 | unsigned OpNum, |
1429 | const MCSubtargetInfo &STI, |
1430 | raw_ostream &O) { |
1431 | printVectorList(MI, OpNum, STI, O, ""); |
1432 | } |
1433 | |
1434 | template <unsigned NumLanes, char LaneKind> |
1435 | void AArch64InstPrinter::printTypedVectorList(const MCInst *MI, unsigned OpNum, |
1436 | const MCSubtargetInfo &STI, |
1437 | raw_ostream &O) { |
1438 | std::string Suffix("."); |
1439 | if (NumLanes) |
1440 | Suffix += itostr(NumLanes) + LaneKind; |
1441 | else |
1442 | Suffix += LaneKind; |
1443 | |
1444 | printVectorList(MI, OpNum, STI, O, Suffix); |
1445 | } |
1446 | |
1447 | void AArch64InstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, |
1448 | const MCSubtargetInfo &STI, |
1449 | raw_ostream &O) { |
1450 | O << "[" << MI->getOperand(OpNum).getImm() << "]"; |
1451 | } |
1452 | |
1453 | void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, uint64_t Address, |
1454 | unsigned OpNum, |
1455 | const MCSubtargetInfo &STI, |
1456 | raw_ostream &O) { |
1457 | const MCOperand &Op = MI->getOperand(OpNum); |
1458 | |
1459 | |
1460 | |
1461 | if (Op.isImm()) { |
1462 | int64_t Offset = Op.getImm() * 4; |
1463 | if (PrintBranchImmAsAddress) |
1464 | O << formatHex(Address + Offset); |
1465 | else |
1466 | O << "#" << formatImm(Offset); |
1467 | return; |
1468 | } |
1469 | |
1470 | |
1471 | const MCConstantExpr *BranchTarget = |
1472 | dyn_cast<MCConstantExpr>(MI->getOperand(OpNum).getExpr()); |
1473 | int64_t TargetAddress; |
1474 | if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) { |
1475 | O << formatHex(TargetAddress); |
1476 | } else { |
1477 | |
1478 | MI->getOperand(OpNum).getExpr()->print(O, &MAI); |
1479 | } |
1480 | } |
1481 | |
1482 | void AArch64InstPrinter::printAdrpLabel(const MCInst *MI, uint64_t Address, |
1483 | unsigned OpNum, |
1484 | const MCSubtargetInfo &STI, |
1485 | raw_ostream &O) { |
1486 | const MCOperand &Op = MI->getOperand(OpNum); |
1487 | |
1488 | |
1489 | |
1490 | if (Op.isImm()) { |
1491 | const int64_t Offset = Op.getImm() * 4096; |
1492 | if (PrintBranchImmAsAddress) |
1493 | O << formatHex((Address & -4096) + Offset); |
1494 | else |
1495 | O << "#" << Offset; |
1496 | return; |
1497 | } |
1498 | |
1499 | |
1500 | MI->getOperand(OpNum).getExpr()->print(O, &MAI); |
1501 | } |
1502 | |
1503 | void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo, |
1504 | const MCSubtargetInfo &STI, |
1505 | raw_ostream &O) { |
1506 | unsigned Val = MI->getOperand(OpNo).getImm(); |
1507 | unsigned Opcode = MI->getOpcode(); |
1508 | |
1509 | StringRef Name; |
1510 | if (Opcode == AArch64::ISB) { |
1511 | auto ISB = AArch64ISB::lookupISBByEncoding(Val); |
1512 | Name = ISB ? ISB->Name : ""; |
1513 | } else if (Opcode == AArch64::TSB) { |
1514 | auto TSB = AArch64TSB::lookupTSBByEncoding(Val); |
1515 | Name = TSB ? TSB->Name : ""; |
1516 | } else { |
1517 | auto DB = AArch64DB::lookupDBByEncoding(Val); |
1518 | Name = DB ? DB->Name : ""; |
1519 | } |
1520 | if (!Name.empty()) |
1521 | O << Name; |
1522 | else |
1523 | O << "#" << Val; |
1524 | } |
1525 | |
1526 | void AArch64InstPrinter::printBarriernXSOption(const MCInst *MI, unsigned OpNo, |
1527 | const MCSubtargetInfo &STI, |
1528 | raw_ostream &O) { |
1529 | unsigned Val = MI->getOperand(OpNo).getImm(); |
1530 | assert(MI->getOpcode() == AArch64::DSBnXS); |
1531 | |
1532 | StringRef Name; |
1533 | auto DB = AArch64DBnXS::lookupDBnXSByEncoding(Val); |
1534 | Name = DB ? DB->Name : ""; |
1535 | |
1536 | if (!Name.empty()) |
1537 | O << Name; |
1538 | else |
1539 | O << "#" << Val; |
1540 | } |
1541 | |
1542 | void AArch64InstPrinter::printMRSSystemRegister(const MCInst *MI, unsigned OpNo, |
1543 | const MCSubtargetInfo &STI, |
1544 | raw_ostream &O) { |
1545 | unsigned Val = MI->getOperand(OpNo).getImm(); |
1546 | |
1547 | |
1548 | |
1549 | |
1550 | if (Val == AArch64SysReg::DBGDTRRX_EL0) { |
1551 | O << "DBGDTRRX_EL0"; |
1552 | return; |
1553 | } |
1554 | |
1555 | |
1556 | if (Val == AArch64SysReg::TRCEXTINSELR) { |
1557 | O << "TRCEXTINSELR"; |
1558 | return; |
1559 | } |
1560 | |
1561 | const AArch64SysReg::SysReg *Reg = AArch64SysReg::lookupSysRegByEncoding(Val); |
1562 | if (Reg && Reg->Readable && Reg->haveFeatures(STI.getFeatureBits())) |
1563 | O << Reg->Name; |
1564 | else |
1565 | O << AArch64SysReg::genericRegisterString(Val); |
1566 | } |
1567 | |
1568 | void AArch64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo, |
1569 | const MCSubtargetInfo &STI, |
1570 | raw_ostream &O) { |
1571 | unsigned Val = MI->getOperand(OpNo).getImm(); |
1572 | |
1573 | |
1574 | |
1575 | |
1576 | if (Val == AArch64SysReg::DBGDTRTX_EL0) { |
1577 | O << "DBGDTRTX_EL0"; |
1578 | return; |
1579 | } |
1580 | |
1581 | |
1582 | if (Val == AArch64SysReg::TRCEXTINSELR) { |
1583 | O << "TRCEXTINSELR"; |
1584 | return; |
1585 | } |
1586 | |
1587 | const AArch64SysReg::SysReg *Reg = AArch64SysReg::lookupSysRegByEncoding(Val); |
1588 | if (Reg && Reg->Writeable && Reg->haveFeatures(STI.getFeatureBits())) |
1589 | O << Reg->Name; |
1590 | else |
1591 | O << AArch64SysReg::genericRegisterString(Val); |
1592 | } |
1593 | |
1594 | void AArch64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo, |
1595 | const MCSubtargetInfo &STI, |
1596 | raw_ostream &O) { |
1597 | unsigned Val = MI->getOperand(OpNo).getImm(); |
1598 | |
1599 | auto PState = AArch64PState::lookupPStateByEncoding(Val); |
1600 | if (PState && PState->haveFeatures(STI.getFeatureBits())) |
1601 | O << PState->Name; |
1602 | else |
1603 | O << "#" << formatImm(Val); |
1604 | } |
1605 | |
1606 | void AArch64InstPrinter::printSIMDType10Operand(const MCInst *MI, unsigned OpNo, |
1607 | const MCSubtargetInfo &STI, |
1608 | raw_ostream &O) { |
1609 | unsigned RawVal = MI->getOperand(OpNo).getImm(); |
1610 | uint64_t Val = AArch64_AM::decodeAdvSIMDModImmType10(RawVal); |
1611 | O << format("#%#016llx", Val); |
1612 | } |
1613 | |
1614 | template<int64_t Angle, int64_t Remainder> |
1615 | void AArch64InstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo, |
1616 | const MCSubtargetInfo &STI, |
1617 | raw_ostream &O) { |
1618 | unsigned Val = MI->getOperand(OpNo).getImm(); |
1619 | O << "#" << (Val * Angle) + Remainder; |
1620 | } |
1621 | |
1622 | void AArch64InstPrinter::printSVEPattern(const MCInst *MI, unsigned OpNum, |
1623 | const MCSubtargetInfo &STI, |
1624 | raw_ostream &O) { |
1625 | unsigned Val = MI->getOperand(OpNum).getImm(); |
1626 | if (auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByEncoding(Val)) |
1627 | O << Pat->Name; |
1628 | else |
1629 | O << '#' << formatImm(Val); |
1630 | } |
1631 | |
1632 | template <char suffix> |
1633 | void AArch64InstPrinter::printSVERegOp(const MCInst *MI, unsigned OpNum, |
1634 | const MCSubtargetInfo &STI, |
1635 | raw_ostream &O) { |
1636 | switch (suffix) { |
1637 | case 0: |
1638 | case 'b': |
1639 | case 'h': |
1640 | case 's': |
1641 | case 'd': |
1642 | case 'q': |
1643 | break; |
1644 | default: llvm_unreachable("Invalid kind specifier."); |
1645 | } |
1646 | |
1647 | unsigned Reg = MI->getOperand(OpNum).getReg(); |
1648 | O << getRegisterName(Reg); |
1649 | if (suffix != 0) |
1650 | O << '.' << suffix; |
1651 | } |
1652 | |
1653 | template <typename T> |
1654 | void AArch64InstPrinter::printImmSVE(T Value, raw_ostream &O) { |
1655 | std::make_unsigned_t<T> HexValue = Value; |
1656 | |
1657 | if (getPrintImmHex()) |
1658 | O << '#' << formatHex((uint64_t)HexValue); |
1659 | else |
1660 | O << '#' << formatDec(Value); |
1661 | |
1662 | if (CommentStream) { |
1663 | |
1664 | if (getPrintImmHex()) |
1665 | *CommentStream << '=' << formatDec(HexValue) << '\n'; |
1666 | else |
1667 | *CommentStream << '=' << formatHex((uint64_t)Value) << '\n'; |
1668 | } |
1669 | } |
1670 | |
1671 | template <typename T> |
1672 | void AArch64InstPrinter::printImm8OptLsl(const MCInst *MI, unsigned OpNum, |
1673 | const MCSubtargetInfo &STI, |
1674 | raw_ostream &O) { |
1675 | unsigned UnscaledVal = MI->getOperand(OpNum).getImm(); |
1676 | unsigned Shift = MI->getOperand(OpNum + 1).getImm(); |
1677 | assert(AArch64_AM::getShiftType(Shift) == AArch64_AM::LSL && |
1678 | "Unexepected shift type!"); |
1679 | |
1680 | |
1681 | if ((UnscaledVal == 0) && (AArch64_AM::getShiftValue(Shift) != 0)) { |
1682 | O << '#' << formatImm(UnscaledVal); |
1683 | printShifter(MI, OpNum + 1, STI, O); |
1684 | return; |
1685 | } |
1686 | |
1687 | T Val; |
1688 | if (std::is_signed<T>()) |
1689 | Val = (int8_t)UnscaledVal * (1 << AArch64_AM::getShiftValue(Shift)); |
1690 | else |
1691 | Val = (uint8_t)UnscaledVal * (1 << AArch64_AM::getShiftValue(Shift)); |
1692 | |
1693 | printImmSVE(Val, O); |
1694 | } |
1695 | |
1696 | template <typename T> |
1697 | void AArch64InstPrinter::printSVELogicalImm(const MCInst *MI, unsigned OpNum, |
1698 | const MCSubtargetInfo &STI, |
1699 | raw_ostream &O) { |
1700 | typedef std::make_signed_t<T> SignedT; |
1701 | typedef std::make_unsigned_t<T> UnsignedT; |
1702 | |
1703 | uint64_t Val = MI->getOperand(OpNum).getImm(); |
1704 | UnsignedT PrintVal = AArch64_AM::decodeLogicalImmediate(Val, 64); |
1705 | |
1706 | |
1707 | if ((int16_t)PrintVal == (SignedT)PrintVal) |
1708 | printImmSVE((T)PrintVal, O); |
1709 | else if ((uint16_t)PrintVal == PrintVal) |
1710 | printImmSVE(PrintVal, O); |
1711 | else |
1712 | O << '#' << formatHex((uint64_t)PrintVal); |
1713 | } |
1714 | |
1715 | template <int Width> |
1716 | void AArch64InstPrinter::printZPRasFPR(const MCInst *MI, unsigned OpNum, |
1717 | const MCSubtargetInfo &STI, |
1718 | raw_ostream &O) { |
1719 | unsigned Base; |
1720 | switch (Width) { |
1721 | case 8: Base = AArch64::B0; break; |
1722 | case 16: Base = AArch64::H0; break; |
1723 | case 32: Base = AArch64::S0; break; |
1724 | case 64: Base = AArch64::D0; break; |
1725 | case 128: Base = AArch64::Q0; break; |
1726 | default: |
1727 | llvm_unreachable("Unsupported width"); |
1728 | } |
1729 | unsigned Reg = MI->getOperand(OpNum).getReg(); |
1730 | O << getRegisterName(Reg - AArch64::Z0 + Base); |
1731 | } |
1732 | |
1733 | template <unsigned ImmIs0, unsigned ImmIs1> |
1734 | void AArch64InstPrinter::printExactFPImm(const MCInst *MI, unsigned OpNum, |
1735 | const MCSubtargetInfo &STI, |
1736 | raw_ostream &O) { |
1737 | auto *Imm0Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs0); |
1738 | auto *Imm1Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs1); |
1739 | unsigned Val = MI->getOperand(OpNum).getImm(); |
1740 | O << "#" << (Val ? Imm1Desc->Repr : Imm0Desc->Repr); |
1741 | } |
1742 | |
1743 | void AArch64InstPrinter::printGPR64as32(const MCInst *MI, unsigned OpNum, |
1744 | const MCSubtargetInfo &STI, |
1745 | raw_ostream &O) { |
1746 | unsigned Reg = MI->getOperand(OpNum).getReg(); |
1747 | O << getRegisterName(getWRegFromXReg(Reg)); |
1748 | } |
1749 | |
1750 | void AArch64InstPrinter::printGPR64x8(const MCInst *MI, unsigned OpNum, |
1751 | const MCSubtargetInfo &STI, |
1752 | raw_ostream &O) { |
1753 | unsigned Reg = MI->getOperand(OpNum).getReg(); |
1754 | O << getRegisterName(MRI.getSubReg(Reg, AArch64::x8sub_0)); |
1755 | } |