LLVM  17.0.0git
AArch64InstPrinter.cpp
Go to the documentation of this file.
1 //==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class prints an AArch64 MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AArch64InstPrinter.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"
24 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/Format.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 
45  const MCInstrInfo &MII,
46  const MCRegisterInfo &MRI)
47  : MCInstPrinter(MAI, MII, MRI) {}
48 
50  const MCInstrInfo &MII,
51  const MCRegisterInfo &MRI)
52  : AArch64InstPrinter(MAI, MII, MRI) {}
53 
55  if (Opt == "no-aliases") {
56  PrintAliases = false;
57  return true;
58  }
59  return false;
60 }
61 
63  OS << markup("<reg:") << getRegisterName(Reg) << markup(">");
64 }
65 
67  unsigned AltIdx) const {
68  OS << markup("<reg:") << getRegisterName(Reg, AltIdx) << markup(">");
69 }
70 
72  return getRegisterName(Reg);
73 }
74 
76  StringRef Annot, const MCSubtargetInfo &STI,
77  raw_ostream &O) {
78  // Check for special encodings and print the canonical alias instead.
79 
80  unsigned Opcode = MI->getOpcode();
81 
82  if (Opcode == AArch64::SYSxt)
83  if (printSysAlias(MI, STI, O)) {
84  printAnnotation(O, Annot);
85  return;
86  }
87 
88  if (Opcode == AArch64::SYSPxt || Opcode == AArch64::SYSPxt_XZR)
89  if (printSyspAlias(MI, STI, O)) {
90  printAnnotation(O, Annot);
91  return;
92  }
93 
94  // RPRFM overlaps PRFM (reg), so try to print it as RPRFM here.
95  if ((Opcode == AArch64::PRFMroX) || (Opcode == AArch64::PRFMroW)) {
96  if (printRangePrefetchAlias(MI, STI, O, Annot))
97  return;
98  }
99 
100  // SBFM/UBFM should print to a nicer aliased form if possible.
101  if (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri ||
102  Opcode == AArch64::UBFMXri || Opcode == AArch64::UBFMWri) {
103  const MCOperand &Op0 = MI->getOperand(0);
104  const MCOperand &Op1 = MI->getOperand(1);
105  const MCOperand &Op2 = MI->getOperand(2);
106  const MCOperand &Op3 = MI->getOperand(3);
107 
108  bool IsSigned = (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri);
109  bool Is64Bit = (Opcode == AArch64::SBFMXri || Opcode == AArch64::UBFMXri);
110  if (Op2.isImm() && Op2.getImm() == 0 && Op3.isImm()) {
111  const char *AsmMnemonic = nullptr;
112 
113  switch (Op3.getImm()) {
114  default:
115  break;
116  case 7:
117  if (IsSigned)
118  AsmMnemonic = "sxtb";
119  else if (!Is64Bit)
120  AsmMnemonic = "uxtb";
121  break;
122  case 15:
123  if (IsSigned)
124  AsmMnemonic = "sxth";
125  else if (!Is64Bit)
126  AsmMnemonic = "uxth";
127  break;
128  case 31:
129  // *xtw is only valid for signed 64-bit operations.
130  if (Is64Bit && IsSigned)
131  AsmMnemonic = "sxtw";
132  break;
133  }
134 
135  if (AsmMnemonic) {
136  O << '\t' << AsmMnemonic << '\t';
137  printRegName(O, Op0.getReg());
138  O << ", ";
140  printAnnotation(O, Annot);
141  return;
142  }
143  }
144 
145  // All immediate shifts are aliases, implemented using the Bitfield
146  // instruction. In all cases the immediate shift amount shift must be in
147  // the range 0 to (reg.size -1).
148  if (Op2.isImm() && Op3.isImm()) {
149  const char *AsmMnemonic = nullptr;
150  int shift = 0;
151  int64_t immr = Op2.getImm();
152  int64_t imms = Op3.getImm();
153  if (Opcode == AArch64::UBFMWri && imms != 0x1F && ((imms + 1) == immr)) {
154  AsmMnemonic = "lsl";
155  shift = 31 - imms;
156  } else if (Opcode == AArch64::UBFMXri && imms != 0x3f &&
157  ((imms + 1 == immr))) {
158  AsmMnemonic = "lsl";
159  shift = 63 - imms;
160  } else if (Opcode == AArch64::UBFMWri && imms == 0x1f) {
161  AsmMnemonic = "lsr";
162  shift = immr;
163  } else if (Opcode == AArch64::UBFMXri && imms == 0x3f) {
164  AsmMnemonic = "lsr";
165  shift = immr;
166  } else if (Opcode == AArch64::SBFMWri && imms == 0x1f) {
167  AsmMnemonic = "asr";
168  shift = immr;
169  } else if (Opcode == AArch64::SBFMXri && imms == 0x3f) {
170  AsmMnemonic = "asr";
171  shift = immr;
172  }
173  if (AsmMnemonic) {
174  O << '\t' << AsmMnemonic << '\t';
175  printRegName(O, Op0.getReg());
176  O << ", ";
177  printRegName(O, Op1.getReg());
178  O << ", " << markup("<imm:") << "#" << shift << markup(">");
179  printAnnotation(O, Annot);
180  return;
181  }
182  }
183 
184  // SBFIZ/UBFIZ aliases
185  if (Op2.getImm() > Op3.getImm()) {
186  O << '\t' << (IsSigned ? "sbfiz" : "ubfiz") << '\t';
187  printRegName(O, Op0.getReg());
188  O << ", ";
189  printRegName(O, Op1.getReg());
190  O << ", " << markup("<imm:") << "#" << (Is64Bit ? 64 : 32) - Op2.getImm()
191  << markup(">") << ", " << markup("<imm:") << "#" << Op3.getImm() + 1
192  << markup(">");
193  printAnnotation(O, Annot);
194  return;
195  }
196 
197  // Otherwise SBFX/UBFX is the preferred form
198  O << '\t' << (IsSigned ? "sbfx" : "ubfx") << '\t';
199  printRegName(O, Op0.getReg());
200  O << ", ";
201  printRegName(O, Op1.getReg());
202  O << ", " << markup("<imm:") << "#" << Op2.getImm() << markup(">") << ", "
203  << markup("<imm:") << "#" << Op3.getImm() - Op2.getImm() + 1
204  << markup(">");
205  printAnnotation(O, Annot);
206  return;
207  }
208 
209  if (Opcode == AArch64::BFMXri || Opcode == AArch64::BFMWri) {
210  const MCOperand &Op0 = MI->getOperand(0); // Op1 == Op0
211  const MCOperand &Op2 = MI->getOperand(2);
212  int ImmR = MI->getOperand(3).getImm();
213  int ImmS = MI->getOperand(4).getImm();
214 
215  if ((Op2.getReg() == AArch64::WZR || Op2.getReg() == AArch64::XZR) &&
216  (ImmR == 0 || ImmS < ImmR) &&
217  STI.getFeatureBits()[AArch64::HasV8_2aOps]) {
218  // BFC takes precedence over its entire range, sligtly differently to BFI.
219  int BitWidth = Opcode == AArch64::BFMXri ? 64 : 32;
220  int LSB = (BitWidth - ImmR) % BitWidth;
221  int Width = ImmS + 1;
222 
223  O << "\tbfc\t";
224  printRegName(O, Op0.getReg());
225  O << ", " << markup("<imm:") << "#" << LSB << markup(">") << ", "
226  << markup("<imm:") << "#" << Width << markup(">");
227  printAnnotation(O, Annot);
228  return;
229  } else if (ImmS < ImmR) {
230  // BFI alias
231  int BitWidth = Opcode == AArch64::BFMXri ? 64 : 32;
232  int LSB = (BitWidth - ImmR) % BitWidth;
233  int Width = ImmS + 1;
234 
235  O << "\tbfi\t";
236  printRegName(O, Op0.getReg());
237  O << ", ";
238  printRegName(O, Op2.getReg());
239  O << ", " << markup("<imm:") << "#" << LSB << markup(">") << ", "
240  << markup("<imm:") << "#" << Width << markup(">");
241  printAnnotation(O, Annot);
242  return;
243  }
244 
245  int LSB = ImmR;
246  int Width = ImmS - ImmR + 1;
247  // Otherwise BFXIL the preferred form
248  O << "\tbfxil\t";
249  printRegName(O, Op0.getReg());
250  O << ", ";
251  printRegName(O, Op2.getReg());
252  O << ", " << markup("<imm:") << "#" << LSB << markup(">") << ", "
253  << markup("<imm:") << "#" << Width << markup(">");
254  printAnnotation(O, Annot);
255  return;
256  }
257 
258  // Symbolic operands for MOVZ, MOVN and MOVK already imply a shift
259  // (e.g. :gottprel_g1: is always going to be "lsl #16") so it should not be
260  // printed.
261  if ((Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi ||
262  Opcode == AArch64::MOVNXi || Opcode == AArch64::MOVNWi) &&
263  MI->getOperand(1).isExpr()) {
264  if (Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi)
265  O << "\tmovz\t";
266  else
267  O << "\tmovn\t";
268 
269  printRegName(O, MI->getOperand(0).getReg());
270  O << ", " << markup("<imm:") << "#";
271  MI->getOperand(1).getExpr()->print(O, &MAI);
272  O << markup(">");
273  return;
274  }
275 
276  if ((Opcode == AArch64::MOVKXi || Opcode == AArch64::MOVKWi) &&
277  MI->getOperand(2).isExpr()) {
278  O << "\tmovk\t";
279  printRegName(O, MI->getOperand(0).getReg());
280  O << ", " << markup("<imm:") << "#";
281  MI->getOperand(2).getExpr()->print(O, &MAI);
282  O << markup(">");
283  return;
284  }
285 
286  // MOVZ, MOVN and "ORR wzr, #imm" instructions are aliases for MOV, but their
287  // domains overlap so they need to be prioritized. The chain is "MOVZ lsl #0 >
288  // MOVZ lsl #N > MOVN lsl #0 > MOVN lsl #N > ORR". The highest instruction
289  // that can represent the move is the MOV alias, and the rest get printed
290  // normally.
291  if ((Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi) &&
292  MI->getOperand(1).isImm() && MI->getOperand(2).isImm()) {
293  int RegWidth = Opcode == AArch64::MOVZXi ? 64 : 32;
294  int Shift = MI->getOperand(2).getImm();
295  uint64_t Value = (uint64_t)MI->getOperand(1).getImm() << Shift;
296 
298  Opcode == AArch64::MOVZXi ? 64 : 32)) {
299  O << "\tmov\t";
300  printRegName(O, MI->getOperand(0).getReg());
301  O << ", " << markup("<imm:") << "#"
302  << formatImm(SignExtend64(Value, RegWidth)) << markup(">");
303  return;
304  }
305  }
306 
307  if ((Opcode == AArch64::MOVNXi || Opcode == AArch64::MOVNWi) &&
308  MI->getOperand(1).isImm() && MI->getOperand(2).isImm()) {
309  int RegWidth = Opcode == AArch64::MOVNXi ? 64 : 32;
310  int Shift = MI->getOperand(2).getImm();
311  uint64_t Value = ~((uint64_t)MI->getOperand(1).getImm() << Shift);
312  if (RegWidth == 32)
313  Value = Value & 0xffffffff;
314 
315  if (AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth)) {
316  O << "\tmov\t";
317  printRegName(O, MI->getOperand(0).getReg());
318  O << ", " << markup("<imm:") << "#"
319  << formatImm(SignExtend64(Value, RegWidth)) << markup(">");
320  return;
321  }
322  }
323 
324  if ((Opcode == AArch64::ORRXri || Opcode == AArch64::ORRWri) &&
325  (MI->getOperand(1).getReg() == AArch64::XZR ||
326  MI->getOperand(1).getReg() == AArch64::WZR) &&
327  MI->getOperand(2).isImm()) {
328  int RegWidth = Opcode == AArch64::ORRXri ? 64 : 32;
330  MI->getOperand(2).getImm(), RegWidth);
331  if (!AArch64_AM::isAnyMOVWMovAlias(Value, RegWidth)) {
332  O << "\tmov\t";
333  printRegName(O, MI->getOperand(0).getReg());
334  O << ", " << markup("<imm:") << "#"
335  << formatImm(SignExtend64(Value, RegWidth)) << markup(">");
336  return;
337  }
338  }
339 
340  if (Opcode == AArch64::SPACE) {
341  O << '\t' << MAI.getCommentString() << " SPACE "
342  << MI->getOperand(1).getImm();
343  printAnnotation(O, Annot);
344  return;
345  }
346 
347  // Instruction TSB is specified as a one operand instruction, but 'csync' is
348  // not encoded, so for printing it is treated as a special case here:
349  if (Opcode == AArch64::TSB) {
350  O << "\ttsb\tcsync";
351  return;
352  }
353 
354  if (!PrintAliases || !printAliasInstr(MI, Address, STI, O))
355  printInstruction(MI, Address, STI, O);
356 
357  printAnnotation(O, Annot);
358 
359  if (atomicBarrierDroppedOnZero(Opcode) &&
360  (MI->getOperand(0).getReg() == AArch64::XZR ||
361  MI->getOperand(0).getReg() == AArch64::WZR)) {
362  printAnnotation(O, "acquire semantics dropped since destination is zero");
363  }
364 }
365 
366 static bool isTblTbxInstruction(unsigned Opcode, StringRef &Layout,
367  bool &IsTbx) {
368  switch (Opcode) {
369  case AArch64::TBXv8i8One:
370  case AArch64::TBXv8i8Two:
371  case AArch64::TBXv8i8Three:
372  case AArch64::TBXv8i8Four:
373  IsTbx = true;
374  Layout = ".8b";
375  return true;
376  case AArch64::TBLv8i8One:
377  case AArch64::TBLv8i8Two:
378  case AArch64::TBLv8i8Three:
379  case AArch64::TBLv8i8Four:
380  IsTbx = false;
381  Layout = ".8b";
382  return true;
383  case AArch64::TBXv16i8One:
384  case AArch64::TBXv16i8Two:
385  case AArch64::TBXv16i8Three:
386  case AArch64::TBXv16i8Four:
387  IsTbx = true;
388  Layout = ".16b";
389  return true;
390  case AArch64::TBLv16i8One:
391  case AArch64::TBLv16i8Two:
392  case AArch64::TBLv16i8Three:
393  case AArch64::TBLv16i8Four:
394  IsTbx = false;
395  Layout = ".16b";
396  return true;
397  default:
398  return false;
399  }
400 }
401 
403  unsigned Opcode;
404  const char *Mnemonic;
405  const char *Layout;
407  bool HasLane;
409 };
410 
411 static const LdStNInstrDesc LdStNInstInfo[] = {
412  { AArch64::LD1i8, "ld1", ".b", 1, true, 0 },
413  { AArch64::LD1i16, "ld1", ".h", 1, true, 0 },
414  { AArch64::LD1i32, "ld1", ".s", 1, true, 0 },
415  { AArch64::LD1i64, "ld1", ".d", 1, true, 0 },
416  { AArch64::LD1i8_POST, "ld1", ".b", 2, true, 1 },
417  { AArch64::LD1i16_POST, "ld1", ".h", 2, true, 2 },
418  { AArch64::LD1i32_POST, "ld1", ".s", 2, true, 4 },
419  { AArch64::LD1i64_POST, "ld1", ".d", 2, true, 8 },
420  { AArch64::LD1Rv16b, "ld1r", ".16b", 0, false, 0 },
421  { AArch64::LD1Rv8h, "ld1r", ".8h", 0, false, 0 },
422  { AArch64::LD1Rv4s, "ld1r", ".4s", 0, false, 0 },
423  { AArch64::LD1Rv2d, "ld1r", ".2d", 0, false, 0 },
424  { AArch64::LD1Rv8b, "ld1r", ".8b", 0, false, 0 },
425  { AArch64::LD1Rv4h, "ld1r", ".4h", 0, false, 0 },
426  { AArch64::LD1Rv2s, "ld1r", ".2s", 0, false, 0 },
427  { AArch64::LD1Rv1d, "ld1r", ".1d", 0, false, 0 },
428  { AArch64::LD1Rv16b_POST, "ld1r", ".16b", 1, false, 1 },
429  { AArch64::LD1Rv8h_POST, "ld1r", ".8h", 1, false, 2 },
430  { AArch64::LD1Rv4s_POST, "ld1r", ".4s", 1, false, 4 },
431  { AArch64::LD1Rv2d_POST, "ld1r", ".2d", 1, false, 8 },
432  { AArch64::LD1Rv8b_POST, "ld1r", ".8b", 1, false, 1 },
433  { AArch64::LD1Rv4h_POST, "ld1r", ".4h", 1, false, 2 },
434  { AArch64::LD1Rv2s_POST, "ld1r", ".2s", 1, false, 4 },
435  { AArch64::LD1Rv1d_POST, "ld1r", ".1d", 1, false, 8 },
436  { AArch64::LD1Onev16b, "ld1", ".16b", 0, false, 0 },
437  { AArch64::LD1Onev8h, "ld1", ".8h", 0, false, 0 },
438  { AArch64::LD1Onev4s, "ld1", ".4s", 0, false, 0 },
439  { AArch64::LD1Onev2d, "ld1", ".2d", 0, false, 0 },
440  { AArch64::LD1Onev8b, "ld1", ".8b", 0, false, 0 },
441  { AArch64::LD1Onev4h, "ld1", ".4h", 0, false, 0 },
442  { AArch64::LD1Onev2s, "ld1", ".2s", 0, false, 0 },
443  { AArch64::LD1Onev1d, "ld1", ".1d", 0, false, 0 },
444  { AArch64::LD1Onev16b_POST, "ld1", ".16b", 1, false, 16 },
445  { AArch64::LD1Onev8h_POST, "ld1", ".8h", 1, false, 16 },
446  { AArch64::LD1Onev4s_POST, "ld1", ".4s", 1, false, 16 },
447  { AArch64::LD1Onev2d_POST, "ld1", ".2d", 1, false, 16 },
448  { AArch64::LD1Onev8b_POST, "ld1", ".8b", 1, false, 8 },
449  { AArch64::LD1Onev4h_POST, "ld1", ".4h", 1, false, 8 },
450  { AArch64::LD1Onev2s_POST, "ld1", ".2s", 1, false, 8 },
451  { AArch64::LD1Onev1d_POST, "ld1", ".1d", 1, false, 8 },
452  { AArch64::LD1Twov16b, "ld1", ".16b", 0, false, 0 },
453  { AArch64::LD1Twov8h, "ld1", ".8h", 0, false, 0 },
454  { AArch64::LD1Twov4s, "ld1", ".4s", 0, false, 0 },
455  { AArch64::LD1Twov2d, "ld1", ".2d", 0, false, 0 },
456  { AArch64::LD1Twov8b, "ld1", ".8b", 0, false, 0 },
457  { AArch64::LD1Twov4h, "ld1", ".4h", 0, false, 0 },
458  { AArch64::LD1Twov2s, "ld1", ".2s", 0, false, 0 },
459  { AArch64::LD1Twov1d, "ld1", ".1d", 0, false, 0 },
460  { AArch64::LD1Twov16b_POST, "ld1", ".16b", 1, false, 32 },
461  { AArch64::LD1Twov8h_POST, "ld1", ".8h", 1, false, 32 },
462  { AArch64::LD1Twov4s_POST, "ld1", ".4s", 1, false, 32 },
463  { AArch64::LD1Twov2d_POST, "ld1", ".2d", 1, false, 32 },
464  { AArch64::LD1Twov8b_POST, "ld1", ".8b", 1, false, 16 },
465  { AArch64::LD1Twov4h_POST, "ld1", ".4h", 1, false, 16 },
466  { AArch64::LD1Twov2s_POST, "ld1", ".2s", 1, false, 16 },
467  { AArch64::LD1Twov1d_POST, "ld1", ".1d", 1, false, 16 },
468  { AArch64::LD1Threev16b, "ld1", ".16b", 0, false, 0 },
469  { AArch64::LD1Threev8h, "ld1", ".8h", 0, false, 0 },
470  { AArch64::LD1Threev4s, "ld1", ".4s", 0, false, 0 },
471  { AArch64::LD1Threev2d, "ld1", ".2d", 0, false, 0 },
472  { AArch64::LD1Threev8b, "ld1", ".8b", 0, false, 0 },
473  { AArch64::LD1Threev4h, "ld1", ".4h", 0, false, 0 },
474  { AArch64::LD1Threev2s, "ld1", ".2s", 0, false, 0 },
475  { AArch64::LD1Threev1d, "ld1", ".1d", 0, false, 0 },
476  { AArch64::LD1Threev16b_POST, "ld1", ".16b", 1, false, 48 },
477  { AArch64::LD1Threev8h_POST, "ld1", ".8h", 1, false, 48 },
478  { AArch64::LD1Threev4s_POST, "ld1", ".4s", 1, false, 48 },
479  { AArch64::LD1Threev2d_POST, "ld1", ".2d", 1, false, 48 },
480  { AArch64::LD1Threev8b_POST, "ld1", ".8b", 1, false, 24 },
481  { AArch64::LD1Threev4h_POST, "ld1", ".4h", 1, false, 24 },
482  { AArch64::LD1Threev2s_POST, "ld1", ".2s", 1, false, 24 },
483  { AArch64::LD1Threev1d_POST, "ld1", ".1d", 1, false, 24 },
484  { AArch64::LD1Fourv16b, "ld1", ".16b", 0, false, 0 },
485  { AArch64::LD1Fourv8h, "ld1", ".8h", 0, false, 0 },
486  { AArch64::LD1Fourv4s, "ld1", ".4s", 0, false, 0 },
487  { AArch64::LD1Fourv2d, "ld1", ".2d", 0, false, 0 },
488  { AArch64::LD1Fourv8b, "ld1", ".8b", 0, false, 0 },
489  { AArch64::LD1Fourv4h, "ld1", ".4h", 0, false, 0 },
490  { AArch64::LD1Fourv2s, "ld1", ".2s", 0, false, 0 },
491  { AArch64::LD1Fourv1d, "ld1", ".1d", 0, false, 0 },
492  { AArch64::LD1Fourv16b_POST, "ld1", ".16b", 1, false, 64 },
493  { AArch64::LD1Fourv8h_POST, "ld1", ".8h", 1, false, 64 },
494  { AArch64::LD1Fourv4s_POST, "ld1", ".4s", 1, false, 64 },
495  { AArch64::LD1Fourv2d_POST, "ld1", ".2d", 1, false, 64 },
496  { AArch64::LD1Fourv8b_POST, "ld1", ".8b", 1, false, 32 },
497  { AArch64::LD1Fourv4h_POST, "ld1", ".4h", 1, false, 32 },
498  { AArch64::LD1Fourv2s_POST, "ld1", ".2s", 1, false, 32 },
499  { AArch64::LD1Fourv1d_POST, "ld1", ".1d", 1, false, 32 },
500  { AArch64::LD2i8, "ld2", ".b", 1, true, 0 },
501  { AArch64::LD2i16, "ld2", ".h", 1, true, 0 },
502  { AArch64::LD2i32, "ld2", ".s", 1, true, 0 },
503  { AArch64::LD2i64, "ld2", ".d", 1, true, 0 },
504  { AArch64::LD2i8_POST, "ld2", ".b", 2, true, 2 },
505  { AArch64::LD2i16_POST, "ld2", ".h", 2, true, 4 },
506  { AArch64::LD2i32_POST, "ld2", ".s", 2, true, 8 },
507  { AArch64::LD2i64_POST, "ld2", ".d", 2, true, 16 },
508  { AArch64::LD2Rv16b, "ld2r", ".16b", 0, false, 0 },
509  { AArch64::LD2Rv8h, "ld2r", ".8h", 0, false, 0 },
510  { AArch64::LD2Rv4s, "ld2r", ".4s", 0, false, 0 },
511  { AArch64::LD2Rv2d, "ld2r", ".2d", 0, false, 0 },
512  { AArch64::LD2Rv8b, "ld2r", ".8b", 0, false, 0 },
513  { AArch64::LD2Rv4h, "ld2r", ".4h", 0, false, 0 },
514  { AArch64::LD2Rv2s, "ld2r", ".2s", 0, false, 0 },
515  { AArch64::LD2Rv1d, "ld2r", ".1d", 0, false, 0 },
516  { AArch64::LD2Rv16b_POST, "ld2r", ".16b", 1, false, 2 },
517  { AArch64::LD2Rv8h_POST, "ld2r", ".8h", 1, false, 4 },
518  { AArch64::LD2Rv4s_POST, "ld2r", ".4s", 1, false, 8 },
519  { AArch64::LD2Rv2d_POST, "ld2r", ".2d", 1, false, 16 },
520  { AArch64::LD2Rv8b_POST, "ld2r", ".8b", 1, false, 2 },
521  { AArch64::LD2Rv4h_POST, "ld2r", ".4h", 1, false, 4 },
522  { AArch64::LD2Rv2s_POST, "ld2r", ".2s", 1, false, 8 },
523  { AArch64::LD2Rv1d_POST, "ld2r", ".1d", 1, false, 16 },
524  { AArch64::LD2Twov16b, "ld2", ".16b", 0, false, 0 },
525  { AArch64::LD2Twov8h, "ld2", ".8h", 0, false, 0 },
526  { AArch64::LD2Twov4s, "ld2", ".4s", 0, false, 0 },
527  { AArch64::LD2Twov2d, "ld2", ".2d", 0, false, 0 },
528  { AArch64::LD2Twov8b, "ld2", ".8b", 0, false, 0 },
529  { AArch64::LD2Twov4h, "ld2", ".4h", 0, false, 0 },
530  { AArch64::LD2Twov2s, "ld2", ".2s", 0, false, 0 },
531  { AArch64::LD2Twov16b_POST, "ld2", ".16b", 1, false, 32 },
532  { AArch64::LD2Twov8h_POST, "ld2", ".8h", 1, false, 32 },
533  { AArch64::LD2Twov4s_POST, "ld2", ".4s", 1, false, 32 },
534  { AArch64::LD2Twov2d_POST, "ld2", ".2d", 1, false, 32 },
535  { AArch64::LD2Twov8b_POST, "ld2", ".8b", 1, false, 16 },
536  { AArch64::LD2Twov4h_POST, "ld2", ".4h", 1, false, 16 },
537  { AArch64::LD2Twov2s_POST, "ld2", ".2s", 1, false, 16 },
538  { AArch64::LD3i8, "ld3", ".b", 1, true, 0 },
539  { AArch64::LD3i16, "ld3", ".h", 1, true, 0 },
540  { AArch64::LD3i32, "ld3", ".s", 1, true, 0 },
541  { AArch64::LD3i64, "ld3", ".d", 1, true, 0 },
542  { AArch64::LD3i8_POST, "ld3", ".b", 2, true, 3 },
543  { AArch64::LD3i16_POST, "ld3", ".h", 2, true, 6 },
544  { AArch64::LD3i32_POST, "ld3", ".s", 2, true, 12 },
545  { AArch64::LD3i64_POST, "ld3", ".d", 2, true, 24 },
546  { AArch64::LD3Rv16b, "ld3r", ".16b", 0, false, 0 },
547  { AArch64::LD3Rv8h, "ld3r", ".8h", 0, false, 0 },
548  { AArch64::LD3Rv4s, "ld3r", ".4s", 0, false, 0 },
549  { AArch64::LD3Rv2d, "ld3r", ".2d", 0, false, 0 },
550  { AArch64::LD3Rv8b, "ld3r", ".8b", 0, false, 0 },
551  { AArch64::LD3Rv4h, "ld3r", ".4h", 0, false, 0 },
552  { AArch64::LD3Rv2s, "ld3r", ".2s", 0, false, 0 },
553  { AArch64::LD3Rv1d, "ld3r", ".1d", 0, false, 0 },
554  { AArch64::LD3Rv16b_POST, "ld3r", ".16b", 1, false, 3 },
555  { AArch64::LD3Rv8h_POST, "ld3r", ".8h", 1, false, 6 },
556  { AArch64::LD3Rv4s_POST, "ld3r", ".4s", 1, false, 12 },
557  { AArch64::LD3Rv2d_POST, "ld3r", ".2d", 1, false, 24 },
558  { AArch64::LD3Rv8b_POST, "ld3r", ".8b", 1, false, 3 },
559  { AArch64::LD3Rv4h_POST, "ld3r", ".4h", 1, false, 6 },
560  { AArch64::LD3Rv2s_POST, "ld3r", ".2s", 1, false, 12 },
561  { AArch64::LD3Rv1d_POST, "ld3r", ".1d", 1, false, 24 },
562  { AArch64::LD3Threev16b, "ld3", ".16b", 0, false, 0 },
563  { AArch64::LD3Threev8h, "ld3", ".8h", 0, false, 0 },
564  { AArch64::LD3Threev4s, "ld3", ".4s", 0, false, 0 },
565  { AArch64::LD3Threev2d, "ld3", ".2d", 0, false, 0 },
566  { AArch64::LD3Threev8b, "ld3", ".8b", 0, false, 0 },
567  { AArch64::LD3Threev4h, "ld3", ".4h", 0, false, 0 },
568  { AArch64::LD3Threev2s, "ld3", ".2s", 0, false, 0 },
569  { AArch64::LD3Threev16b_POST, "ld3", ".16b", 1, false, 48 },
570  { AArch64::LD3Threev8h_POST, "ld3", ".8h", 1, false, 48 },
571  { AArch64::LD3Threev4s_POST, "ld3", ".4s", 1, false, 48 },
572  { AArch64::LD3Threev2d_POST, "ld3", ".2d", 1, false, 48 },
573  { AArch64::LD3Threev8b_POST, "ld3", ".8b", 1, false, 24 },
574  { AArch64::LD3Threev4h_POST, "ld3", ".4h", 1, false, 24 },
575  { AArch64::LD3Threev2s_POST, "ld3", ".2s", 1, false, 24 },
576  { AArch64::LD4i8, "ld4", ".b", 1, true, 0 },
577  { AArch64::LD4i16, "ld4", ".h", 1, true, 0 },
578  { AArch64::LD4i32, "ld4", ".s", 1, true, 0 },
579  { AArch64::LD4i64, "ld4", ".d", 1, true, 0 },
580  { AArch64::LD4i8_POST, "ld4", ".b", 2, true, 4 },
581  { AArch64::LD4i16_POST, "ld4", ".h", 2, true, 8 },
582  { AArch64::LD4i32_POST, "ld4", ".s", 2, true, 16 },
583  { AArch64::LD4i64_POST, "ld4", ".d", 2, true, 32 },
584  { AArch64::LD4Rv16b, "ld4r", ".16b", 0, false, 0 },
585  { AArch64::LD4Rv8h, "ld4r", ".8h", 0, false, 0 },
586  { AArch64::LD4Rv4s, "ld4r", ".4s", 0, false, 0 },
587  { AArch64::LD4Rv2d, "ld4r", ".2d", 0, false, 0 },
588  { AArch64::LD4Rv8b, "ld4r", ".8b", 0, false, 0 },
589  { AArch64::LD4Rv4h, "ld4r", ".4h", 0, false, 0 },
590  { AArch64::LD4Rv2s, "ld4r", ".2s", 0, false, 0 },
591  { AArch64::LD4Rv1d, "ld4r", ".1d", 0, false, 0 },
592  { AArch64::LD4Rv16b_POST, "ld4r", ".16b", 1, false, 4 },
593  { AArch64::LD4Rv8h_POST, "ld4r", ".8h", 1, false, 8 },
594  { AArch64::LD4Rv4s_POST, "ld4r", ".4s", 1, false, 16 },
595  { AArch64::LD4Rv2d_POST, "ld4r", ".2d", 1, false, 32 },
596  { AArch64::LD4Rv8b_POST, "ld4r", ".8b", 1, false, 4 },
597  { AArch64::LD4Rv4h_POST, "ld4r", ".4h", 1, false, 8 },
598  { AArch64::LD4Rv2s_POST, "ld4r", ".2s", 1, false, 16 },
599  { AArch64::LD4Rv1d_POST, "ld4r", ".1d", 1, false, 32 },
600  { AArch64::LD4Fourv16b, "ld4", ".16b", 0, false, 0 },
601  { AArch64::LD4Fourv8h, "ld4", ".8h", 0, false, 0 },
602  { AArch64::LD4Fourv4s, "ld4", ".4s", 0, false, 0 },
603  { AArch64::LD4Fourv2d, "ld4", ".2d", 0, false, 0 },
604  { AArch64::LD4Fourv8b, "ld4", ".8b", 0, false, 0 },
605  { AArch64::LD4Fourv4h, "ld4", ".4h", 0, false, 0 },
606  { AArch64::LD4Fourv2s, "ld4", ".2s", 0, false, 0 },
607  { AArch64::LD4Fourv16b_POST, "ld4", ".16b", 1, false, 64 },
608  { AArch64::LD4Fourv8h_POST, "ld4", ".8h", 1, false, 64 },
609  { AArch64::LD4Fourv4s_POST, "ld4", ".4s", 1, false, 64 },
610  { AArch64::LD4Fourv2d_POST, "ld4", ".2d", 1, false, 64 },
611  { AArch64::LD4Fourv8b_POST, "ld4", ".8b", 1, false, 32 },
612  { AArch64::LD4Fourv4h_POST, "ld4", ".4h", 1, false, 32 },
613  { AArch64::LD4Fourv2s_POST, "ld4", ".2s", 1, false, 32 },
614  { AArch64::ST1i8, "st1", ".b", 0, true, 0 },
615  { AArch64::ST1i16, "st1", ".h", 0, true, 0 },
616  { AArch64::ST1i32, "st1", ".s", 0, true, 0 },
617  { AArch64::ST1i64, "st1", ".d", 0, true, 0 },
618  { AArch64::ST1i8_POST, "st1", ".b", 1, true, 1 },
619  { AArch64::ST1i16_POST, "st1", ".h", 1, true, 2 },
620  { AArch64::ST1i32_POST, "st1", ".s", 1, true, 4 },
621  { AArch64::ST1i64_POST, "st1", ".d", 1, true, 8 },
622  { AArch64::ST1Onev16b, "st1", ".16b", 0, false, 0 },
623  { AArch64::ST1Onev8h, "st1", ".8h", 0, false, 0 },
624  { AArch64::ST1Onev4s, "st1", ".4s", 0, false, 0 },
625  { AArch64::ST1Onev2d, "st1", ".2d", 0, false, 0 },
626  { AArch64::ST1Onev8b, "st1", ".8b", 0, false, 0 },
627  { AArch64::ST1Onev4h, "st1", ".4h", 0, false, 0 },
628  { AArch64::ST1Onev2s, "st1", ".2s", 0, false, 0 },
629  { AArch64::ST1Onev1d, "st1", ".1d", 0, false, 0 },
630  { AArch64::ST1Onev16b_POST, "st1", ".16b", 1, false, 16 },
631  { AArch64::ST1Onev8h_POST, "st1", ".8h", 1, false, 16 },
632  { AArch64::ST1Onev4s_POST, "st1", ".4s", 1, false, 16 },
633  { AArch64::ST1Onev2d_POST, "st1", ".2d", 1, false, 16 },
634  { AArch64::ST1Onev8b_POST, "st1", ".8b", 1, false, 8 },
635  { AArch64::ST1Onev4h_POST, "st1", ".4h", 1, false, 8 },
636  { AArch64::ST1Onev2s_POST, "st1", ".2s", 1, false, 8 },
637  { AArch64::ST1Onev1d_POST, "st1", ".1d", 1, false, 8 },
638  { AArch64::ST1Twov16b, "st1", ".16b", 0, false, 0 },
639  { AArch64::ST1Twov8h, "st1", ".8h", 0, false, 0 },
640  { AArch64::ST1Twov4s, "st1", ".4s", 0, false, 0 },
641  { AArch64::ST1Twov2d, "st1", ".2d", 0, false, 0 },
642  { AArch64::ST1Twov8b, "st1", ".8b", 0, false, 0 },
643  { AArch64::ST1Twov4h, "st1", ".4h", 0, false, 0 },
644  { AArch64::ST1Twov2s, "st1", ".2s", 0, false, 0 },
645  { AArch64::ST1Twov1d, "st1", ".1d", 0, false, 0 },
646  { AArch64::ST1Twov16b_POST, "st1", ".16b", 1, false, 32 },
647  { AArch64::ST1Twov8h_POST, "st1", ".8h", 1, false, 32 },
648  { AArch64::ST1Twov4s_POST, "st1", ".4s", 1, false, 32 },
649  { AArch64::ST1Twov2d_POST, "st1", ".2d", 1, false, 32 },
650  { AArch64::ST1Twov8b_POST, "st1", ".8b", 1, false, 16 },
651  { AArch64::ST1Twov4h_POST, "st1", ".4h", 1, false, 16 },
652  { AArch64::ST1Twov2s_POST, "st1", ".2s", 1, false, 16 },
653  { AArch64::ST1Twov1d_POST, "st1", ".1d", 1, false, 16 },
654  { AArch64::ST1Threev16b, "st1", ".16b", 0, false, 0 },
655  { AArch64::ST1Threev8h, "st1", ".8h", 0, false, 0 },
656  { AArch64::ST1Threev4s, "st1", ".4s", 0, false, 0 },
657  { AArch64::ST1Threev2d, "st1", ".2d", 0, false, 0 },
658  { AArch64::ST1Threev8b, "st1", ".8b", 0, false, 0 },
659  { AArch64::ST1Threev4h, "st1", ".4h", 0, false, 0 },
660  { AArch64::ST1Threev2s, "st1", ".2s", 0, false, 0 },
661  { AArch64::ST1Threev1d, "st1", ".1d", 0, false, 0 },
662  { AArch64::ST1Threev16b_POST, "st1", ".16b", 1, false, 48 },
663  { AArch64::ST1Threev8h_POST, "st1", ".8h", 1, false, 48 },
664  { AArch64::ST1Threev4s_POST, "st1", ".4s", 1, false, 48 },
665  { AArch64::ST1Threev2d_POST, "st1", ".2d", 1, false, 48 },
666  { AArch64::ST1Threev8b_POST, "st1", ".8b", 1, false, 24 },
667  { AArch64::ST1Threev4h_POST, "st1", ".4h", 1, false, 24 },
668  { AArch64::ST1Threev2s_POST, "st1", ".2s", 1, false, 24 },
669  { AArch64::ST1Threev1d_POST, "st1", ".1d", 1, false, 24 },
670  { AArch64::ST1Fourv16b, "st1", ".16b", 0, false, 0 },
671  { AArch64::ST1Fourv8h, "st1", ".8h", 0, false, 0 },
672  { AArch64::ST1Fourv4s, "st1", ".4s", 0, false, 0 },
673  { AArch64::ST1Fourv2d, "st1", ".2d", 0, false, 0 },
674  { AArch64::ST1Fourv8b, "st1", ".8b", 0, false, 0 },
675  { AArch64::ST1Fourv4h, "st1", ".4h", 0, false, 0 },
676  { AArch64::ST1Fourv2s, "st1", ".2s", 0, false, 0 },
677  { AArch64::ST1Fourv1d, "st1", ".1d", 0, false, 0 },
678  { AArch64::ST1Fourv16b_POST, "st1", ".16b", 1, false, 64 },
679  { AArch64::ST1Fourv8h_POST, "st1", ".8h", 1, false, 64 },
680  { AArch64::ST1Fourv4s_POST, "st1", ".4s", 1, false, 64 },
681  { AArch64::ST1Fourv2d_POST, "st1", ".2d", 1, false, 64 },
682  { AArch64::ST1Fourv8b_POST, "st1", ".8b", 1, false, 32 },
683  { AArch64::ST1Fourv4h_POST, "st1", ".4h", 1, false, 32 },
684  { AArch64::ST1Fourv2s_POST, "st1", ".2s", 1, false, 32 },
685  { AArch64::ST1Fourv1d_POST, "st1", ".1d", 1, false, 32 },
686  { AArch64::ST2i8, "st2", ".b", 0, true, 0 },
687  { AArch64::ST2i16, "st2", ".h", 0, true, 0 },
688  { AArch64::ST2i32, "st2", ".s", 0, true, 0 },
689  { AArch64::ST2i64, "st2", ".d", 0, true, 0 },
690  { AArch64::ST2i8_POST, "st2", ".b", 1, true, 2 },
691  { AArch64::ST2i16_POST, "st2", ".h", 1, true, 4 },
692  { AArch64::ST2i32_POST, "st2", ".s", 1, true, 8 },
693  { AArch64::ST2i64_POST, "st2", ".d", 1, true, 16 },
694  { AArch64::ST2Twov16b, "st2", ".16b", 0, false, 0 },
695  { AArch64::ST2Twov8h, "st2", ".8h", 0, false, 0 },
696  { AArch64::ST2Twov4s, "st2", ".4s", 0, false, 0 },
697  { AArch64::ST2Twov2d, "st2", ".2d", 0, false, 0 },
698  { AArch64::ST2Twov8b, "st2", ".8b", 0, false, 0 },
699  { AArch64::ST2Twov4h, "st2", ".4h", 0, false, 0 },
700  { AArch64::ST2Twov2s, "st2", ".2s", 0, false, 0 },
701  { AArch64::ST2Twov16b_POST, "st2", ".16b", 1, false, 32 },
702  { AArch64::ST2Twov8h_POST, "st2", ".8h", 1, false, 32 },
703  { AArch64::ST2Twov4s_POST, "st2", ".4s", 1, false, 32 },
704  { AArch64::ST2Twov2d_POST, "st2", ".2d", 1, false, 32 },
705  { AArch64::ST2Twov8b_POST, "st2", ".8b", 1, false, 16 },
706  { AArch64::ST2Twov4h_POST, "st2", ".4h", 1, false, 16 },
707  { AArch64::ST2Twov2s_POST, "st2", ".2s", 1, false, 16 },
708  { AArch64::ST3i8, "st3", ".b", 0, true, 0 },
709  { AArch64::ST3i16, "st3", ".h", 0, true, 0 },
710  { AArch64::ST3i32, "st3", ".s", 0, true, 0 },
711  { AArch64::ST3i64, "st3", ".d", 0, true, 0 },
712  { AArch64::ST3i8_POST, "st3", ".b", 1, true, 3 },
713  { AArch64::ST3i16_POST, "st3", ".h", 1, true, 6 },
714  { AArch64::ST3i32_POST, "st3", ".s", 1, true, 12 },
715  { AArch64::ST3i64_POST, "st3", ".d", 1, true, 24 },
716  { AArch64::ST3Threev16b, "st3", ".16b", 0, false, 0 },
717  { AArch64::ST3Threev8h, "st3", ".8h", 0, false, 0 },
718  { AArch64::ST3Threev4s, "st3", ".4s", 0, false, 0 },
719  { AArch64::ST3Threev2d, "st3", ".2d", 0, false, 0 },
720  { AArch64::ST3Threev8b, "st3", ".8b", 0, false, 0 },
721  { AArch64::ST3Threev4h, "st3", ".4h", 0, false, 0 },
722  { AArch64::ST3Threev2s, "st3", ".2s", 0, false, 0 },
723  { AArch64::ST3Threev16b_POST, "st3", ".16b", 1, false, 48 },
724  { AArch64::ST3Threev8h_POST, "st3", ".8h", 1, false, 48 },
725  { AArch64::ST3Threev4s_POST, "st3", ".4s", 1, false, 48 },
726  { AArch64::ST3Threev2d_POST, "st3", ".2d", 1, false, 48 },
727  { AArch64::ST3Threev8b_POST, "st3", ".8b", 1, false, 24 },
728  { AArch64::ST3Threev4h_POST, "st3", ".4h", 1, false, 24 },
729  { AArch64::ST3Threev2s_POST, "st3", ".2s", 1, false, 24 },
730  { AArch64::ST4i8, "st4", ".b", 0, true, 0 },
731  { AArch64::ST4i16, "st4", ".h", 0, true, 0 },
732  { AArch64::ST4i32, "st4", ".s", 0, true, 0 },
733  { AArch64::ST4i64, "st4", ".d", 0, true, 0 },
734  { AArch64::ST4i8_POST, "st4", ".b", 1, true, 4 },
735  { AArch64::ST4i16_POST, "st4", ".h", 1, true, 8 },
736  { AArch64::ST4i32_POST, "st4", ".s", 1, true, 16 },
737  { AArch64::ST4i64_POST, "st4", ".d", 1, true, 32 },
738  { AArch64::ST4Fourv16b, "st4", ".16b", 0, false, 0 },
739  { AArch64::ST4Fourv8h, "st4", ".8h", 0, false, 0 },
740  { AArch64::ST4Fourv4s, "st4", ".4s", 0, false, 0 },
741  { AArch64::ST4Fourv2d, "st4", ".2d", 0, false, 0 },
742  { AArch64::ST4Fourv8b, "st4", ".8b", 0, false, 0 },
743  { AArch64::ST4Fourv4h, "st4", ".4h", 0, false, 0 },
744  { AArch64::ST4Fourv2s, "st4", ".2s", 0, false, 0 },
745  { AArch64::ST4Fourv16b_POST, "st4", ".16b", 1, false, 64 },
746  { AArch64::ST4Fourv8h_POST, "st4", ".8h", 1, false, 64 },
747  { AArch64::ST4Fourv4s_POST, "st4", ".4s", 1, false, 64 },
748  { AArch64::ST4Fourv2d_POST, "st4", ".2d", 1, false, 64 },
749  { AArch64::ST4Fourv8b_POST, "st4", ".8b", 1, false, 32 },
750  { AArch64::ST4Fourv4h_POST, "st4", ".4h", 1, false, 32 },
751  { AArch64::ST4Fourv2s_POST, "st4", ".2s", 1, false, 32 },
752 };
753 
754 static const LdStNInstrDesc *getLdStNInstrDesc(unsigned Opcode) {
755  for (const auto &Info : LdStNInstInfo)
756  if (Info.Opcode == Opcode)
757  return &Info;
758 
759  return nullptr;
760 }
761 
763  StringRef Annot,
764  const MCSubtargetInfo &STI,
765  raw_ostream &O) {
766  unsigned Opcode = MI->getOpcode();
767  StringRef Layout;
768 
769  bool IsTbx;
770  if (isTblTbxInstruction(MI->getOpcode(), Layout, IsTbx)) {
771  O << "\t" << (IsTbx ? "tbx" : "tbl") << Layout << '\t';
772  printRegName(O, MI->getOperand(0).getReg(), AArch64::vreg);
773  O << ", ";
774 
775  unsigned ListOpNum = IsTbx ? 2 : 1;
776  printVectorList(MI, ListOpNum, STI, O, "");
777 
778  O << ", ";
779  printRegName(O, MI->getOperand(ListOpNum + 1).getReg(), AArch64::vreg);
780  printAnnotation(O, Annot);
781  return;
782  }
783 
784  if (const LdStNInstrDesc *LdStDesc = getLdStNInstrDesc(Opcode)) {
785  O << "\t" << LdStDesc->Mnemonic << LdStDesc->Layout << '\t';
786 
787  // Now onto the operands: first a vector list with possible lane
788  // specifier. E.g. { v0 }[2]
789  int OpNum = LdStDesc->ListOperand;
790  printVectorList(MI, OpNum++, STI, O, "");
791 
792  if (LdStDesc->HasLane)
793  O << '[' << MI->getOperand(OpNum++).getImm() << ']';
794 
795  // Next the address: [xN]
796  unsigned AddrReg = MI->getOperand(OpNum++).getReg();
797  O << ", [";
798  printRegName(O, AddrReg);
799  O << ']';
800 
801  // Finally, there might be a post-indexed offset.
802  if (LdStDesc->NaturalOffset != 0) {
803  unsigned Reg = MI->getOperand(OpNum++).getReg();
804  if (Reg != AArch64::XZR) {
805  O << ", ";
806  printRegName(O, Reg);
807  } else {
808  assert(LdStDesc->NaturalOffset && "no offset on post-inc instruction?");
809  O << ", " << markup("<imm:") << "#" << LdStDesc->NaturalOffset
810  << markup(">");
811  }
812  }
813 
814  printAnnotation(O, Annot);
815  return;
816  }
817 
818  AArch64InstPrinter::printInst(MI, Address, Annot, STI, O);
819 }
820 
822  return getRegisterName(Reg);
823 }
824 
826  const MCSubtargetInfo &STI,
827  raw_ostream &O,
828  StringRef Annot) {
829  unsigned Opcode = MI->getOpcode();
830 
831 #ifndef NDEBUG
832  assert(((Opcode == AArch64::PRFMroX) || (Opcode == AArch64::PRFMroW)) &&
833  "Invalid opcode for RPRFM alias!");
834 #endif
835 
836  unsigned PRFOp = MI->getOperand(0).getImm();
837  unsigned Mask = 0x18; // 0b11000
838  if ((PRFOp & Mask) != Mask)
839  return false; // Rt != '11xxx', it's a PRFM instruction.
840 
841  unsigned Rm = MI->getOperand(2).getReg();
842 
843  // "Rm" must be a 64-bit GPR for RPRFM.
844  if (MRI.getRegClass(AArch64::GPR32RegClassID).contains(Rm))
845  Rm = MRI.getMatchingSuperReg(Rm, AArch64::sub_32,
846  &MRI.getRegClass(AArch64::GPR64RegClassID));
847 
848  unsigned SignExtend = MI->getOperand(3).getImm(); // encoded in "option<2>".
849  unsigned Shift = MI->getOperand(4).getImm(); // encoded in "S".
850 
851  assert((SignExtend <= 1) && "sign extend should be a single bit!");
852  assert((Shift <= 1) && "Shift should be a single bit!");
853 
854  unsigned Option0 = (Opcode == AArch64::PRFMroX) ? 1 : 0;
855 
856  // encoded in "option<2>:option<0>:S:Rt<2:0>".
857  unsigned RPRFOp =
858  (SignExtend << 5) | (Option0 << 4) | (Shift << 3) | (PRFOp & 0x7);
859 
860  O << "\trprfm ";
861  if (auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(RPRFOp))
862  O << RPRFM->Name << ", ";
863  else
864  O << "#" << formatImm(RPRFOp) << ", ";
865  O << getRegisterName(Rm);
866  O << ", [";
867  printOperand(MI, 1, STI, O); // "Rn".
868  O << "]";
869 
870  printAnnotation(O, Annot);
871 
872  return true;
873 }
874 
876  const MCSubtargetInfo &STI,
877  raw_ostream &O) {
878 #ifndef NDEBUG
879  unsigned Opcode = MI->getOpcode();
880  assert(Opcode == AArch64::SYSxt && "Invalid opcode for SYS alias!");
881 #endif
882 
883  const MCOperand &Op1 = MI->getOperand(0);
884  const MCOperand &Cn = MI->getOperand(1);
885  const MCOperand &Cm = MI->getOperand(2);
886  const MCOperand &Op2 = MI->getOperand(3);
887 
888  unsigned Op1Val = Op1.getImm();
889  unsigned CnVal = Cn.getImm();
890  unsigned CmVal = Cm.getImm();
891  unsigned Op2Val = Op2.getImm();
892 
893  uint16_t Encoding = Op2Val;
894  Encoding |= CmVal << 3;
895  Encoding |= CnVal << 7;
896  Encoding |= Op1Val << 11;
897 
898  bool NeedsReg;
899  std::string Ins;
900  std::string Name;
901 
902  if (CnVal == 7) {
903  switch (CmVal) {
904  default: return false;
905  // Maybe IC, maybe Prediction Restriction
906  case 1:
907  switch (Op1Val) {
908  default: return false;
909  case 0: goto Search_IC;
910  case 3: goto Search_PRCTX;
911  }
912  // Prediction Restriction aliases
913  case 3: {
914  Search_PRCTX:
915  if (Op1Val != 3 || CnVal != 7 || CmVal != 3)
916  return false;
917 
918  const auto Requires =
919  Op2Val == 6 ? AArch64::FeatureSPECRES2 : AArch64::FeaturePredRes;
920  if (!(STI.hasFeature(AArch64::FeatureAll) || STI.hasFeature(Requires)))
921  return false;
922 
923  NeedsReg = true;
924  switch (Op2Val) {
925  default: return false;
926  case 4: Ins = "cfp\t"; break;
927  case 5: Ins = "dvp\t"; break;
928  case 6: Ins = "cosp\t"; break;
929  case 7: Ins = "cpp\t"; break;
930  }
931  Name = "RCTX";
932  }
933  break;
934  // IC aliases
935  case 5: {
936  Search_IC:
937  const AArch64IC::IC *IC = AArch64IC::lookupICByEncoding(Encoding);
938  if (!IC || !IC->haveFeatures(STI.getFeatureBits()))
939  return false;
940 
941  NeedsReg = IC->NeedsReg;
942  Ins = "ic\t";
943  Name = std::string(IC->Name);
944  }
945  break;
946  // DC aliases
947  case 4: case 6: case 10: case 11: case 12: case 13: case 14:
948  {
949  const AArch64DC::DC *DC = AArch64DC::lookupDCByEncoding(Encoding);
950  if (!DC || !DC->haveFeatures(STI.getFeatureBits()))
951  return false;
952 
953  NeedsReg = true;
954  Ins = "dc\t";
955  Name = std::string(DC->Name);
956  }
957  break;
958  // AT aliases
959  case 8: case 9: {
960  const AArch64AT::AT *AT = AArch64AT::lookupATByEncoding(Encoding);
961  if (!AT || !AT->haveFeatures(STI.getFeatureBits()))
962  return false;
963 
964  NeedsReg = true;
965  Ins = "at\t";
966  Name = std::string(AT->Name);
967  }
968  break;
969  }
970  } else if (CnVal == 8 || CnVal == 9) {
971  // TLBI aliases
972  const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByEncoding(Encoding);
973  if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits()))
974  return false;
975 
976  NeedsReg = TLBI->NeedsReg;
977  Ins = "tlbi\t";
978  Name = std::string(TLBI->Name);
979  }
980  else
981  return false;
982 
983  std::string Str = Ins + Name;
984  std::transform(Str.begin(), Str.end(), Str.begin(), ::tolower);
985 
986  O << '\t' << Str;
987  if (NeedsReg) {
988  O << ", ";
989  printRegName(O, MI->getOperand(4).getReg());
990  }
991 
992  return true;
993 }
994 
996  const MCSubtargetInfo &STI,
997  raw_ostream &O) {
998 #ifndef NDEBUG
999  unsigned Opcode = MI->getOpcode();
1000  assert((Opcode == AArch64::SYSPxt || Opcode == AArch64::SYSPxt_XZR) &&
1001  "Invalid opcode for SYSP alias!");
1002 #endif
1003 
1004  const MCOperand &Op1 = MI->getOperand(0);
1005  const MCOperand &Cn = MI->getOperand(1);
1006  const MCOperand &Cm = MI->getOperand(2);
1007  const MCOperand &Op2 = MI->getOperand(3);
1008 
1009  unsigned Op1Val = Op1.getImm();
1010  unsigned CnVal = Cn.getImm();
1011  unsigned CmVal = Cm.getImm();
1012  unsigned Op2Val = Op2.getImm();
1013 
1014  uint16_t Encoding = Op2Val;
1015  Encoding |= CmVal << 3;
1016  Encoding |= CnVal << 7;
1017  Encoding |= Op1Val << 11;
1018 
1019  std::string Ins;
1020  std::string Name;
1021 
1022  if (CnVal == 8 || CnVal == 9) {
1023  // TLBIP aliases
1024 
1025  if (CnVal == 9) {
1026  if (!STI.hasFeature(AArch64::FeatureXS))
1027  return false;
1028  Encoding &= ~(1 << 7);
1029  }
1030 
1031  const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByEncoding(Encoding);
1032  if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits()))
1033  return false;
1034 
1035  Ins = "tlbip\t";
1036  Name = std::string(TLBI->Name);
1037  if (CnVal == 9)
1038  Name += "nXS";
1039  } else
1040  return false;
1041 
1042  std::string Str = Ins + Name;
1043  std::transform(Str.begin(), Str.end(), Str.begin(), ::tolower);
1044 
1045  O << '\t' << Str;
1046  O << ", ";
1047  if (MI->getOperand(4).getReg() == AArch64::XZR)
1048  printSyspXzrPair(MI, 4, STI, O);
1049  else
1050  printGPRSeqPairsClassOperand<64>(MI, 4, STI, O);
1051 
1052  return true;
1053 }
1054 
1055 template <int EltSize>
1056 void AArch64InstPrinter::printMatrix(const MCInst *MI, unsigned OpNum,
1057  const MCSubtargetInfo &STI,
1058  raw_ostream &O) {
1059  const MCOperand &RegOp = MI->getOperand(OpNum);
1060  assert(RegOp.isReg() && "Unexpected operand type!");
1061 
1062  printRegName(O, RegOp.getReg());
1063  switch (EltSize) {
1064  case 0:
1065  break;
1066  case 8:
1067  O << ".b";
1068  break;
1069  case 16:
1070  O << ".h";
1071  break;
1072  case 32:
1073  O << ".s";
1074  break;
1075  case 64:
1076  O << ".d";
1077  break;
1078  case 128:
1079  O << ".q";
1080  break;
1081  default:
1082  llvm_unreachable("Unsupported element size");
1083  }
1084 }
1085 
1086 template <bool IsVertical>
1088  const MCSubtargetInfo &STI,
1089  raw_ostream &O) {
1090  const MCOperand &RegOp = MI->getOperand(OpNum);
1091  assert(RegOp.isReg() && "Unexpected operand type!");
1093 
1094  // Insert the horizontal/vertical flag before the suffix.
1095  StringRef Base, Suffix;
1096  std::tie(Base, Suffix) = RegName.split('.');
1097  O << Base << (IsVertical ? "v" : "h") << '.' << Suffix;
1098 }
1099 
1100 void AArch64InstPrinter::printMatrixTile(const MCInst *MI, unsigned OpNum,
1101  const MCSubtargetInfo &STI,
1102  raw_ostream &O) {
1103  const MCOperand &RegOp = MI->getOperand(OpNum);
1104  assert(RegOp.isReg() && "Unexpected operand type!");
1105  printRegName(O, RegOp.getReg());
1106 }
1107 
1108 void AArch64InstPrinter::printSVCROp(const MCInst *MI, unsigned OpNum,
1109  const MCSubtargetInfo &STI,
1110  raw_ostream &O) {
1111  const MCOperand &MO = MI->getOperand(OpNum);
1112  assert(MO.isImm() && "Unexpected operand type!");
1113  unsigned svcrop = MO.getImm();
1114  const auto *SVCR = AArch64SVCR::lookupSVCRByEncoding(svcrop);
1115  assert(SVCR && "Unexpected SVCR operand!");
1116  O << SVCR->Name;
1117 }
1118 
1119 void AArch64InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1120  const MCSubtargetInfo &STI,
1121  raw_ostream &O) {
1122  const MCOperand &Op = MI->getOperand(OpNo);
1123  if (Op.isReg()) {
1124  unsigned Reg = Op.getReg();
1125  printRegName(O, Reg);
1126  } else if (Op.isImm()) {
1127  printImm(MI, OpNo, STI, O);
1128  } else {
1129  assert(Op.isExpr() && "unknown operand kind in printOperand");
1130  Op.getExpr()->print(O, &MAI);
1131  }
1132 }
1133 
1134 void AArch64InstPrinter::printImm(const MCInst *MI, unsigned OpNo,
1135  const MCSubtargetInfo &STI,
1136  raw_ostream &O) {
1137  const MCOperand &Op = MI->getOperand(OpNo);
1138  O << markup("<imm:") << "#" << formatImm(Op.getImm()) << markup(">");
1139 }
1140 
1141 void AArch64InstPrinter::printImmHex(const MCInst *MI, unsigned OpNo,
1142  const MCSubtargetInfo &STI,
1143  raw_ostream &O) {
1144  const MCOperand &Op = MI->getOperand(OpNo);
1145  O << markup("<imm:") << format("#%#llx", Op.getImm()) << markup(">");
1146 }
1147 
1148 template<int Size>
1149 void AArch64InstPrinter::printSImm(const MCInst *MI, unsigned OpNo,
1150  const MCSubtargetInfo &STI,
1151  raw_ostream &O) {
1152  const MCOperand &Op = MI->getOperand(OpNo);
1153  if (Size == 8)
1154  O << markup("<imm:") << "#" << formatImm((signed char)Op.getImm())
1155  << markup(">");
1156  else if (Size == 16)
1157  O << markup("<imm:") << "#" << formatImm((signed short)Op.getImm())
1158  << markup(">");
1159  else
1160  O << markup("<imm:") << "#" << formatImm(Op.getImm()) << markup(">");
1161 }
1162 
1164  unsigned Imm, raw_ostream &O) {
1165  const MCOperand &Op = MI->getOperand(OpNo);
1166  if (Op.isReg()) {
1167  unsigned Reg = Op.getReg();
1168  if (Reg == AArch64::XZR)
1169  O << markup("<imm:") << "#" << Imm << markup(">");
1170  else
1171  printRegName(O, Reg);
1172  } else
1173  llvm_unreachable("unknown operand kind in printPostIncOperand64");
1174 }
1175 
1177  const MCSubtargetInfo &STI,
1178  raw_ostream &O) {
1179  const MCOperand &Op = MI->getOperand(OpNo);
1180  assert(Op.isReg() && "Non-register vreg operand!");
1181  unsigned Reg = Op.getReg();
1182  printRegName(O, Reg, AArch64::vreg);
1183 }
1184 
1186  const MCSubtargetInfo &STI,
1187  raw_ostream &O) {
1188  const MCOperand &Op = MI->getOperand(OpNo);
1189  assert(Op.isImm() && "System instruction C[nm] operands must be immediates!");
1190  O << "c" << Op.getImm();
1191 }
1192 
1193 void AArch64InstPrinter::printAddSubImm(const MCInst *MI, unsigned OpNum,
1194  const MCSubtargetInfo &STI,
1195  raw_ostream &O) {
1196  const MCOperand &MO = MI->getOperand(OpNum);
1197  if (MO.isImm()) {
1198  unsigned Val = (MO.getImm() & 0xfff);
1199  assert(Val == MO.getImm() && "Add/sub immediate out of range!");
1200  unsigned Shift =
1201  AArch64_AM::getShiftValue(MI->getOperand(OpNum + 1).getImm());
1202  O << markup("<imm:") << '#' << formatImm(Val) << markup(">");
1203  if (Shift != 0) {
1204  printShifter(MI, OpNum + 1, STI, O);
1205  if (CommentStream)
1206  *CommentStream << '=' << formatImm(Val << Shift) << '\n';
1207  }
1208  } else {
1209  assert(MO.isExpr() && "Unexpected operand type!");
1210  MO.getExpr()->print(O, &MAI);
1211  printShifter(MI, OpNum + 1, STI, O);
1212  }
1213 }
1214 
1215 template <typename T>
1216 void AArch64InstPrinter::printLogicalImm(const MCInst *MI, unsigned OpNum,
1217  const MCSubtargetInfo &STI,
1218  raw_ostream &O) {
1219  uint64_t Val = MI->getOperand(OpNum).getImm();
1220  O << markup("<imm:") << "#0x";
1221  O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 8 * sizeof(T)));
1222  O << markup(">");
1223 }
1224 
1225 void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum,
1226  const MCSubtargetInfo &STI,
1227  raw_ostream &O) {
1228  unsigned Val = MI->getOperand(OpNum).getImm();
1229  // LSL #0 should not be printed.
1231  AArch64_AM::getShiftValue(Val) == 0)
1232  return;
1234  << " " << markup("<imm:") << "#" << AArch64_AM::getShiftValue(Val)
1235  << markup(">");
1236 }
1237 
1239  const MCSubtargetInfo &STI,
1240  raw_ostream &O) {
1241  printRegName(O, MI->getOperand(OpNum).getReg());
1242  printShifter(MI, OpNum + 1, STI, O);
1243 }
1244 
1246  const MCSubtargetInfo &STI,
1247  raw_ostream &O) {
1248  printRegName(O, MI->getOperand(OpNum).getReg());
1249  printArithExtend(MI, OpNum + 1, STI, O);
1250 }
1251 
1252 void AArch64InstPrinter::printArithExtend(const MCInst *MI, unsigned OpNum,
1253  const MCSubtargetInfo &STI,
1254  raw_ostream &O) {
1255  unsigned Val = MI->getOperand(OpNum).getImm();
1257  unsigned ShiftVal = AArch64_AM::getArithShiftValue(Val);
1258 
1259  // If the destination or first source register operand is [W]SP, print
1260  // UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at
1261  // all.
1262  if (ExtType == AArch64_AM::UXTW || ExtType == AArch64_AM::UXTX) {
1263  unsigned Dest = MI->getOperand(0).getReg();
1264  unsigned Src1 = MI->getOperand(1).getReg();
1265  if ( ((Dest == AArch64::SP || Src1 == AArch64::SP) &&
1266  ExtType == AArch64_AM::UXTX) ||
1267  ((Dest == AArch64::WSP || Src1 == AArch64::WSP) &&
1268  ExtType == AArch64_AM::UXTW) ) {
1269  if (ShiftVal != 0)
1270  O << ", lsl " << markup("<imm:") << "#" << ShiftVal << markup(">");
1271  return;
1272  }
1273  }
1274  O << ", " << AArch64_AM::getShiftExtendName(ExtType);
1275  if (ShiftVal != 0)
1276  O << " " << markup("<imm:") << "#" << ShiftVal << markup(">");
1277 }
1278 
1279 static void printMemExtendImpl(bool SignExtend, bool DoShift, unsigned Width,
1280  char SrcRegKind, raw_ostream &O,
1281  bool UseMarkup) {
1282  // sxtw, sxtx, uxtw or lsl (== uxtx)
1283  bool IsLSL = !SignExtend && SrcRegKind == 'x';
1284  if (IsLSL)
1285  O << "lsl";
1286  else
1287  O << (SignExtend ? 's' : 'u') << "xt" << SrcRegKind;
1288 
1289  if (DoShift || IsLSL) {
1290  O << " ";
1291  if (UseMarkup)
1292  O << "<imm:";
1293  O << "#" << Log2_32(Width / 8);
1294  if (UseMarkup)
1295  O << ">";
1296  }
1297 }
1298 
1299 void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum,
1300  raw_ostream &O, char SrcRegKind,
1301  unsigned Width) {
1302  bool SignExtend = MI->getOperand(OpNum).getImm();
1303  bool DoShift = MI->getOperand(OpNum + 1).getImm();
1304  printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O, UseMarkup);
1305 }
1306 
1307 template <bool SignExtend, int ExtWidth, char SrcRegKind, char Suffix>
1309  unsigned OpNum,
1310  const MCSubtargetInfo &STI,
1311  raw_ostream &O) {
1312  printOperand(MI, OpNum, STI, O);
1313  if (Suffix == 's' || Suffix == 'd')
1314  O << '.' << Suffix;
1315  else
1316  assert(Suffix == 0 && "Unsupported suffix size");
1317 
1318  bool DoShift = ExtWidth != 8;
1319  if (SignExtend || DoShift || SrcRegKind == 'w') {
1320  O << ", ";
1321  printMemExtendImpl(SignExtend, DoShift, ExtWidth, SrcRegKind, O, UseMarkup);
1322  }
1323 }
1324 
1325 template <int EltSize>
1327  unsigned OpNum,
1328  const MCSubtargetInfo &STI,
1329  raw_ostream &O) {
1330  unsigned Reg = MI->getOperand(OpNum).getReg();
1331 
1332  assert(Reg <= AArch64::P15 && "Unsupported predicate register");
1333  O << "pn" << (Reg - AArch64::P0);
1334  switch (EltSize) {
1335  case 0:
1336  break;
1337  case 8:
1338  O << ".b";
1339  break;
1340  case 16:
1341  O << ".h";
1342  break;
1343  case 32:
1344  O << ".s";
1345  break;
1346  case 64:
1347  O << ".d";
1348  break;
1349  default:
1350  llvm_unreachable("Unsupported element size");
1351  }
1352 }
1353 
1354 void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum,
1355  const MCSubtargetInfo &STI,
1356  raw_ostream &O) {
1357  AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm();
1359 }
1360 
1362  const MCSubtargetInfo &STI,
1363  raw_ostream &O) {
1364  AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm();
1366 }
1367 
1368 void AArch64InstPrinter::printAMNoIndex(const MCInst *MI, unsigned OpNum,
1369  const MCSubtargetInfo &STI,
1370  raw_ostream &O) {
1371  O << '[';
1372  printRegName(O, MI->getOperand(OpNum).getReg());
1373  O << ']';
1374 }
1375 
1376 template <int Scale>
1377 void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum,
1378  const MCSubtargetInfo &STI,
1379  raw_ostream &O) {
1380  O << markup("<imm:") << '#'
1381  << formatImm(Scale * MI->getOperand(OpNum).getImm()) << markup(">");
1382 }
1383 
1384 template <int Scale, int Offset>
1386  const MCSubtargetInfo &STI,
1387  raw_ostream &O) {
1388  unsigned FirstImm = Scale * MI->getOperand(OpNum).getImm();
1389  O << formatImm(FirstImm);
1390  O << ":" << formatImm(FirstImm + Offset);
1391 }
1392 
1394  unsigned Scale, raw_ostream &O) {
1395  const MCOperand MO = MI->getOperand(OpNum);
1396  if (MO.isImm()) {
1397  O << markup("<imm:") << '#' << formatImm(MO.getImm() * Scale)
1398  << markup(">");
1399  } else {
1400  assert(MO.isExpr() && "Unexpected operand type!");
1401  MO.getExpr()->print(O, &MAI);
1402  }
1403 }
1404 
1405 void AArch64InstPrinter::printAMIndexedWB(const MCInst *MI, unsigned OpNum,
1406  unsigned Scale, raw_ostream &O) {
1407  const MCOperand MO1 = MI->getOperand(OpNum + 1);
1408  O << '[';
1409  printRegName(O, MI->getOperand(OpNum).getReg());
1410  if (MO1.isImm()) {
1411  O << ", " << markup("<imm:") << "#" << formatImm(MO1.getImm() * Scale)
1412  << markup(">");
1413  } else {
1414  assert(MO1.isExpr() && "Unexpected operand type!");
1415  O << ", ";
1416  MO1.getExpr()->print(O, &MAI);
1417  }
1418  O << ']';
1419 }
1420 
1422  const MCSubtargetInfo &STI,
1423  raw_ostream &O) {
1424  unsigned prfop = MI->getOperand(OpNum).getImm();
1425  if (auto PRFM = AArch64RPRFM::lookupRPRFMByEncoding(prfop)) {
1426  O << PRFM->Name;
1427  return;
1428  }
1429 
1430  O << '#' << formatImm(prfop);
1431 }
1432 
1433 template <bool IsSVEPrefetch>
1434 void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum,
1435  const MCSubtargetInfo &STI,
1436  raw_ostream &O) {
1437  unsigned prfop = MI->getOperand(OpNum).getImm();
1438  if (IsSVEPrefetch) {
1439  if (auto PRFM = AArch64SVEPRFM::lookupSVEPRFMByEncoding(prfop)) {
1440  O << PRFM->Name;
1441  return;
1442  }
1443  } else {
1444  auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop);
1445  if (PRFM && PRFM->haveFeatures(STI.getFeatureBits())) {
1446  O << PRFM->Name;
1447  return;
1448  }
1449  }
1450 
1451  O << markup("<imm:") << '#' << formatImm(prfop) << markup(">");
1452 }
1453 
1454 void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum,
1455  const MCSubtargetInfo &STI,
1456  raw_ostream &O) {
1457  unsigned psbhintop = MI->getOperand(OpNum).getImm();
1458  auto PSB = AArch64PSBHint::lookupPSBByEncoding(psbhintop);
1459  if (PSB)
1460  O << PSB->Name;
1461  else
1462  O << markup("<imm:") << '#' << formatImm(psbhintop) << markup(">");
1463 }
1464 
1465 void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum,
1466  const MCSubtargetInfo &STI,
1467  raw_ostream &O) {
1468  unsigned btihintop = MI->getOperand(OpNum).getImm() ^ 32;
1469  auto BTI = AArch64BTIHint::lookupBTIByEncoding(btihintop);
1470  if (BTI)
1471  O << BTI->Name;
1472  else
1473  O << markup("<imm:") << '#' << formatImm(btihintop) << markup(">");
1474 }
1475 
1477  const MCSubtargetInfo &STI,
1478  raw_ostream &O) {
1479  const MCOperand &MO = MI->getOperand(OpNum);
1480  float FPImm = MO.isDFPImm() ? bit_cast<double>(MO.getDFPImm())
1482 
1483  // 8 decimal places are enough to perfectly represent permitted floats.
1484  O << markup("<imm:") << format("#%.8f", FPImm) << markup(">");
1485 }
1486 
1487 static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1) {
1488  while (Stride--) {
1489  switch (Reg) {
1490  default:
1491  llvm_unreachable("Vector register expected!");
1492  case AArch64::Q0: Reg = AArch64::Q1; break;
1493  case AArch64::Q1: Reg = AArch64::Q2; break;
1494  case AArch64::Q2: Reg = AArch64::Q3; break;
1495  case AArch64::Q3: Reg = AArch64::Q4; break;
1496  case AArch64::Q4: Reg = AArch64::Q5; break;
1497  case AArch64::Q5: Reg = AArch64::Q6; break;
1498  case AArch64::Q6: Reg = AArch64::Q7; break;
1499  case AArch64::Q7: Reg = AArch64::Q8; break;
1500  case AArch64::Q8: Reg = AArch64::Q9; break;
1501  case AArch64::Q9: Reg = AArch64::Q10; break;
1502  case AArch64::Q10: Reg = AArch64::Q11; break;
1503  case AArch64::Q11: Reg = AArch64::Q12; break;
1504  case AArch64::Q12: Reg = AArch64::Q13; break;
1505  case AArch64::Q13: Reg = AArch64::Q14; break;
1506  case AArch64::Q14: Reg = AArch64::Q15; break;
1507  case AArch64::Q15: Reg = AArch64::Q16; break;
1508  case AArch64::Q16: Reg = AArch64::Q17; break;
1509  case AArch64::Q17: Reg = AArch64::Q18; break;
1510  case AArch64::Q18: Reg = AArch64::Q19; break;
1511  case AArch64::Q19: Reg = AArch64::Q20; break;
1512  case AArch64::Q20: Reg = AArch64::Q21; break;
1513  case AArch64::Q21: Reg = AArch64::Q22; break;
1514  case AArch64::Q22: Reg = AArch64::Q23; break;
1515  case AArch64::Q23: Reg = AArch64::Q24; break;
1516  case AArch64::Q24: Reg = AArch64::Q25; break;
1517  case AArch64::Q25: Reg = AArch64::Q26; break;
1518  case AArch64::Q26: Reg = AArch64::Q27; break;
1519  case AArch64::Q27: Reg = AArch64::Q28; break;
1520  case AArch64::Q28: Reg = AArch64::Q29; break;
1521  case AArch64::Q29: Reg = AArch64::Q30; break;
1522  case AArch64::Q30: Reg = AArch64::Q31; break;
1523  // Vector lists can wrap around.
1524  case AArch64::Q31:
1525  Reg = AArch64::Q0;
1526  break;
1527  case AArch64::Z0: Reg = AArch64::Z1; break;
1528  case AArch64::Z1: Reg = AArch64::Z2; break;
1529  case AArch64::Z2: Reg = AArch64::Z3; break;
1530  case AArch64::Z3: Reg = AArch64::Z4; break;
1531  case AArch64::Z4: Reg = AArch64::Z5; break;
1532  case AArch64::Z5: Reg = AArch64::Z6; break;
1533  case AArch64::Z6: Reg = AArch64::Z7; break;
1534  case AArch64::Z7: Reg = AArch64::Z8; break;
1535  case AArch64::Z8: Reg = AArch64::Z9; break;
1536  case AArch64::Z9: Reg = AArch64::Z10; break;
1537  case AArch64::Z10: Reg = AArch64::Z11; break;
1538  case AArch64::Z11: Reg = AArch64::Z12; break;
1539  case AArch64::Z12: Reg = AArch64::Z13; break;
1540  case AArch64::Z13: Reg = AArch64::Z14; break;
1541  case AArch64::Z14: Reg = AArch64::Z15; break;
1542  case AArch64::Z15: Reg = AArch64::Z16; break;
1543  case AArch64::Z16: Reg = AArch64::Z17; break;
1544  case AArch64::Z17: Reg = AArch64::Z18; break;
1545  case AArch64::Z18: Reg = AArch64::Z19; break;
1546  case AArch64::Z19: Reg = AArch64::Z20; break;
1547  case AArch64::Z20: Reg = AArch64::Z21; break;
1548  case AArch64::Z21: Reg = AArch64::Z22; break;
1549  case AArch64::Z22: Reg = AArch64::Z23; break;
1550  case AArch64::Z23: Reg = AArch64::Z24; break;
1551  case AArch64::Z24: Reg = AArch64::Z25; break;
1552  case AArch64::Z25: Reg = AArch64::Z26; break;
1553  case AArch64::Z26: Reg = AArch64::Z27; break;
1554  case AArch64::Z27: Reg = AArch64::Z28; break;
1555  case AArch64::Z28: Reg = AArch64::Z29; break;
1556  case AArch64::Z29: Reg = AArch64::Z30; break;
1557  case AArch64::Z30: Reg = AArch64::Z31; break;
1558  // Vector lists can wrap around.
1559  case AArch64::Z31:
1560  Reg = AArch64::Z0;
1561  break;
1562  case AArch64::P0: Reg = AArch64::P1; break;
1563  case AArch64::P1: Reg = AArch64::P2; break;
1564  case AArch64::P2: Reg = AArch64::P3; break;
1565  case AArch64::P3: Reg = AArch64::P4; break;
1566  case AArch64::P4: Reg = AArch64::P5; break;
1567  case AArch64::P5: Reg = AArch64::P6; break;
1568  case AArch64::P6: Reg = AArch64::P7; break;
1569  case AArch64::P7: Reg = AArch64::P8; break;
1570  case AArch64::P8: Reg = AArch64::P9; break;
1571  case AArch64::P9: Reg = AArch64::P10; break;
1572  case AArch64::P10: Reg = AArch64::P11; break;
1573  case AArch64::P11: Reg = AArch64::P12; break;
1574  case AArch64::P12: Reg = AArch64::P13; break;
1575  case AArch64::P13: Reg = AArch64::P14; break;
1576  case AArch64::P14: Reg = AArch64::P15; break;
1577  // Vector lists can wrap around.
1578  case AArch64::P15: Reg = AArch64::P0; break;
1579  }
1580  }
1581  return Reg;
1582 }
1583 
1584 template<unsigned size>
1586  unsigned OpNum,
1587  const MCSubtargetInfo &STI,
1588  raw_ostream &O) {
1589  static_assert(size == 64 || size == 32,
1590  "Template parameter must be either 32 or 64");
1591  unsigned Reg = MI->getOperand(OpNum).getReg();
1592 
1593  unsigned Sube = (size == 32) ? AArch64::sube32 : AArch64::sube64;
1594  unsigned Subo = (size == 32) ? AArch64::subo32 : AArch64::subo64;
1595 
1596  unsigned Even = MRI.getSubReg(Reg, Sube);
1597  unsigned Odd = MRI.getSubReg(Reg, Subo);
1598  printRegName(O, Even);
1599  O << ", ";
1600  printRegName(O, Odd);
1601 }
1602 
1604  const MCSubtargetInfo &STI,
1605  raw_ostream &O) {
1606  unsigned MaxRegs = 8;
1607  unsigned RegMask = MI->getOperand(OpNum).getImm();
1608 
1609  unsigned NumRegs = 0;
1610  for (unsigned I = 0; I < MaxRegs; ++I)
1611  if ((RegMask & (1 << I)) != 0)
1612  ++NumRegs;
1613 
1614  O << "{";
1615  unsigned Printed = 0;
1616  for (unsigned I = 0; I < MaxRegs; ++I) {
1617  unsigned Reg = RegMask & (1 << I);
1618  if (Reg == 0)
1619  continue;
1620  printRegName(O, AArch64::ZAD0 + I);
1621  if (Printed + 1 != NumRegs)
1622  O << ", ";
1623  ++Printed;
1624  }
1625  O << "}";
1626 }
1627 
1628 void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum,
1629  const MCSubtargetInfo &STI,
1630  raw_ostream &O,
1631  StringRef LayoutSuffix) {
1632  unsigned Reg = MI->getOperand(OpNum).getReg();
1633 
1634  O << "{ ";
1635 
1636  // Work out how many registers there are in the list (if there is an actual
1637  // list).
1638  unsigned NumRegs = 1;
1639  if (MRI.getRegClass(AArch64::DDRegClassID).contains(Reg) ||
1640  MRI.getRegClass(AArch64::ZPR2RegClassID).contains(Reg) ||
1641  MRI.getRegClass(AArch64::QQRegClassID).contains(Reg) ||
1642  MRI.getRegClass(AArch64::PPR2RegClassID).contains(Reg) ||
1643  MRI.getRegClass(AArch64::ZPR2StridedRegClassID).contains(Reg))
1644  NumRegs = 2;
1645  else if (MRI.getRegClass(AArch64::DDDRegClassID).contains(Reg) ||
1646  MRI.getRegClass(AArch64::ZPR3RegClassID).contains(Reg) ||
1647  MRI.getRegClass(AArch64::QQQRegClassID).contains(Reg))
1648  NumRegs = 3;
1649  else if (MRI.getRegClass(AArch64::DDDDRegClassID).contains(Reg) ||
1650  MRI.getRegClass(AArch64::ZPR4RegClassID).contains(Reg) ||
1651  MRI.getRegClass(AArch64::QQQQRegClassID).contains(Reg) ||
1652  MRI.getRegClass(AArch64::ZPR4StridedRegClassID).contains(Reg))
1653  NumRegs = 4;
1654 
1655  unsigned Stride = 1;
1656  if (MRI.getRegClass(AArch64::ZPR2StridedRegClassID).contains(Reg))
1657  Stride = 8;
1658  else if (MRI.getRegClass(AArch64::ZPR4StridedRegClassID).contains(Reg))
1659  Stride = 4;
1660 
1661  // Now forget about the list and find out what the first register is.
1662  if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::dsub0))
1663  Reg = FirstReg;
1664  else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::qsub0))
1665  Reg = FirstReg;
1666  else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::zsub0))
1667  Reg = FirstReg;
1668  else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::psub0))
1669  Reg = FirstReg;
1670 
1671  // If it's a D-reg, we need to promote it to the equivalent Q-reg before
1672  // printing (otherwise getRegisterName fails).
1673  if (MRI.getRegClass(AArch64::FPR64RegClassID).contains(Reg)) {
1674  const MCRegisterClass &FPR128RC =
1675  MRI.getRegClass(AArch64::FPR128RegClassID);
1676  Reg = MRI.getMatchingSuperReg(Reg, AArch64::dsub, &FPR128RC);
1677  }
1678 
1679  if ((MRI.getRegClass(AArch64::ZPRRegClassID).contains(Reg) ||
1680  MRI.getRegClass(AArch64::PPRRegClassID).contains(Reg)) &&
1681  NumRegs > 1 && Stride == 1 &&
1682  // Do not print the range when the last register is lower than the first.
1683  // Because it is a wrap-around register.
1684  Reg < getNextVectorRegister(Reg, NumRegs - 1)) {
1685  printRegName(O, Reg);
1686  O << LayoutSuffix;
1687  if (NumRegs > 1) {
1688  // Set of two sve registers should be separated by ','
1689  StringRef split_char = NumRegs == 2 ? ", " : " - ";
1690  O << split_char;
1691  printRegName(O, (getNextVectorRegister(Reg, NumRegs - 1)));
1692  O << LayoutSuffix;
1693  }
1694  } else {
1695  for (unsigned i = 0; i < NumRegs;
1696  ++i, Reg = getNextVectorRegister(Reg, Stride)) {
1697  // wrap-around sve register
1698  if (MRI.getRegClass(AArch64::ZPRRegClassID).contains(Reg) ||
1699  MRI.getRegClass(AArch64::PPRRegClassID).contains(Reg))
1700  printRegName(O, Reg);
1701  else
1702  printRegName(O, Reg, AArch64::vreg);
1703  O << LayoutSuffix;
1704  if (i + 1 != NumRegs)
1705  O << ", ";
1706  }
1707  }
1708  O << " }";
1709 }
1710 
1711 void
1713  unsigned OpNum,
1714  const MCSubtargetInfo &STI,
1715  raw_ostream &O) {
1716  printVectorList(MI, OpNum, STI, O, "");
1717 }
1718 
1719 template <unsigned NumLanes, char LaneKind>
1721  const MCSubtargetInfo &STI,
1722  raw_ostream &O) {
1723  std::string Suffix(".");
1724  if (NumLanes)
1725  Suffix += itostr(NumLanes) + LaneKind;
1726  else
1727  Suffix += LaneKind;
1728 
1729  printVectorList(MI, OpNum, STI, O, Suffix);
1730 }
1731 
1732 template <unsigned Scale>
1733 void AArch64InstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
1734  const MCSubtargetInfo &STI,
1735  raw_ostream &O) {
1736  O << "[" << Scale * MI->getOperand(OpNum).getImm() << "]";
1737 }
1738 
1739 void AArch64InstPrinter::printMatrixIndex(const MCInst *MI, unsigned OpNum,
1740  const MCSubtargetInfo &STI,
1741  raw_ostream &O) {
1742  O << MI->getOperand(OpNum).getImm();
1743 }
1744 
1746  unsigned OpNum,
1747  const MCSubtargetInfo &STI,
1748  raw_ostream &O) {
1749  const MCOperand &Op = MI->getOperand(OpNum);
1750 
1751  // If the label has already been resolved to an immediate offset (say, when
1752  // we're running the disassembler), just print the immediate.
1753  if (Op.isImm()) {
1754  O << markup("<imm:");
1755  int64_t Offset = Op.getImm() * 4;
1757  O << formatHex(Address + Offset);
1758  else
1759  O << "#" << formatImm(Offset);
1760  O << markup(">");
1761  return;
1762  }
1763 
1764  // If the branch target is simply an address then print it in hex.
1765  const MCConstantExpr *BranchTarget =
1766  dyn_cast<MCConstantExpr>(MI->getOperand(OpNum).getExpr());
1767  int64_t TargetAddress;
1768  if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) {
1769  O << formatHex((uint64_t)TargetAddress);
1770  } else {
1771  // Otherwise, just print the expression.
1772  MI->getOperand(OpNum).getExpr()->print(O, &MAI);
1773  }
1774 }
1775 
1777  unsigned OpNum,
1778  const MCSubtargetInfo &STI,
1779  raw_ostream &O) {
1780  const MCOperand &Op = MI->getOperand(OpNum);
1781 
1782  // If the label has already been resolved to an immediate offset (say, when
1783  // we're running the disassembler), just print the immediate.
1784  if (Op.isImm()) {
1785  const int64_t Offset = Op.getImm() * 4096;
1786  O << markup("<imm:");
1788  O << formatHex((Address & -4096) + Offset);
1789  else
1790  O << "#" << Offset;
1791  O << markup(">");
1792  return;
1793  }
1794 
1795  // Otherwise, just print the expression.
1796  MI->getOperand(OpNum).getExpr()->print(O, &MAI);
1797 }
1798 
1800  const MCSubtargetInfo &STI,
1801  raw_ostream &O) {
1802  unsigned Val = MI->getOperand(OpNo).getImm();
1803  unsigned Opcode = MI->getOpcode();
1804 
1805  StringRef Name;
1806  if (Opcode == AArch64::ISB) {
1807  auto ISB = AArch64ISB::lookupISBByEncoding(Val);
1808  Name = ISB ? ISB->Name : "";
1809  } else if (Opcode == AArch64::TSB) {
1810  auto TSB = AArch64TSB::lookupTSBByEncoding(Val);
1811  Name = TSB ? TSB->Name : "";
1812  } else {
1813  auto DB = AArch64DB::lookupDBByEncoding(Val);
1814  Name = DB ? DB->Name : "";
1815  }
1816  if (!Name.empty())
1817  O << Name;
1818  else
1819  O << markup("<imm:") << "#" << Val << markup(">");
1820 }
1821 
1823  const MCSubtargetInfo &STI,
1824  raw_ostream &O) {
1825  unsigned Val = MI->getOperand(OpNo).getImm();
1826  assert(MI->getOpcode() == AArch64::DSBnXS);
1827 
1828  StringRef Name;
1829  auto DB = AArch64DBnXS::lookupDBnXSByEncoding(Val);
1830  Name = DB ? DB->Name : "";
1831 
1832  if (!Name.empty())
1833  O << Name;
1834  else
1835  O << markup("<imm:") << "#" << Val << markup(">");
1836 }
1837 
1838 static bool isValidSysReg(const AArch64SysReg::SysReg *Reg, bool Read,
1839  const MCSubtargetInfo &STI) {
1840  return (Reg && (Read ? Reg->Readable : Reg->Writeable) &&
1841  Reg->haveFeatures(STI.getFeatureBits()));
1842 }
1843 
1844 // Looks up a system register either by encoding or by name. Some system
1845 // registers share the same encoding between different architectures,
1846 // therefore a tablegen lookup by encoding will return an entry regardless
1847 // of the register's predication on a specific subtarget feature. To work
1848 // around this problem we keep an alternative name for such registers and
1849 // look them up by that name if the first lookup was unsuccessful.
1850 static const AArch64SysReg::SysReg *lookupSysReg(unsigned Val, bool Read,
1851  const MCSubtargetInfo &STI) {
1853 
1854  if (Reg && !isValidSysReg(Reg, Read, STI))
1856 
1857  return Reg;
1858 }
1859 
1861  const MCSubtargetInfo &STI,
1862  raw_ostream &O) {
1863  unsigned Val = MI->getOperand(OpNo).getImm();
1864 
1865  // Horrible hack for the one register that has identical encodings but
1866  // different names in MSR and MRS. Because of this, one of MRS and MSR is
1867  // going to get the wrong entry
1868  if (Val == AArch64SysReg::DBGDTRRX_EL0) {
1869  O << "DBGDTRRX_EL0";
1870  return;
1871  }
1872 
1873  // Horrible hack for two different registers having the same encoding.
1874  if (Val == AArch64SysReg::TRCEXTINSELR) {
1875  O << "TRCEXTINSELR";
1876  return;
1877  }
1878 
1879  const AArch64SysReg::SysReg *Reg = lookupSysReg(Val, true /*Read*/, STI);
1880 
1881  if (isValidSysReg(Reg, true /*Read*/, STI))
1882  O << Reg->Name;
1883  else
1885 }
1886 
1888  const MCSubtargetInfo &STI,
1889  raw_ostream &O) {
1890  unsigned Val = MI->getOperand(OpNo).getImm();
1891 
1892  // Horrible hack for the one register that has identical encodings but
1893  // different names in MSR and MRS. Because of this, one of MRS and MSR is
1894  // going to get the wrong entry
1895  if (Val == AArch64SysReg::DBGDTRTX_EL0) {
1896  O << "DBGDTRTX_EL0";
1897  return;
1898  }
1899 
1900  // Horrible hack for two different registers having the same encoding.
1901  if (Val == AArch64SysReg::TRCEXTINSELR) {
1902  O << "TRCEXTINSELR";
1903  return;
1904  }
1905 
1906  const AArch64SysReg::SysReg *Reg = lookupSysReg(Val, false /*Read*/, STI);
1907 
1908  if (isValidSysReg(Reg, false /*Read*/, STI))
1909  O << Reg->Name;
1910  else
1912 }
1913 
1915  const MCSubtargetInfo &STI,
1916  raw_ostream &O) {
1917  unsigned Val = MI->getOperand(OpNo).getImm();
1918 
1919  auto PStateImm15 = AArch64PState::lookupPStateImm0_15ByEncoding(Val);
1920  auto PStateImm1 = AArch64PState::lookupPStateImm0_1ByEncoding(Val);
1921  if (PStateImm15 && PStateImm15->haveFeatures(STI.getFeatureBits()))
1922  O << PStateImm15->Name;
1923  else if (PStateImm1 && PStateImm1->haveFeatures(STI.getFeatureBits()))
1924  O << PStateImm1->Name;
1925  else
1926  O << "#" << formatImm(Val);
1927 }
1928 
1930  const MCSubtargetInfo &STI,
1931  raw_ostream &O) {
1932  unsigned RawVal = MI->getOperand(OpNo).getImm();
1934  O << markup("<imm:") << format("#%#016llx", Val) << markup(">");
1935 }
1936 
1937 template<int64_t Angle, int64_t Remainder>
1939  const MCSubtargetInfo &STI,
1940  raw_ostream &O) {
1941  unsigned Val = MI->getOperand(OpNo).getImm();
1942  O << markup("<imm:") << "#" << (Val * Angle) + Remainder << markup(">");
1943 }
1944 
1945 void AArch64InstPrinter::printSVEPattern(const MCInst *MI, unsigned OpNum,
1946  const MCSubtargetInfo &STI,
1947  raw_ostream &O) {
1948  unsigned Val = MI->getOperand(OpNum).getImm();
1949  if (auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByEncoding(Val))
1950  O << Pat->Name;
1951  else
1952  O << markup("<imm:") << '#' << formatImm(Val) << markup(">");
1953 }
1954 
1956  unsigned OpNum,
1957  const MCSubtargetInfo &STI,
1958  raw_ostream &O) {
1959  unsigned Val = MI->getOperand(OpNum).getImm();
1960  // Pattern has only 1 bit
1961  if (Val > 1)
1962  llvm_unreachable("Invalid vector length specifier");
1963  if (auto Pat =
1964  AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByEncoding(Val))
1965  O << Pat->Name;
1966  else
1967  llvm_unreachable("Invalid vector length specifier");
1968 }
1969 
1970 template <char suffix>
1971 void AArch64InstPrinter::printSVERegOp(const MCInst *MI, unsigned OpNum,
1972  const MCSubtargetInfo &STI,
1973  raw_ostream &O) {
1974  switch (suffix) {
1975  case 0:
1976  case 'b':
1977  case 'h':
1978  case 's':
1979  case 'd':
1980  case 'q':
1981  break;
1982  default: llvm_unreachable("Invalid kind specifier.");
1983  }
1984 
1985  unsigned Reg = MI->getOperand(OpNum).getReg();
1986  printRegName(O, Reg);
1987  if (suffix != 0)
1988  O << '.' << suffix;
1989 }
1990 
1991 template <typename T>
1993  std::make_unsigned_t<T> HexValue = Value;
1994 
1995  if (getPrintImmHex())
1996  O << markup("<imm:") << '#' << formatHex((uint64_t)HexValue) << markup(">");
1997  else
1998  O << markup("<imm:") << '#' << formatDec(Value) << markup(">");
1999 
2000  if (CommentStream) {
2001  // Do the opposite to that used for instruction operands.
2002  if (getPrintImmHex())
2003  *CommentStream << '=' << formatDec(HexValue) << '\n';
2004  else
2005  *CommentStream << '=' << formatHex((uint64_t)Value) << '\n';
2006  }
2007 }
2008 
2009 template <typename T>
2010 void AArch64InstPrinter::printImm8OptLsl(const MCInst *MI, unsigned OpNum,
2011  const MCSubtargetInfo &STI,
2012  raw_ostream &O) {
2013  unsigned UnscaledVal = MI->getOperand(OpNum).getImm();
2014  unsigned Shift = MI->getOperand(OpNum + 1).getImm();
2016  "Unexepected shift type!");
2017 
2018  // #0 lsl #8 is never pretty printed
2019  if ((UnscaledVal == 0) && (AArch64_AM::getShiftValue(Shift) != 0)) {
2020  O << markup("<imm:") << '#' << formatImm(UnscaledVal) << markup(">");
2021  printShifter(MI, OpNum + 1, STI, O);
2022  return;
2023  }
2024 
2025  T Val;
2026  if (std::is_signed<T>())
2027  Val = (int8_t)UnscaledVal * (1 << AArch64_AM::getShiftValue(Shift));
2028  else
2029  Val = (uint8_t)UnscaledVal * (1 << AArch64_AM::getShiftValue(Shift));
2030 
2031  printImmSVE(Val, O);
2032 }
2033 
2034 template <typename T>
2036  const MCSubtargetInfo &STI,
2037  raw_ostream &O) {
2038  typedef std::make_signed_t<T> SignedT;
2039  typedef std::make_unsigned_t<T> UnsignedT;
2040 
2041  uint64_t Val = MI->getOperand(OpNum).getImm();
2042  UnsignedT PrintVal = AArch64_AM::decodeLogicalImmediate(Val, 64);
2043 
2044  // Prefer the default format for 16bit values, hex otherwise.
2045  if ((int16_t)PrintVal == (SignedT)PrintVal)
2046  printImmSVE((T)PrintVal, O);
2047  else if ((uint16_t)PrintVal == PrintVal)
2048  printImmSVE(PrintVal, O);
2049  else
2050  O << markup("<imm:") << '#' << formatHex((uint64_t)PrintVal) << markup(">");
2051 }
2052 
2053 template <int Width>
2054 void AArch64InstPrinter::printZPRasFPR(const MCInst *MI, unsigned OpNum,
2055  const MCSubtargetInfo &STI,
2056  raw_ostream &O) {
2057  unsigned Base;
2058  switch (Width) {
2059  case 8: Base = AArch64::B0; break;
2060  case 16: Base = AArch64::H0; break;
2061  case 32: Base = AArch64::S0; break;
2062  case 64: Base = AArch64::D0; break;
2063  case 128: Base = AArch64::Q0; break;
2064  default:
2065  llvm_unreachable("Unsupported width");
2066  }
2067  unsigned Reg = MI->getOperand(OpNum).getReg();
2068  printRegName(O, Reg - AArch64::Z0 + Base);
2069 }
2070 
2071 template <unsigned ImmIs0, unsigned ImmIs1>
2072 void AArch64InstPrinter::printExactFPImm(const MCInst *MI, unsigned OpNum,
2073  const MCSubtargetInfo &STI,
2074  raw_ostream &O) {
2075  auto *Imm0Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs0);
2076  auto *Imm1Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs1);
2077  unsigned Val = MI->getOperand(OpNum).getImm();
2078  O << markup("<imm:") << "#" << (Val ? Imm1Desc->Repr : Imm0Desc->Repr)
2079  << markup(">");
2080 }
2081 
2082 void AArch64InstPrinter::printGPR64as32(const MCInst *MI, unsigned OpNum,
2083  const MCSubtargetInfo &STI,
2084  raw_ostream &O) {
2085  unsigned Reg = MI->getOperand(OpNum).getReg();
2087 }
2088 
2089 void AArch64InstPrinter::printGPR64x8(const MCInst *MI, unsigned OpNum,
2090  const MCSubtargetInfo &STI,
2091  raw_ostream &O) {
2092  unsigned Reg = MI->getOperand(OpNum).getReg();
2093  printRegName(O, MRI.getSubReg(Reg, AArch64::x8sub_0));
2094 }
2095 
2096 void AArch64InstPrinter::printSyspXzrPair(const MCInst *MI, unsigned OpNum,
2097  const MCSubtargetInfo &STI,
2098  raw_ostream &O) {
2099  unsigned Reg = MI->getOperand(OpNum).getReg();
2100  assert(Reg == AArch64::XZR &&
2101  "MC representation of SyspXzrPair should be XZR");
2102  O << getRegisterName(Reg) << ", " << getRegisterName(Reg);
2103 }
isValidSysReg
static bool isValidSysReg(const AArch64SysReg::SysReg *Reg, bool Read, const MCSubtargetInfo &STI)
Definition: AArch64InstPrinter.cpp:1838
i
i
Definition: README.txt:29
llvm::AArch64InstPrinter::printMRSSystemRegister
void printMRSSystemRegister(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1860
llvm::AArch64InstPrinter::printSysCROperand
void printSysCROperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1185
llvm::AArch64InstPrinter::printAlignedLabel
void printAlignedLabel(const MCInst *MI, uint64_t Address, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1745
llvm::MCInstPrinter::formatDec
format_object< int64_t > formatDec(int64_t Value) const
Utility functions to print decimal/hexadecimal values.
Definition: MCInstPrinter.cpp:194
llvm::AArch64InstPrinter::printSImm
void printSImm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1149
LdStNInstrDesc::Mnemonic
const char * Mnemonic
Definition: AArch64InstPrinter.cpp:404
llvm::AArch64_AM::getArithShiftValue
static unsigned getArithShiftValue(unsigned Imm)
getArithShiftValue - get the arithmetic shift value.
Definition: AArch64AddressingModes.h:119
llvm::AArch64InstPrinter::printMatrix
void printMatrix(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1056
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
MathExtras.h
llvm::AArch64InstPrinter::printSystemPStateField
void printSystemPStateField(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1914
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MCAsmInfo::getCommentString
StringRef getCommentString() const
Definition: MCAsmInfo.h:655
llvm::AArch64InstPrinter::printZPRasFPR
void printZPRasFPR(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:2054
llvm::AArch64_AM::getFPImmFloat
static float getFPImmFloat(unsigned Imm)
Definition: AArch64AddressingModes.h:344
llvm::AArch64InstPrinter::printImplicitlyTypedVectorList
void printImplicitlyTypedVectorList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Print a list of vector registers where the type suffix is implicit (i.e.
Definition: AArch64InstPrinter.cpp:1712
llvm::AArch64_AM::LSL
@ LSL
Definition: AArch64AddressingModes.h:35
llvm::AArch64InstPrinter::printSIMDType10Operand
void printSIMDType10Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1929
llvm::AArch64InstPrinter::printSVEPattern
void printSVEPattern(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1945
llvm::MCOperand::isReg
bool isReg() const
Definition: MCInst.h:61
lookupSysReg
static const AArch64SysReg::SysReg * lookupSysReg(unsigned Val, bool Read, const MCSubtargetInfo &STI)
Definition: AArch64InstPrinter.cpp:1850
T
llvm::MCInstPrinter::PrintAliases
bool PrintAliases
True if we prefer aliases (e.g. nop) to raw mnemonics.
Definition: MCInstPrinter.h:59
llvm::AArch64InstPrinter::getRegName
virtual StringRef getRegName(MCRegister Reg) const
Definition: AArch64InstPrinter.cpp:71
StringRef.h
llvm::MCRegisterInfo::getMatchingSuperReg
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
Definition: MCRegisterInfo.cpp:24
llvm::AArch64InstPrinter::printRPRFMOperand
void printRPRFMOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1421
llvm::AArch64SysReg::lookupSysRegByName
const SysReg * lookupSysRegByName(StringRef)
llvm::MCAsmInfo
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
llvm::AArch64AppleInstPrinter::getRegisterName
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
llvm::AArch64TLBI::TLBI
Definition: AArch64BaseInfo.h:712
ErrorHandling.h
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::AArch64AppleInstPrinter::printInst
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
Definition: AArch64InstPrinter.cpp:762
llvm::AArch64_AM::isMOVZMovAlias
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
Definition: AArch64AddressingModes.h:818
llvm::AArch64InstPrinter::printArithExtend
void printArithExtend(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1252
AArch64BaseInfo.h
llvm::AArch64InstPrinter::printRangePrefetchAlias
bool printRangePrefetchAlias(const MCInst *MI, const MCSubtargetInfo &STI, raw_ostream &O, StringRef Annot)
Definition: AArch64InstPrinter.cpp:825
LdStNInstrDesc::HasLane
bool HasLane
Definition: AArch64InstPrinter.cpp:407
Shift
bool Shift
Definition: README.txt:468
llvm::AArch64InstPrinter::printMatrixTileList
void printMatrixTileList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1603
llvm::MCRegisterClass::contains
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
Definition: MCRegisterInfo.h:68
llvm::AArch64SysReg::SysReg
Definition: AArch64BaseInfo.h:687
STLExtras.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Format.h
llvm::MCInstPrinter::PrintBranchImmAsAddress
bool PrintBranchImmAsAddress
If true, a branch immediate (e.g.
Definition: MCInstPrinter.h:70
llvm::MCRegisterInfo::getSubReg
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Definition: MCRegisterInfo.cpp:32
llvm::AArch64InstPrinter::printPrefetchOp
void printPrefetchOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1434
llvm::AArch64InstPrinter::printAddSubImm
void printAddSubImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1193
llvm::AArch64InstPrinter::printImm8OptLsl
void printImm8OptLsl(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:2010
llvm::MCRegisterClass
MCRegisterClass - Base class of TargetRegisterClass.
Definition: MCRegisterInfo.h:31
llvm::AArch64InstPrinter::printShifter
void printShifter(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1225
llvm::AArch64PACKey::DB
@ DB
Definition: AArch64BaseInfo.h:828
LdStNInstrDesc::Opcode
unsigned Opcode
Definition: AArch64InstPrinter.cpp:403
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::MCInstPrinter::MRI
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:52
llvm::MCRegisterInfo::getRegClass
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Definition: MCRegisterInfo.h:543
llvm::AArch64InstPrinter::printGPR64as32
void printGPR64as32(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:2082
P2
This might compile to this xmm1 xorps xmm0 movss xmm0 ret Now consider if the code caused xmm1 to get spilled This might produce this xmm1 movaps xmm0 movaps xmm1 movss xmm0 ret since the reload is only used by these we could fold it into the producing something like xmm1 movaps xmm0 ret saving two instructions The basic idea is that a reload from a spill if only one byte chunk is bring in zeros the one element instead of elements This can be used to simplify a variety of shuffle where the elements are fixed zeros This code generates ugly probably due to costs being off or< 4 x float > * P2
Definition: README-SSE.txt:278
llvm::MCSubtargetInfo::hasFeature
bool hasFeature(unsigned Feature) const
Definition: MCSubtargetInfo.h:119
llvm::AArch64_AM::isMOVNMovAlias
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
Definition: AArch64AddressingModes.h:829
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
llvm::AArch64InstPrinter::printBarriernXSOption
void printBarriernXSOption(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1822
llvm::AArch64InstPrinter::printMemExtend
void printMemExtend(const MCInst *MI, unsigned OpNum, raw_ostream &O, char SrcRegKind, unsigned Width)
Definition: AArch64InstPrinter.cpp:1299
MCInst.h
llvm::AArch64InstPrinter::printAliasInstr
virtual bool printAliasInstr(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
llvm::Log2_32
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:373
llvm::AArch64InstPrinter::printCondCode
void printCondCode(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1354
MCSubtargetInfo.h
llvm::AArch64InstPrinter::printUImm12Offset
void printUImm12Offset(const MCInst *MI, unsigned OpNum, unsigned Scale, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1393
llvm::AArch64InstPrinter::printMatrixTileVector
void printMatrixTileVector(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1087
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:112
printMemExtendImpl
static void printMemExtendImpl(bool SignExtend, bool DoShift, unsigned Width, char SrcRegKind, raw_ostream &O, bool UseMarkup)
Definition: AArch64InstPrinter.cpp:1279
llvm::AArch64DC::DC
Definition: AArch64BaseInfo.h:437
llvm::AArch64IC::IC
Definition: AArch64BaseInfo.h:445
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::MCInstPrinter::UseMarkup
bool UseMarkup
True if we are printing marked up assembly.
Definition: MCInstPrinter.h:56
llvm::AArch64InstPrinter::printFPImmOperand
void printFPImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1476
llvm::MCInstPrinter::CommentStream
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
Definition: MCInstPrinter.h:49
llvm::MCOI::BranchTarget
@ BranchTarget
Definition: MCInstrDesc.h:54
llvm::AArch64InstPrinter::printMatrixTile
void printMatrixTile(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1100
llvm::AArch64_AM::getShiftValue
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
Definition: AArch64AddressingModes.h:86
llvm::AArch64CC::getCondCodeName
static const char * getCondCodeName(CondCode Code)
Definition: AArch64BaseInfo.h:281
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::AArch64AppleInstPrinter::getRegName
StringRef getRegName(MCRegister Reg) const override
Definition: AArch64InstPrinter.cpp:821
llvm::MCInstPrinter::printAnnotation
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
Definition: MCInstPrinter.cpp:50
llvm::AArch64InstPrinter::printExtendedRegister
void printExtendedRegister(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1245
llvm::AArch64InstPrinter::AArch64InstPrinter
AArch64InstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
Definition: AArch64InstPrinter.cpp:44
llvm::AArch64_AM::getArithExtendType
static AArch64_AM::ShiftExtendType getArithExtendType(unsigned Imm)
Definition: AArch64AddressingModes.h:139
llvm::Pass::print
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:130
llvm::MCConstantExpr
Definition: MCExpr.h:144
AArch64AddressingModes.h
llvm::AArch64InstPrinter::printComplexRotationOp
void printComplexRotationOp(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1938
llvm::AArch64InstPrinter::printSVELogicalImm
void printSVELogicalImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:2035
llvm::AArch64_AM::decodeLogicalImmediate
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
Definition: AArch64AddressingModes.h:294
llvm::AArch64InstPrinter::printAMNoIndex
void printAMNoIndex(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1368
llvm::AArch64InstPrinter::printBarrierOption
void printBarrierOption(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1799
llvm::AArch64_AM::getShiftExtendName
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
Definition: AArch64AddressingModes.h:53
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:274
LdStNInstrDesc::NaturalOffset
int NaturalOffset
Definition: AArch64InstPrinter.cpp:408
llvm::AArch64InstPrinter::printPSBHintOp
void printPSBHintOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1454
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::AArch64InstPrinter::printAMIndexedWB
void printAMIndexedWB(const MCInst *MI, unsigned OpNum, unsigned Scale, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1405
llvm::AArch64InstPrinter::printTypedVectorList
void printTypedVectorList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1720
llvm::AArch64AT::AT
Definition: AArch64BaseInfo.h:413
llvm::AArch64InstPrinter::printOperand
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1119
uint64_t
llvm::AArch64InstPrinter::printPredicateAsCounter
void printPredicateAsCounter(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1326
LdStNInstrDesc::ListOperand
int ListOperand
Definition: AArch64InstPrinter.cpp:406
llvm::MCInstPrinter
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:44
llvm::AArch64InstPrinter::printVectorList
void printVectorList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O, StringRef LayoutSuffix)
Definition: AArch64InstPrinter.cpp:1628
llvm::AArch64InstPrinter::printImmRangeScale
void printImmRangeScale(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1385
llvm::AArch64AppleInstPrinter::AArch64AppleInstPrinter
AArch64AppleInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
Definition: AArch64InstPrinter.cpp:49
getNextVectorRegister
static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride=1)
Definition: AArch64InstPrinter.cpp:1487
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::SysAlias::Name
const char * Name
Definition: AArch64BaseInfo.h:372
StringExtras.h
llvm::MCInstPrinter::getPrintImmHex
bool getPrintImmHex() const
Definition: MCInstPrinter.h:122
llvm::AArch64InstPrinter::printSysAlias
bool printSysAlias(const MCInst *MI, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:875
llvm::MCInstPrinter::formatHex
format_object< int64_t > formatHex(int64_t Value) const
Definition: MCInstPrinter.cpp:198
MCRegisterInfo.h
llvm::AArch64InstPrinter::printAdrpLabel
void printAdrpLabel(const MCInst *MI, uint64_t Address, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1776
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AArch64InstPrinter::printRegWithShiftExtend
void printRegWithShiftExtend(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1308
llvm::AArch64InstPrinter::printImmSVE
void printImmSVE(T Value, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1992
llvm::AArch64InstPrinter::printSVERegOp
void printSVERegOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1971
llvm::AArch64InstPrinter::printPostIncOperand
void printPostIncOperand(const MCInst *MI, unsigned OpNo, unsigned Imm, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1163
llvm::AArch64InstPrinter::printImm
void printImm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1134
llvm::MCInstPrinter::formatImm
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Definition: MCInstPrinter.h:135
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1716
llvm::AArch64InstPrinter::printLogicalImm
void printLogicalImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1216
llvm::AArch64InstPrinter::printMatrixIndex
void printMatrixIndex(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1739
llvm::AArch64InstPrinter::printShiftedRegister
void printShiftedRegister(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1238
MCAsmInfo.h
llvm::atomicBarrierDroppedOnZero
static bool atomicBarrierDroppedOnZero(unsigned Opcode)
Definition: AArch64BaseInfo.h:207
AArch64InstPrinter.h
llvm::AArch64InstPrinter
Definition: AArch64InstPrinter.h:23
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::Offset
@ Offset
Definition: DWP.cpp:406
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
LdStNInstrDesc::Layout
const char * Layout
Definition: AArch64InstPrinter.cpp:405
CC
auto CC
Definition: RISCVRedundantCopyElimination.cpp:79
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::AArch64InstPrinter::printVRegOperand
void printVRegOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1176
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
llvm::AArch64InstPrinter::printSVCROp
void printSVCROp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1108
llvm::SignExtend64
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition: MathExtras.h:543
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::AArch64InstPrinter::printInverseCondCode
void printInverseCondCode(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1361
llvm::AArch64_AM::ShiftExtendType
ShiftExtendType
Definition: AArch64AddressingModes.h:33
llvm::AArch64_AM::UXTX
@ UXTX
Definition: AArch64AddressingModes.h:44
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
llvm::AArch64SysReg::lookupSysRegByEncoding
const SysReg * lookupSysRegByEncoding(uint16_t)
llvm::AArch64InstPrinter::printMSRSystemRegister
void printMSRSystemRegister(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1887
uint16_t
llvm::SysAliasReg::NeedsReg
bool NeedsReg
Definition: AArch64BaseInfo.h:389
isTblTbxInstruction
static bool isTblTbxInstruction(unsigned Opcode, StringRef &Layout, bool &IsTbx)
Definition: AArch64InstPrinter.cpp:366
llvm::AArch64_AM::isAnyMOVWMovAlias
static bool isAnyMOVWMovAlias(uint64_t Value, int RegWidth)
Definition: AArch64AddressingModes.h:841
llvm::AArch64SysReg::genericRegisterString
std::string genericRegisterString(uint32_t Bits)
Definition: AArch64BaseInfo.cpp:170
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:354
llvm::AArch64InstPrinter::printExactFPImm
void printExactFPImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:2072
llvm::AArch64_AM::decodeAdvSIMDModImmType10
static uint64_t decodeAdvSIMDModImmType10(uint8_t Imm)
Definition: AArch64AddressingModes.h:642
Casting.h
llvm::BitWidth
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:147
llvm::MCOperand::getExpr
const MCExpr * getExpr() const
Definition: MCInst.h:114
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
transform
instcombine should handle this transform
Definition: README.txt:262
llvm::AArch64CC::getInvertedCondCode
static CondCode getInvertedCondCode(CondCode Code)
Definition: AArch64BaseInfo.h:303
llvm::AArch64InstPrinter::printImmScale
void printImmScale(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1377
llvm::AArch64_AM::getShiftType
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
Definition: AArch64AddressingModes.h:74
llvm::AArch64InstPrinter::printSVEVecLenSpecifier
void printSVEVecLenSpecifier(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1955
llvm::AArch64_AM::UXTW
@ UXTW
Definition: AArch64AddressingModes.h:43
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
LdStNInstrDesc
Definition: AArch64InstPrinter.cpp:402
llvm::AMDGPU::Hwreg::Width
Width
Definition: SIDefines.h:439
llvm::AArch64InstPrinter::getRegisterName
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::MCInstPrinter::markup
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
Definition: MCInstPrinter.cpp:174
llvm::AArch64InstPrinter::printInst
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
Definition: AArch64InstPrinter.cpp:75
llvm::AArch64InstPrinter::printInstruction
virtual void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
llvm::MCInstPrinter::MAI
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:50
llvm::MCExpr::print
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
llvm::MCOperand::getDFPImm
uint64_t getDFPImm() const
Definition: MCInst.h:100
llvm::getWRegFromXReg
static unsigned getWRegFromXReg(unsigned Reg)
Definition: AArch64BaseInfo.h:29
llvm::AArch64InstPrinter::printSyspAlias
bool printSyspAlias(const MCInst *MI, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:995
LdStNInstInfo
static const LdStNInstrDesc LdStNInstInfo[]
Definition: AArch64InstPrinter.cpp:411
llvm::AArch64InstPrinter::printVectorIndex
void printVectorIndex(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1733
llvm::AArch64InstPrinter::printSyspXzrPair
void printSyspXzrPair(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:2096
getLdStNInstrDesc
static const LdStNInstrDesc * getLdStNInstrDesc(unsigned Opcode)
Definition: AArch64InstPrinter.cpp:754
shift
http eax xorl edx cl sete al setne dl sall eax sall edx But that requires good bit subreg support this might be better It s an extra shift
Definition: README.txt:30
llvm::AArch64InstPrinter::applyTargetSpecificCLOption
bool applyTargetSpecificCLOption(StringRef Opt) override
Customize the printer according to a command line option.
Definition: AArch64InstPrinter.cpp:54
llvm::AArch64InstPrinter::printRegName
void printRegName(raw_ostream &OS, MCRegister Reg) const override
Print the assembler register name.
Definition: AArch64InstPrinter.cpp:62
llvm::SysAlias::haveFeatures
bool haveFeatures(FeatureBitset ActiveFeatures) const
Definition: AArch64BaseInfo.h:380
llvm::MipsISD::Ins
@ Ins
Definition: MipsISelLowering.h:160
RegName
#define RegName(no)
llvm::AArch64CC::CondCode
CondCode
Definition: AArch64BaseInfo.h:254
llvm::AArch64InstPrinter::printGPRSeqPairsClassOperand
void printGPRSeqPairsClassOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1585
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::AArch64InstPrinter::printBTIHintOp
void printBTIHintOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1465
raw_ostream.h
llvm::AArch64InstPrinter::printGPR64x8
void printGPR64x8(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:2089
llvm::AArch64InstPrinter::printImmHex
void printImmHex(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
Definition: AArch64InstPrinter.cpp:1141
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::MCOperand::isDFPImm
bool isDFPImm() const
Definition: MCInst.h:64
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
llvm::MCOperand::getReg
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69