1 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
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 #include "AArch64InstrInfo.h"
10 #include "MCTargetDesc/AArch64AddressingModes.h"
11 #include "MCTargetDesc/AArch64InstPrinter.h"
12 #include "MCTargetDesc/AArch64MCExpr.h"
13 #include "MCTargetDesc/AArch64MCTargetDesc.h"
14 #include "MCTargetDesc/AArch64TargetStreamer.h"
15 #include "TargetInfo/AArch64TargetInfo.h"
16 #include "Utils/AArch64BaseInfo.h"
17 #include "llvm/ADT/APFloat.h"
18 #include "llvm/ADT/APInt.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/SmallSet.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/StringMap.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/ADT/StringSwitch.h"
27 #include "llvm/ADT/Twine.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCExpr.h"
30 #include "llvm/MC/MCInst.h"
31 #include "llvm/MC/MCLinkerOptimizationHint.h"
32 #include "llvm/MC/MCObjectFileInfo.h"
33 #include "llvm/MC/MCParser/MCAsmLexer.h"
34 #include "llvm/MC/MCParser/MCAsmParser.h"
35 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
36 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
37 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
38 #include "llvm/MC/MCRegisterInfo.h"
39 #include "llvm/MC/MCStreamer.h"
40 #include "llvm/MC/MCSubtargetInfo.h"
41 #include "llvm/MC/MCSymbol.h"
42 #include "llvm/MC/MCTargetOptions.h"
43 #include "llvm/MC/MCValue.h"
44 #include "llvm/MC/SubtargetFeature.h"
45 #include "llvm/MC/TargetRegistry.h"
46 #include "llvm/Support/Casting.h"
47 #include "llvm/Support/Compiler.h"
48 #include "llvm/Support/ErrorHandling.h"
49 #include "llvm/Support/MathExtras.h"
50 #include "llvm/Support/SMLoc.h"
51 #include "llvm/Support/TargetParser.h"
52 #include "llvm/Support/raw_ostream.h"
53 #include <cassert>
54 #include <cctype>
55 #include <cstdint>
56 #include <cstdio>
57 #include <string>
58 #include <tuple>
59 #include <utility>
60 #include <vector>
61 
62 using namespace llvm;
63 
64 namespace {
65 
66 enum class RegKind {
67   Scalar,
68   NeonVector,
69   SVEDataVector,
70   SVEPredicateVector,
71   Matrix
72 };
73 
74 enum class MatrixKind { Array, Tile, Row, Col };
75 
76 enum RegConstraintEqualityTy {
77   EqualsReg,
78   EqualsSuperReg,
79   EqualsSubReg
80 };
81 
82 class AArch64AsmParser : public MCTargetAsmParser {
83 private:
84   StringRef Mnemonic; ///< Instruction mnemonic.
85 
86   // Map of register aliases registers via the .req directive.
87   StringMap<std::pair<RegKind, unsigned>> RegisterReqs;
88 
89   class PrefixInfo {
90   public:
91     static PrefixInfo CreateFromInst(const MCInst &Inst, uint64_t TSFlags) {
92       PrefixInfo Prefix;
93       switch (Inst.getOpcode()) {
94       case AArch64::MOVPRFX_ZZ:
95         Prefix.Active = true;
96         Prefix.Dst = Inst.getOperand(0).getReg();
97         break;
98       case AArch64::MOVPRFX_ZPmZ_B:
99       case AArch64::MOVPRFX_ZPmZ_H:
100       case AArch64::MOVPRFX_ZPmZ_S:
101       case AArch64::MOVPRFX_ZPmZ_D:
102         Prefix.Active = true;
103         Prefix.Predicated = true;
104         Prefix.ElementSize = TSFlags & AArch64::ElementSizeMask;
105         assert(Prefix.ElementSize != AArch64::ElementSizeNone &&
106                "No destructive element size set for movprfx");
107         Prefix.Dst = Inst.getOperand(0).getReg();
108         Prefix.Pg = Inst.getOperand(2).getReg();
109         break;
110       case AArch64::MOVPRFX_ZPzZ_B:
111       case AArch64::MOVPRFX_ZPzZ_H:
112       case AArch64::MOVPRFX_ZPzZ_S:
113       case AArch64::MOVPRFX_ZPzZ_D:
114         Prefix.Active = true;
115         Prefix.Predicated = true;
116         Prefix.ElementSize = TSFlags & AArch64::ElementSizeMask;
117         assert(Prefix.ElementSize != AArch64::ElementSizeNone &&
118                "No destructive element size set for movprfx");
119         Prefix.Dst = Inst.getOperand(0).getReg();
120         Prefix.Pg = Inst.getOperand(1).getReg();
121         break;
122       default:
123         break;
124       }
125 
126       return Prefix;
127     }
128 
129     PrefixInfo() : Active(false), Predicated(false) {}
130     bool isActive() const { return Active; }
131     bool isPredicated() const { return Predicated; }
132     unsigned getElementSize() const {
133       assert(Predicated);
134       return ElementSize;
135     }
136     unsigned getDstReg() const { return Dst; }
137     unsigned getPgReg() const {
138       assert(Predicated);
139       return Pg;
140     }
141 
142   private:
143     bool Active;
144     bool Predicated;
145     unsigned ElementSize;
146     unsigned Dst;
147     unsigned Pg;
148   } NextPrefix;
149 
150   AArch64TargetStreamer &getTargetStreamer() {
151     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
152     return static_cast<AArch64TargetStreamer &>(TS);
153   }
154 
155   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
156 
157   bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
158   void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S);
159   AArch64CC::CondCode parseCondCodeString(StringRef Cond);
160   bool parseCondCode(OperandVector &Operands, bool invertCondCode);
161   unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind);
162   bool parseRegister(OperandVector &Operands);
163   bool parseSymbolicImmVal(const MCExpr *&ImmVal);
164   bool parseNeonVectorList(OperandVector &Operands);
165   bool parseOptionalMulOperand(OperandVector &Operands);
166   bool parseKeywordOperand(OperandVector &Operands);
167   bool parseOperand(OperandVector &Operands, bool isCondCode,
168                     bool invertCondCode);
169   bool parseImmExpr(int64_t &Out);
170   bool parseComma();
171   bool parseRegisterInRange(unsigned &Out, unsigned Base, unsigned First,
172                             unsigned Last);
173 
174   bool showMatchError(SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
175                       OperandVector &Operands);
176 
177   bool parseDirectiveArch(SMLoc L);
178   bool parseDirectiveArchExtension(SMLoc L);
179   bool parseDirectiveCPU(SMLoc L);
180   bool parseDirectiveInst(SMLoc L);
181 
182   bool parseDirectiveTLSDescCall(SMLoc L);
183 
184   bool parseDirectiveLOH(StringRef LOH, SMLoc L);
185   bool parseDirectiveLtorg(SMLoc L);
186 
187   bool parseDirectiveReq(StringRef Name, SMLoc L);
188   bool parseDirectiveUnreq(SMLoc L);
189   bool parseDirectiveCFINegateRAState();
190   bool parseDirectiveCFIBKeyFrame();
191 
192   bool parseDirectiveVariantPCS(SMLoc L);
193 
194   bool parseDirectiveSEHAllocStack(SMLoc L);
195   bool parseDirectiveSEHPrologEnd(SMLoc L);
196   bool parseDirectiveSEHSaveR19R20X(SMLoc L);
197   bool parseDirectiveSEHSaveFPLR(SMLoc L);
198   bool parseDirectiveSEHSaveFPLRX(SMLoc L);
199   bool parseDirectiveSEHSaveReg(SMLoc L);
200   bool parseDirectiveSEHSaveRegX(SMLoc L);
201   bool parseDirectiveSEHSaveRegP(SMLoc L);
202   bool parseDirectiveSEHSaveRegPX(SMLoc L);
203   bool parseDirectiveSEHSaveLRPair(SMLoc L);
204   bool parseDirectiveSEHSaveFReg(SMLoc L);
205   bool parseDirectiveSEHSaveFRegX(SMLoc L);
206   bool parseDirectiveSEHSaveFRegP(SMLoc L);
207   bool parseDirectiveSEHSaveFRegPX(SMLoc L);
208   bool parseDirectiveSEHSetFP(SMLoc L);
209   bool parseDirectiveSEHAddFP(SMLoc L);
210   bool parseDirectiveSEHNop(SMLoc L);
211   bool parseDirectiveSEHSaveNext(SMLoc L);
212   bool parseDirectiveSEHEpilogStart(SMLoc L);
213   bool parseDirectiveSEHEpilogEnd(SMLoc L);
214   bool parseDirectiveSEHTrapFrame(SMLoc L);
215   bool parseDirectiveSEHMachineFrame(SMLoc L);
216   bool parseDirectiveSEHContext(SMLoc L);
217   bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
218 
219   bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
220                            SmallVectorImpl<SMLoc> &Loc);
221   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
222                                OperandVector &Operands, MCStreamer &Out,
223                                uint64_t &ErrorInfo,
224                                bool MatchingInlineAsm) override;
225 /// @name Auto-generated Match Functions
226 /// {
227 
228 #define GET_ASSEMBLER_HEADER
229 #include "AArch64GenAsmMatcher.inc"
230 
231   /// }
232 
233   OperandMatchResultTy tryParseScalarRegister(unsigned &Reg);
234   OperandMatchResultTy tryParseVectorRegister(unsigned &Reg, StringRef &Kind,
235                                               RegKind MatchKind);
236   OperandMatchResultTy tryParseMatrixRegister(OperandVector &Operands);
237   OperandMatchResultTy tryParseSVCR(OperandVector &Operands);
238   OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
239   OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
240   OperandMatchResultTy tryParseBarriernXSOperand(OperandVector &Operands);
241   OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
242   OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
243   OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
244   template <bool IsSVEPrefetch = false>
245   OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
246   OperandMatchResultTy tryParsePSBHint(OperandVector &Operands);
247   OperandMatchResultTy tryParseBTIHint(OperandVector &Operands);
248   OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
249   OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
250   template<bool AddFPZeroAsLiteral>
251   OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
252   OperandMatchResultTy tryParseImmWithOptionalShift(OperandVector &Operands);
253   OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
254   bool tryParseNeonVectorRegister(OperandVector &Operands);
255   OperandMatchResultTy tryParseVectorIndex(OperandVector &Operands);
256   OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands);
257   template <bool ParseShiftExtend,
258             RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
259   OperandMatchResultTy tryParseGPROperand(OperandVector &Operands);
260   template <bool ParseShiftExtend, bool ParseSuffix>
261   OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands);
262   OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands);
263   template <RegKind VectorKind>
264   OperandMatchResultTy tryParseVectorList(OperandVector &Operands,
265                                           bool ExpectMatch = false);
266   OperandMatchResultTy tryParseMatrixTileList(OperandVector &Operands);
267   OperandMatchResultTy tryParseSVEPattern(OperandVector &Operands);
268   OperandMatchResultTy tryParseGPR64x8(OperandVector &Operands);
269 
270 public:
271   enum AArch64MatchResultTy {
272     Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
273 #define GET_OPERAND_DIAGNOSTIC_TYPES
274 #include "AArch64GenAsmMatcher.inc"
275   };
276   bool IsILP32;
277 
278   AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
279                    const MCInstrInfo &MII, const MCTargetOptions &Options)
280     : MCTargetAsmParser(Options, STI, MII) {
281     IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
282     MCAsmParserExtension::Initialize(Parser);
283     MCStreamer &S = getParser().getStreamer();
284     if (S.getTargetStreamer() == nullptr)
285       new AArch64TargetStreamer(S);
286 
287     // Alias .hword/.word/.[dx]word to the target-independent
288     // .2byte/.4byte/.8byte directives as they have the same form and
289     // semantics:
290     ///  ::= (.hword | .word | .dword | .xword ) [ expression (, expression)* ]
291     Parser.addAliasForDirective(".hword", ".2byte");
292     Parser.addAliasForDirective(".word", ".4byte");
293     Parser.addAliasForDirective(".dword", ".8byte");
294     Parser.addAliasForDirective(".xword", ".8byte");
295 
296     // Initialize the set of available features.
297     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
298   }
299 
300   bool regsEqual(const MCParsedAsmOperand &Op1,
301                  const MCParsedAsmOperand &Op2) const override;
302   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
303                         SMLoc NameLoc, OperandVector &Operands) override;
304   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
305   OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
306                                         SMLoc &EndLoc) override;
307   bool ParseDirective(AsmToken DirectiveID) override;
308   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
309                                       unsigned Kind) override;
310 
311   static bool classifySymbolRef(const MCExpr *Expr,
312                                 AArch64MCExpr::VariantKind &ELFRefKind,
313                                 MCSymbolRefExpr::VariantKind &DarwinRefKind,
314                                 int64_t &Addend);
315 };
316 
317 /// AArch64Operand - Instances of this class represent a parsed AArch64 machine
318 /// instruction.
319 class AArch64Operand : public MCParsedAsmOperand {
320 private:
321   enum KindTy {
322     k_Immediate,
323     k_ShiftedImm,
324     k_CondCode,
325     k_Register,
326     k_MatrixRegister,
327     k_MatrixTileList,
328     k_SVCR,
329     k_VectorList,
330     k_VectorIndex,
331     k_Token,
332     k_SysReg,
333     k_SysCR,
334     k_Prefetch,
335     k_ShiftExtend,
336     k_FPImm,
337     k_Barrier,
338     k_PSBHint,
339     k_BTIHint,
340   } Kind;
341 
342   SMLoc StartLoc, EndLoc;
343 
344   struct TokOp {
345     const char *Data;
346     unsigned Length;
347     bool IsSuffix; // Is the operand actually a suffix on the mnemonic.
348   };
349 
350   // Separate shift/extend operand.
351   struct ShiftExtendOp {
352     AArch64_AM::ShiftExtendType Type;
353     unsigned Amount;
354     bool HasExplicitAmount;
355   };
356 
357   struct RegOp {
358     unsigned RegNum;
359     RegKind Kind;
360     int ElementWidth;
361 
362     // The register may be allowed as a different register class,
363     // e.g. for GPR64as32 or GPR32as64.
364     RegConstraintEqualityTy EqualityTy;
365 
366     // In some cases the shift/extend needs to be explicitly parsed together
367     // with the register, rather than as a separate operand. This is needed
368     // for addressing modes where the instruction as a whole dictates the
369     // scaling/extend, rather than specific bits in the instruction.
370     // By parsing them as a single operand, we avoid the need to pass an
371     // extra operand in all CodeGen patterns (because all operands need to
372     // have an associated value), and we avoid the need to update TableGen to
373     // accept operands that have no associated bits in the instruction.
374     //
375     // An added benefit of parsing them together is that the assembler
376     // can give a sensible diagnostic if the scaling is not correct.
377     //
378     // The default is 'lsl #0' (HasExplicitAmount = false) if no
379     // ShiftExtend is specified.
380     ShiftExtendOp ShiftExtend;
381   };
382 
383   struct MatrixRegOp {
384     unsigned RegNum;
385     unsigned ElementWidth;
386     MatrixKind Kind;
387   };
388 
389   struct MatrixTileListOp {
390     unsigned RegMask = 0;
391   };
392 
393   struct VectorListOp {
394     unsigned RegNum;
395     unsigned Count;
396     unsigned NumElements;
397     unsigned ElementWidth;
398     RegKind  RegisterKind;
399   };
400 
401   struct VectorIndexOp {
402     int Val;
403   };
404 
405   struct ImmOp {
406     const MCExpr *Val;
407   };
408 
409   struct ShiftedImmOp {
410     const MCExpr *Val;
411     unsigned ShiftAmount;
412   };
413 
414   struct CondCodeOp {
415     AArch64CC::CondCode Code;
416   };
417 
418   struct FPImmOp {
419     uint64_t Val; // APFloat value bitcasted to uint64_t.
420     bool IsExact; // describes whether parsed value was exact.
421   };
422 
423   struct BarrierOp {
424     const char *Data;
425     unsigned Length;
426     unsigned Val; // Not the enum since not all values have names.
427     bool HasnXSModifier;
428   };
429 
430   struct SysRegOp {
431     const char *Data;
432     unsigned Length;
433     uint32_t MRSReg;
434     uint32_t MSRReg;
435     uint32_t PStateField;
436   };
437 
438   struct SysCRImmOp {
439     unsigned Val;
440   };
441 
442   struct PrefetchOp {
443     const char *Data;
444     unsigned Length;
445     unsigned Val;
446   };
447 
448   struct PSBHintOp {
449     const char *Data;
450     unsigned Length;
451     unsigned Val;
452   };
453 
454   struct BTIHintOp {
455     const char *Data;
456     unsigned Length;
457     unsigned Val;
458   };
459 
460   struct SVCROp {
461     const char *Data;
462     unsigned Length;
463     unsigned PStateField;
464   };
465 
466   union {
467     struct TokOp Tok;
468     struct RegOp Reg;
469     struct MatrixRegOp MatrixReg;
470     struct MatrixTileListOp MatrixTileList;
471     struct VectorListOp VectorList;
472     struct VectorIndexOp VectorIndex;
473     struct ImmOp Imm;
474     struct ShiftedImmOp ShiftedImm;
475     struct CondCodeOp CondCode;
476     struct FPImmOp FPImm;
477     struct BarrierOp Barrier;
478     struct SysRegOp SysReg;
479     struct SysCRImmOp SysCRImm;
480     struct PrefetchOp Prefetch;
481     struct PSBHintOp PSBHint;
482     struct BTIHintOp BTIHint;
483     struct ShiftExtendOp ShiftExtend;
484     struct SVCROp SVCR;
485   };
486 
487   // Keep the MCContext around as the MCExprs may need manipulated during
488   // the add<>Operands() calls.
489   MCContext &Ctx;
490 
491 public:
492   AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {}
493 
494   AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
495     Kind = o.Kind;
496     StartLoc = o.StartLoc;
497     EndLoc = o.EndLoc;
498     switch (Kind) {
499     case k_Token:
500       Tok = o.Tok;
501       break;
502     case k_Immediate:
503       Imm = o.Imm;
504       break;
505     case k_ShiftedImm:
506       ShiftedImm = o.ShiftedImm;
507       break;
508     case k_CondCode:
509       CondCode = o.CondCode;
510       break;
511     case k_FPImm:
512       FPImm = o.FPImm;
513       break;
514     case k_Barrier:
515       Barrier = o.Barrier;
516       break;
517     case k_Register:
518       Reg = o.Reg;
519       break;
520     case k_MatrixRegister:
521       MatrixReg = o.MatrixReg;
522       break;
523     case k_MatrixTileList:
524       MatrixTileList = o.MatrixTileList;
525       break;
526     case k_VectorList:
527       VectorList = o.VectorList;
528       break;
529     case k_VectorIndex:
530       VectorIndex = o.VectorIndex;
531       break;
532     case k_SysReg:
533       SysReg = o.SysReg;
534       break;
535     case k_SysCR:
536       SysCRImm = o.SysCRImm;
537       break;
538     case k_Prefetch:
539       Prefetch = o.Prefetch;
540       break;
541     case k_PSBHint:
542       PSBHint = o.PSBHint;
543       break;
544     case k_BTIHint:
545       BTIHint = o.BTIHint;
546       break;
547     case k_ShiftExtend:
548       ShiftExtend = o.ShiftExtend;
549       break;
550     case k_SVCR:
551       SVCR = o.SVCR;
552       break;
553     }
554   }
555 
556   /// getStartLoc - Get the location of the first token of this operand.
557   SMLoc getStartLoc() const override { return StartLoc; }
558   /// getEndLoc - Get the location of the last token of this operand.
559   SMLoc getEndLoc() const override { return EndLoc; }
560 
561   StringRef getToken() const {
562     assert(Kind == k_Token && "Invalid access!");
563     return StringRef(Tok.Data, Tok.Length);
564   }
565 
566   bool isTokenSuffix() const {
567     assert(Kind == k_Token && "Invalid access!");
568     return Tok.IsSuffix;
569   }
570 
571   const MCExpr *getImm() const {
572     assert(Kind == k_Immediate && "Invalid access!");
573     return Imm.Val;
574   }
575 
576   const MCExpr *getShiftedImmVal() const {
577     assert(Kind == k_ShiftedImm && "Invalid access!");
578     return ShiftedImm.Val;
579   }
580 
581   unsigned getShiftedImmShift() const {
582     assert(Kind == k_ShiftedImm && "Invalid access!");
583     return ShiftedImm.ShiftAmount;
584   }
585 
586   AArch64CC::CondCode getCondCode() const {
587     assert(Kind == k_CondCode && "Invalid access!");
588     return CondCode.Code;
589   }
590 
591   APFloat getFPImm() const {
592     assert (Kind == k_FPImm && "Invalid access!");
593     return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val, true));
594   }
595 
596   bool getFPImmIsExact() const {
597     assert (Kind == k_FPImm && "Invalid access!");
598     return FPImm.IsExact;
599   }
600 
601   unsigned getBarrier() const {
602     assert(Kind == k_Barrier && "Invalid access!");
603     return Barrier.Val;
604   }
605 
606   StringRef getBarrierName() const {
607     assert(Kind == k_Barrier && "Invalid access!");
608     return StringRef(Barrier.Data, Barrier.Length);
609   }
610 
611   bool getBarriernXSModifier() const {
612     assert(Kind == k_Barrier && "Invalid access!");
613     return Barrier.HasnXSModifier;
614   }
615 
616   unsigned getReg() const override {
617     assert(Kind == k_Register && "Invalid access!");
618     return Reg.RegNum;
619   }
620 
621   unsigned getMatrixReg() const {
622     assert(Kind == k_MatrixRegister && "Invalid access!");
623     return MatrixReg.RegNum;
624   }
625 
626   unsigned getMatrixElementWidth() const {
627     assert(Kind == k_MatrixRegister && "Invalid access!");
628     return MatrixReg.ElementWidth;
629   }
630 
631   MatrixKind getMatrixKind() const {
632     assert(Kind == k_MatrixRegister && "Invalid access!");
633     return MatrixReg.Kind;
634   }
635 
636   unsigned getMatrixTileListRegMask() const {
637     assert(isMatrixTileList() && "Invalid access!");
638     return MatrixTileList.RegMask;
639   }
640 
641   RegConstraintEqualityTy getRegEqualityTy() const {
642     assert(Kind == k_Register && "Invalid access!");
643     return Reg.EqualityTy;
644   }
645 
646   unsigned getVectorListStart() const {
647     assert(Kind == k_VectorList && "Invalid access!");
648     return VectorList.RegNum;
649   }
650 
651   unsigned getVectorListCount() const {
652     assert(Kind == k_VectorList && "Invalid access!");
653     return VectorList.Count;
654   }
655 
656   int getVectorIndex() const {
657     assert(Kind == k_VectorIndex && "Invalid access!");
658     return VectorIndex.Val;
659   }
660 
661   StringRef getSysReg() const {
662     assert(Kind == k_SysReg && "Invalid access!");
663     return StringRef(SysReg.Data, SysReg.Length);
664   }
665 
666   unsigned getSysCR() const {
667     assert(Kind == k_SysCR && "Invalid access!");
668     return SysCRImm.Val;
669   }
670 
671   unsigned getPrefetch() const {
672     assert(Kind == k_Prefetch && "Invalid access!");
673     return Prefetch.Val;
674   }
675 
676   unsigned getPSBHint() const {
677     assert(Kind == k_PSBHint && "Invalid access!");
678     return PSBHint.Val;
679   }
680 
681   StringRef getPSBHintName() const {
682     assert(Kind == k_PSBHint && "Invalid access!");
683     return StringRef(PSBHint.Data, PSBHint.Length);
684   }
685 
686   unsigned getBTIHint() const {
687     assert(Kind == k_BTIHint && "Invalid access!");
688     return BTIHint.Val;
689   }
690 
691   StringRef getBTIHintName() const {
692     assert(Kind == k_BTIHint && "Invalid access!");
693     return StringRef(BTIHint.Data, BTIHint.Length);
694   }
695 
696   StringRef getSVCR() const {
697     assert(Kind == k_SVCR && "Invalid access!");
698     return StringRef(SVCR.Data, SVCR.Length);
699   }
700 
701   StringRef getPrefetchName() const {
702     assert(Kind == k_Prefetch && "Invalid access!");
703     return StringRef(Prefetch.Data, Prefetch.Length);
704   }
705 
706   AArch64_AM::ShiftExtendType getShiftExtendType() const {
707     if (Kind == k_ShiftExtend)
708       return ShiftExtend.Type;
709     if (Kind == k_Register)
710       return Reg.ShiftExtend.Type;
711     llvm_unreachable("Invalid access!");
712   }
713 
714   unsigned getShiftExtendAmount() const {
715     if (Kind == k_ShiftExtend)
716       return ShiftExtend.Amount;
717     if (Kind == k_Register)
718       return Reg.ShiftExtend.Amount;
719     llvm_unreachable("Invalid access!");
720   }
721 
722   bool hasShiftExtendAmount() const {
723     if (Kind == k_ShiftExtend)
724       return ShiftExtend.HasExplicitAmount;
725     if (Kind == k_Register)
726       return Reg.ShiftExtend.HasExplicitAmount;
727     llvm_unreachable("Invalid access!");
728   }
729 
730   bool isImm() const override { return Kind == k_Immediate; }
731   bool isMem() const override { return false; }
732 
733   bool isUImm6() const {
734     if (!isImm())
735       return false;
736     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
737     if (!MCE)
738       return false;
739     int64_t Val = MCE->getValue();
740     return (Val >= 0 && Val < 64);
741   }
742 
743   template <int Width> bool isSImm() const { return isSImmScaled<Width, 1>(); }
744 
745   template <int Bits, int Scale> DiagnosticPredicate isSImmScaled() const {
746     return isImmScaled<Bits, Scale>(true);
747   }
748 
749   template <int Bits, int Scale> DiagnosticPredicate isUImmScaled() const {
750     return isImmScaled<Bits, Scale>(false);
751   }
752 
753   template <int Bits, int Scale>
754   DiagnosticPredicate isImmScaled(bool Signed) const {
755     if (!isImm())
756       return DiagnosticPredicateTy::NoMatch;
757 
758     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
759     if (!MCE)
760       return DiagnosticPredicateTy::NoMatch;
761 
762     int64_t MinVal, MaxVal;
763     if (Signed) {
764       int64_t Shift = Bits - 1;
765       MinVal = (int64_t(1) << Shift) * -Scale;
766       MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
767     } else {
768       MinVal = 0;
769       MaxVal = ((int64_t(1) << Bits) - 1) * Scale;
770     }
771 
772     int64_t Val = MCE->getValue();
773     if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
774       return DiagnosticPredicateTy::Match;
775 
776     return DiagnosticPredicateTy::NearMatch;
777   }
778 
779   DiagnosticPredicate isSVEPattern() const {
780     if (!isImm())
781       return DiagnosticPredicateTy::NoMatch;
782     auto *MCE = dyn_cast<MCConstantExpr>(getImm());
783     if (!MCE)
784       return DiagnosticPredicateTy::NoMatch;
785     int64_t Val = MCE->getValue();
786     if (Val >= 0 && Val < 32)
787       return DiagnosticPredicateTy::Match;
788     return DiagnosticPredicateTy::NearMatch;
789   }
790 
791   bool isSymbolicUImm12Offset(const MCExpr *Expr) const {
792     AArch64MCExpr::VariantKind ELFRefKind;
793     MCSymbolRefExpr::VariantKind DarwinRefKind;
794     int64_t Addend;
795     if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
796                                            Addend)) {
797       // If we don't understand the expression, assume the best and
798       // let the fixup and relocation code deal with it.
799       return true;
800     }
801 
802     if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
803         ELFRefKind == AArch64MCExpr::VK_LO12 ||
804         ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
805         ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
806         ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
807         ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
808         ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
809         ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
810         ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
811         ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
812         ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
813         ELFRefKind == AArch64MCExpr::VK_GOT_PAGE_LO15) {
814       // Note that we don't range-check the addend. It's adjusted modulo page
815       // size when converted, so there is no "out of range" condition when using
816       // @pageoff.
817       return true;
818     } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
819                DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
820       // @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
821       return Addend == 0;
822     }
823 
824     return false;
825   }
826 
827   template <int Scale> bool isUImm12Offset() const {
828     if (!isImm())
829       return false;
830 
831     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
832     if (!MCE)
833       return isSymbolicUImm12Offset(getImm());
834 
835     int64_t Val = MCE->getValue();
836     return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
837   }
838 
839   template <int N, int M>
840   bool isImmInRange() const {
841     if (!isImm())
842       return false;
843     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
844     if (!MCE)
845       return false;
846     int64_t Val = MCE->getValue();
847     return (Val >= N && Val <= M);
848   }
849 
850   // NOTE: Also used for isLogicalImmNot as anything that can be represented as
851   // a logical immediate can always be represented when inverted.
852   template <typename T>
853   bool isLogicalImm() const {
854     if (!isImm())
855       return false;
856     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
857     if (!MCE)
858       return false;
859 
860     int64_t Val = MCE->getValue();
861     // Avoid left shift by 64 directly.
862     uint64_t Upper = UINT64_C(-1) << (sizeof(T) * 4) << (sizeof(T) * 4);
863     // Allow all-0 or all-1 in top bits to permit bitwise NOT.
864     if ((Val & Upper) && (Val & Upper) != Upper)
865       return false;
866 
867     return AArch64_AM::isLogicalImmediate(Val & ~Upper, sizeof(T) * 8);
868   }
869 
870   bool isShiftedImm() const { return Kind == k_ShiftedImm; }
871 
872   /// Returns the immediate value as a pair of (imm, shift) if the immediate is
873   /// a shifted immediate by value 'Shift' or '0', or if it is an unshifted
874   /// immediate that can be shifted by 'Shift'.
875   template <unsigned Width>
876   Optional<std::pair<int64_t, unsigned> > getShiftedVal() const {
877     if (isShiftedImm() && Width == getShiftedImmShift())
878       if (auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
879         return std::make_pair(CE->getValue(), Width);
880 
881     if (isImm())
882       if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
883         int64_t Val = CE->getValue();
884         if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
885           return std::make_pair(Val >> Width, Width);
886         else
887           return std::make_pair(Val, 0u);
888       }
889 
890     return {};
891   }
892 
893   bool isAddSubImm() const {
894     if (!isShiftedImm() && !isImm())
895       return false;
896 
897     const MCExpr *Expr;
898 
899     // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
900     if (isShiftedImm()) {
901       unsigned Shift = ShiftedImm.ShiftAmount;
902       Expr = ShiftedImm.Val;
903       if (Shift != 0 && Shift != 12)
904         return false;
905     } else {
906       Expr = getImm();
907     }
908 
909     AArch64MCExpr::VariantKind ELFRefKind;
910     MCSymbolRefExpr::VariantKind DarwinRefKind;
911     int64_t Addend;
912     if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
913                                           DarwinRefKind, Addend)) {
914       return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
915           || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
916           || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
917           || ELFRefKind == AArch64MCExpr::VK_LO12
918           || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
919           || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
920           || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
921           || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
922           || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
923           || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
924           || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12
925           || ELFRefKind == AArch64MCExpr::VK_SECREL_HI12
926           || ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
927     }
928 
929     // If it's a constant, it should be a real immediate in range.
930     if (auto ShiftedVal = getShiftedVal<12>())
931       return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
932 
933     // If it's an expression, we hope for the best and let the fixup/relocation
934     // code deal with it.
935     return true;
936   }
937 
938   bool isAddSubImmNeg() const {
939     if (!isShiftedImm() && !isImm())
940       return false;
941 
942     // Otherwise it should be a real negative immediate in range.
943     if (auto ShiftedVal = getShiftedVal<12>())
944       return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
945 
946     return false;
947   }
948 
949   // Signed value in the range -128 to +127. For element widths of
950   // 16 bits or higher it may also be a signed multiple of 256 in the
951   // range -32768 to +32512.
952   // For element-width of 8 bits a range of -128 to 255 is accepted,
953   // since a copy of a byte can be either signed/unsigned.
954   template <typename T>
955   DiagnosticPredicate isSVECpyImm() const {
956     if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
957       return DiagnosticPredicateTy::NoMatch;
958 
959     bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
960                   std::is_same<int8_t, T>::value;
961     if (auto ShiftedImm = getShiftedVal<8>())
962       if (!(IsByte && ShiftedImm->second) &&
963           AArch64_AM::isSVECpyImm<T>(uint64_t(ShiftedImm->first)
964                                      << ShiftedImm->second))
965         return DiagnosticPredicateTy::Match;
966 
967     return DiagnosticPredicateTy::NearMatch;
968   }
969 
970   // Unsigned value in the range 0 to 255. For element widths of
971   // 16 bits or higher it may also be a signed multiple of 256 in the
972   // range 0 to 65280.
973   template <typename T> DiagnosticPredicate isSVEAddSubImm() const {
974     if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
975       return DiagnosticPredicateTy::NoMatch;
976 
977     bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
978                   std::is_same<int8_t, T>::value;
979     if (auto ShiftedImm = getShiftedVal<8>())
980       if (!(IsByte && ShiftedImm->second) &&
981           AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
982                                         << ShiftedImm->second))
983         return DiagnosticPredicateTy::Match;
984 
985     return DiagnosticPredicateTy::NearMatch;
986   }
987 
988   template <typename T> DiagnosticPredicate isSVEPreferredLogicalImm() const {
989     if (isLogicalImm<T>() && !isSVECpyImm<T>())
990       return DiagnosticPredicateTy::Match;
991     return DiagnosticPredicateTy::NoMatch;
992   }
993 
994   bool isCondCode() const { return Kind == k_CondCode; }
995 
996   bool isSIMDImmType10() const {
997     if (!isImm())
998       return false;
999     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1000     if (!MCE)
1001       return false;
1002     return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue());
1003   }
1004 
1005   template<int N>
1006   bool isBranchTarget() const {
1007     if (!isImm())
1008       return false;
1009     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1010     if (!MCE)
1011       return true;
1012     int64_t Val = MCE->getValue();
1013     if (Val & 0x3)
1014       return false;
1015     assert(N > 0 && "Branch target immediate cannot be 0 bits!");
1016     return (Val >= -((1<<(N-1)) << 2) && Val <= (((1<<(N-1))-1) << 2));
1017   }
1018 
1019   bool
1020   isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const {
1021     if (!isImm())
1022       return false;
1023 
1024     AArch64MCExpr::VariantKind ELFRefKind;
1025     MCSymbolRefExpr::VariantKind DarwinRefKind;
1026     int64_t Addend;
1027     if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
1028                                              DarwinRefKind, Addend)) {
1029       return false;
1030     }
1031     if (DarwinRefKind != MCSymbolRefExpr::VK_None)
1032       return false;
1033 
1034     for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
1035       if (ELFRefKind == AllowedModifiers[i])
1036         return true;
1037     }
1038 
1039     return false;
1040   }
1041 
1042   bool isMovWSymbolG3() const {
1043     return isMovWSymbol({AArch64MCExpr::VK_ABS_G3, AArch64MCExpr::VK_PREL_G3});
1044   }
1045 
1046   bool isMovWSymbolG2() const {
1047     return isMovWSymbol(
1048         {AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S,
1049          AArch64MCExpr::VK_ABS_G2_NC, AArch64MCExpr::VK_PREL_G2,
1050          AArch64MCExpr::VK_PREL_G2_NC, AArch64MCExpr::VK_TPREL_G2,
1051          AArch64MCExpr::VK_DTPREL_G2});
1052   }
1053 
1054   bool isMovWSymbolG1() const {
1055     return isMovWSymbol(
1056         {AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S,
1057          AArch64MCExpr::VK_ABS_G1_NC, AArch64MCExpr::VK_PREL_G1,
1058          AArch64MCExpr::VK_PREL_G1_NC, AArch64MCExpr::VK_GOTTPREL_G1,
1059          AArch64MCExpr::VK_TPREL_G1, AArch64MCExpr::VK_TPREL_G1_NC,
1060          AArch64MCExpr::VK_DTPREL_G1, AArch64MCExpr::VK_DTPREL_G1_NC});
1061   }
1062 
1063   bool isMovWSymbolG0() const {
1064     return isMovWSymbol(
1065         {AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S,
1066          AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_PREL_G0,
1067          AArch64MCExpr::VK_PREL_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC,
1068          AArch64MCExpr::VK_TPREL_G0, AArch64MCExpr::VK_TPREL_G0_NC,
1069          AArch64MCExpr::VK_DTPREL_G0, AArch64MCExpr::VK_DTPREL_G0_NC});
1070   }
1071 
1072   template<int RegWidth, int Shift>
1073   bool isMOVZMovAlias() const {
1074     if (!isImm()) return false;
1075 
1076     const MCExpr *E = getImm();
1077     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(E)) {
1078       uint64_t Value = CE->getValue();
1079 
1080       return AArch64_AM::isMOVZMovAlias(Value, Shift, RegWidth);
1081     }
1082     // Only supports the case of Shift being 0 if an expression is used as an
1083     // operand
1084     return !Shift && E;
1085   }
1086 
1087   template<int RegWidth, int Shift>
1088   bool isMOVNMovAlias() const {
1089     if (!isImm()) return false;
1090 
1091     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1092     if (!CE) return false;
1093     uint64_t Value = CE->getValue();
1094 
1095     return AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth);
1096   }
1097 
1098   bool isFPImm() const {
1099     return Kind == k_FPImm &&
1100            AArch64_AM::getFP64Imm(getFPImm().bitcastToAPInt()) != -1;
1101   }
1102 
1103   bool isBarrier() const {
1104     return Kind == k_Barrier && !getBarriernXSModifier();
1105   }
1106   bool isBarriernXS() const {
1107     return Kind == k_Barrier && getBarriernXSModifier();
1108   }
1109   bool isSysReg() const { return Kind == k_SysReg; }
1110 
1111   bool isMRSSystemRegister() const {
1112     if (!isSysReg()) return false;
1113 
1114     return SysReg.MRSReg != -1U;
1115   }
1116 
1117   bool isMSRSystemRegister() const {
1118     if (!isSysReg()) return false;
1119     return SysReg.MSRReg != -1U;
1120   }
1121 
1122   bool isSystemPStateFieldWithImm0_1() const {
1123     if (!isSysReg()) return false;
1124     return (SysReg.PStateField == AArch64PState::PAN ||
1125             SysReg.PStateField == AArch64PState::DIT ||
1126             SysReg.PStateField == AArch64PState::UAO ||
1127             SysReg.PStateField == AArch64PState::SSBS);
1128   }
1129 
1130   bool isSystemPStateFieldWithImm0_15() const {
1131     if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false;
1132     return SysReg.PStateField != -1U;
1133   }
1134 
1135   bool isSVCR() const {
1136     if (Kind != k_SVCR)
1137       return false;
1138     return SVCR.PStateField != -1U;
1139   }
1140 
1141   bool isReg() const override {
1142     return Kind == k_Register;
1143   }
1144 
1145   bool isScalarReg() const {
1146     return Kind == k_Register && Reg.Kind == RegKind::Scalar;
1147   }
1148 
1149   bool isNeonVectorReg() const {
1150     return Kind == k_Register && Reg.Kind == RegKind::NeonVector;
1151   }
1152 
1153   bool isNeonVectorRegLo() const {
1154     return Kind == k_Register && Reg.Kind == RegKind::NeonVector &&
1155            (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1156                 Reg.RegNum) ||
1157             AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1158                 Reg.RegNum));
1159   }
1160 
1161   bool isMatrix() const { return Kind == k_MatrixRegister; }
1162   bool isMatrixTileList() const { return Kind == k_MatrixTileList; }
1163 
1164   template <unsigned Class> bool isSVEVectorReg() const {
1165     RegKind RK;
1166     switch (Class) {
1167     case AArch64::ZPRRegClassID:
1168     case AArch64::ZPR_3bRegClassID:
1169     case AArch64::ZPR_4bRegClassID:
1170       RK = RegKind::SVEDataVector;
1171       break;
1172     case AArch64::PPRRegClassID:
1173     case AArch64::PPR_3bRegClassID:
1174       RK = RegKind::SVEPredicateVector;
1175       break;
1176     default:
1177       llvm_unreachable("Unsupport register class");
1178     }
1179 
1180     return (Kind == k_Register && Reg.Kind == RK) &&
1181            AArch64MCRegisterClasses[Class].contains(getReg());
1182   }
1183 
1184   template <unsigned Class> bool isFPRasZPR() const {
1185     return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1186            AArch64MCRegisterClasses[Class].contains(getReg());
1187   }
1188 
1189   template <int ElementWidth, unsigned Class>
1190   DiagnosticPredicate isSVEPredicateVectorRegOfWidth() const {
1191     if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector)
1192       return DiagnosticPredicateTy::NoMatch;
1193 
1194     if (isSVEVectorReg<Class>() && (Reg.ElementWidth == ElementWidth))
1195       return DiagnosticPredicateTy::Match;
1196 
1197     return DiagnosticPredicateTy::NearMatch;
1198   }
1199 
1200   template <int ElementWidth, unsigned Class>
1201   DiagnosticPredicate isSVEDataVectorRegOfWidth() const {
1202     if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector)
1203       return DiagnosticPredicateTy::NoMatch;
1204 
1205     if (isSVEVectorReg<Class>() && Reg.ElementWidth == ElementWidth)
1206       return DiagnosticPredicateTy::Match;
1207 
1208     return DiagnosticPredicateTy::NearMatch;
1209   }
1210 
1211   template <int ElementWidth, unsigned Class,
1212             AArch64_AM::ShiftExtendType ShiftExtendTy, int ShiftWidth,
1213             bool ShiftWidthAlwaysSame>
1214   DiagnosticPredicate isSVEDataVectorRegWithShiftExtend() const {
1215     auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1216     if (!VectorMatch.isMatch())
1217       return DiagnosticPredicateTy::NoMatch;
1218 
1219     // Give a more specific diagnostic when the user has explicitly typed in
1220     // a shift-amount that does not match what is expected, but for which
1221     // there is also an unscaled addressing mode (e.g. sxtw/uxtw).
1222     bool MatchShift = getShiftExtendAmount() == Log2_32(ShiftWidth / 8);
1223     if (!MatchShift && (ShiftExtendTy == AArch64_AM::UXTW ||
1224                         ShiftExtendTy == AArch64_AM::SXTW) &&
1225         !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1226       return DiagnosticPredicateTy::NoMatch;
1227 
1228     if (MatchShift && ShiftExtendTy == getShiftExtendType())
1229       return DiagnosticPredicateTy::Match;
1230 
1231     return DiagnosticPredicateTy::NearMatch;
1232   }
1233 
1234   bool isGPR32as64() const {
1235     return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1236       AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
1237   }
1238 
1239   bool isGPR64as32() const {
1240     return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1241       AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(Reg.RegNum);
1242   }
1243 
1244   bool isGPR64x8() const {
1245     return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1246            AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1247                Reg.RegNum);
1248   }
1249 
1250   bool isWSeqPair() const {
1251     return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1252            AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1253                Reg.RegNum);
1254   }
1255 
1256   bool isXSeqPair() const {
1257     return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1258            AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1259                Reg.RegNum);
1260   }
1261 
1262   template<int64_t Angle, int64_t Remainder>
1263   DiagnosticPredicate isComplexRotation() const {
1264     if (!isImm()) return DiagnosticPredicateTy::NoMatch;
1265 
1266     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1267     if (!CE) return DiagnosticPredicateTy::NoMatch;
1268     uint64_t Value = CE->getValue();
1269 
1270     if (Value % Angle == Remainder && Value <= 270)
1271       return DiagnosticPredicateTy::Match;
1272     return DiagnosticPredicateTy::NearMatch;
1273   }
1274 
1275   template <unsigned RegClassID> bool isGPR64() const {
1276     return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1277            AArch64MCRegisterClasses[RegClassID].contains(getReg());
1278   }
1279 
1280   template <unsigned RegClassID, int ExtWidth>
1281   DiagnosticPredicate isGPR64WithShiftExtend() const {
1282     if (Kind != k_Register || Reg.Kind != RegKind::Scalar)
1283       return DiagnosticPredicateTy::NoMatch;
1284 
1285     if (isGPR64<RegClassID>() && getShiftExtendType() == AArch64_AM::LSL &&
1286         getShiftExtendAmount() == Log2_32(ExtWidth / 8))
1287       return DiagnosticPredicateTy::Match;
1288     return DiagnosticPredicateTy::NearMatch;
1289   }
1290 
1291   /// Is this a vector list with the type implicit (presumably attached to the
1292   /// instruction itself)?
1293   template <RegKind VectorKind, unsigned NumRegs>
1294   bool isImplicitlyTypedVectorList() const {
1295     return Kind == k_VectorList && VectorList.Count == NumRegs &&
1296            VectorList.NumElements == 0 &&
1297            VectorList.RegisterKind == VectorKind;
1298   }
1299 
1300   template <RegKind VectorKind, unsigned NumRegs, unsigned NumElements,
1301             unsigned ElementWidth>
1302   bool isTypedVectorList() const {
1303     if (Kind != k_VectorList)
1304       return false;
1305     if (VectorList.Count != NumRegs)
1306       return false;
1307     if (VectorList.RegisterKind != VectorKind)
1308       return false;
1309     if (VectorList.ElementWidth != ElementWidth)
1310       return false;
1311     return VectorList.NumElements == NumElements;
1312   }
1313 
1314   template <int Min, int Max>
1315   DiagnosticPredicate isVectorIndex() const {
1316     if (Kind != k_VectorIndex)
1317       return DiagnosticPredicateTy::NoMatch;
1318     if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1319       return DiagnosticPredicateTy::Match;
1320     return DiagnosticPredicateTy::NearMatch;
1321   }
1322 
1323   bool isToken() const override { return Kind == k_Token; }
1324 
1325   bool isTokenEqual(StringRef Str) const {
1326     return Kind == k_Token && getToken() == Str;
1327   }
1328   bool isSysCR() const { return Kind == k_SysCR; }
1329   bool isPrefetch() const { return Kind == k_Prefetch; }
1330   bool isPSBHint() const { return Kind == k_PSBHint; }
1331   bool isBTIHint() const { return Kind == k_BTIHint; }
1332   bool isShiftExtend() const { return Kind == k_ShiftExtend; }
1333   bool isShifter() const {
1334     if (!isShiftExtend())
1335       return false;
1336 
1337     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1338     return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1339             ST == AArch64_AM::ASR || ST == AArch64_AM::ROR ||
1340             ST == AArch64_AM::MSL);
1341   }
1342 
1343   template <unsigned ImmEnum> DiagnosticPredicate isExactFPImm() const {
1344     if (Kind != k_FPImm)
1345       return DiagnosticPredicateTy::NoMatch;
1346 
1347     if (getFPImmIsExact()) {
1348       // Lookup the immediate from table of supported immediates.
1349       auto *Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1350       assert(Desc && "Unknown enum value");
1351 
1352       // Calculate its FP value.
1353       APFloat RealVal(APFloat::IEEEdouble());
1354       auto StatusOrErr =
1355           RealVal.convertFromString(Desc->Repr, APFloat::rmTowardZero);
1356       if (errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1357         llvm_unreachable("FP immediate is not exact");
1358 
1359       if (getFPImm().bitwiseIsEqual(RealVal))
1360         return DiagnosticPredicateTy::Match;
1361     }
1362 
1363     return DiagnosticPredicateTy::NearMatch;
1364   }
1365 
1366   template <unsigned ImmA, unsigned ImmB>
1367   DiagnosticPredicate isExactFPImm() const {
1368     DiagnosticPredicate Res = DiagnosticPredicateTy::NoMatch;
1369     if ((Res = isExactFPImm<ImmA>()))
1370       return DiagnosticPredicateTy::Match;
1371     if ((Res = isExactFPImm<ImmB>()))
1372       return DiagnosticPredicateTy::Match;
1373     return Res;
1374   }
1375 
1376   bool isExtend() const {
1377     if (!isShiftExtend())
1378       return false;
1379 
1380     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1381     return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
1382             ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
1383             ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW ||
1384             ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
1385             ET == AArch64_AM::LSL) &&
1386            getShiftExtendAmount() <= 4;
1387   }
1388 
1389   bool isExtend64() const {
1390     if (!isExtend())
1391       return false;
1392     // Make sure the extend expects a 32-bit source register.
1393     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1394     return ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
1395            ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
1396            ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW;
1397   }
1398 
1399   bool isExtendLSL64() const {
1400     if (!isExtend())
1401       return false;
1402     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1403     return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
1404             ET == AArch64_AM::LSL) &&
1405            getShiftExtendAmount() <= 4;
1406   }
1407 
1408   template<int Width> bool isMemXExtend() const {
1409     if (!isExtend())
1410       return false;
1411     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1412     return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) &&
1413            (getShiftExtendAmount() == Log2_32(Width / 8) ||
1414             getShiftExtendAmount() == 0);
1415   }
1416 
1417   template<int Width> bool isMemWExtend() const {
1418     if (!isExtend())
1419       return false;
1420     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1421     return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) &&
1422            (getShiftExtendAmount() == Log2_32(Width / 8) ||
1423             getShiftExtendAmount() == 0);
1424   }
1425 
1426   template <unsigned width>
1427   bool isArithmeticShifter() const {
1428     if (!isShifter())
1429       return false;
1430 
1431     // An arithmetic shifter is LSL, LSR, or ASR.
1432     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1433     return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1434             ST == AArch64_AM::ASR) && getShiftExtendAmount() < width;
1435   }
1436 
1437   template <unsigned width>
1438   bool isLogicalShifter() const {
1439     if (!isShifter())
1440       return false;
1441 
1442     // A logical shifter is LSL, LSR, ASR or ROR.
1443     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1444     return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1445             ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) &&
1446            getShiftExtendAmount() < width;
1447   }
1448 
1449   bool isMovImm32Shifter() const {
1450     if (!isShifter())
1451       return false;
1452 
1453     // A MOVi shifter is LSL of 0, 16, 32, or 48.
1454     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1455     if (ST != AArch64_AM::LSL)
1456       return false;
1457     uint64_t Val = getShiftExtendAmount();
1458     return (Val == 0 || Val == 16);
1459   }
1460 
1461   bool isMovImm64Shifter() const {
1462     if (!isShifter())
1463       return false;
1464 
1465     // A MOVi shifter is LSL of 0 or 16.
1466     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1467     if (ST != AArch64_AM::LSL)
1468       return false;
1469     uint64_t Val = getShiftExtendAmount();
1470     return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1471   }
1472 
1473   bool isLogicalVecShifter() const {
1474     if (!isShifter())
1475       return false;
1476 
1477     // A logical vector shifter is a left shift by 0, 8, 16, or 24.
1478     unsigned Shift = getShiftExtendAmount();
1479     return getShiftExtendType() == AArch64_AM::LSL &&
1480            (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1481   }
1482 
1483   bool isLogicalVecHalfWordShifter() const {
1484     if (!isLogicalVecShifter())
1485       return false;
1486 
1487     // A logical vector shifter is a left shift by 0 or 8.
1488     unsigned Shift = getShiftExtendAmount();
1489     return getShiftExtendType() == AArch64_AM::LSL &&
1490            (Shift == 0 || Shift == 8);
1491   }
1492 
1493   bool isMoveVecShifter() const {
1494     if (!isShiftExtend())
1495       return false;
1496 
1497     // A logical vector shifter is a left shift by 8 or 16.
1498     unsigned Shift = getShiftExtendAmount();
1499     return getShiftExtendType() == AArch64_AM::MSL &&
1500            (Shift == 8 || Shift == 16);
1501   }
1502 
1503   // Fallback unscaled operands are for aliases of LDR/STR that fall back
1504   // to LDUR/STUR when the offset is not legal for the former but is for
1505   // the latter. As such, in addition to checking for being a legal unscaled
1506   // address, also check that it is not a legal scaled address. This avoids
1507   // ambiguity in the matcher.
1508   template<int Width>
1509   bool isSImm9OffsetFB() const {
1510     return isSImm<9>() && !isUImm12Offset<Width / 8>();
1511   }
1512 
1513   bool isAdrpLabel() const {
1514     // Validation was handled during parsing, so we just sanity check that
1515     // something didn't go haywire.
1516     if (!isImm())
1517         return false;
1518 
1519     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1520       int64_t Val = CE->getValue();
1521       int64_t Min = - (4096 * (1LL << (21 - 1)));
1522       int64_t Max = 4096 * ((1LL << (21 - 1)) - 1);
1523       return (Val % 4096) == 0 && Val >= Min && Val <= Max;
1524     }
1525 
1526     return true;
1527   }
1528 
1529   bool isAdrLabel() const {
1530     // Validation was handled during parsing, so we just sanity check that
1531     // something didn't go haywire.
1532     if (!isImm())
1533         return false;
1534 
1535     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1536       int64_t Val = CE->getValue();
1537       int64_t Min = - (1LL << (21 - 1));
1538       int64_t Max = ((1LL << (21 - 1)) - 1);
1539       return Val >= Min && Val <= Max;
1540     }
1541 
1542     return true;
1543   }
1544 
1545   template <MatrixKind Kind, unsigned EltSize, unsigned RegClass>
1546   DiagnosticPredicate isMatrixRegOperand() const {
1547     if (!isMatrix())
1548       return DiagnosticPredicateTy::NoMatch;
1549     if (getMatrixKind() != Kind ||
1550         !AArch64MCRegisterClasses[RegClass].contains(getMatrixReg()) ||
1551         EltSize != getMatrixElementWidth())
1552       return DiagnosticPredicateTy::NearMatch;
1553     return DiagnosticPredicateTy::Match;
1554   }
1555 
1556   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1557     // Add as immediates when possible.  Null MCExpr = 0.
1558     if (!Expr)
1559       Inst.addOperand(MCOperand::createImm(0));
1560     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1561       Inst.addOperand(MCOperand::createImm(CE->getValue()));
1562     else
1563       Inst.addOperand(MCOperand::createExpr(Expr));
1564   }
1565 
1566   void addRegOperands(MCInst &Inst, unsigned N) const {
1567     assert(N == 1 && "Invalid number of operands!");
1568     Inst.addOperand(MCOperand::createReg(getReg()));
1569   }
1570 
1571   void addMatrixOperands(MCInst &Inst, unsigned N) const {
1572     assert(N == 1 && "Invalid number of operands!");
1573     Inst.addOperand(MCOperand::createReg(getMatrixReg()));
1574   }
1575 
1576   void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
1577     assert(N == 1 && "Invalid number of operands!");
1578     assert(
1579         AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg()));
1580 
1581     const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1582     uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister(
1583         RI->getEncodingValue(getReg()));
1584 
1585     Inst.addOperand(MCOperand::createReg(Reg));
1586   }
1587 
1588   void addGPR64as32Operands(MCInst &Inst, unsigned N) const {
1589     assert(N == 1 && "Invalid number of operands!");
1590     assert(
1591         AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(getReg()));
1592 
1593     const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1594     uint32_t Reg = RI->getRegClass(AArch64::GPR64RegClassID).getRegister(
1595         RI->getEncodingValue(getReg()));
1596 
1597     Inst.addOperand(MCOperand::createReg(Reg));
1598   }
1599 
1600   template <int Width>
1601   void addFPRasZPRRegOperands(MCInst &Inst, unsigned N) const {
1602     unsigned Base;
1603     switch (Width) {
1604     case 8:   Base = AArch64::B0; break;
1605     case 16:  Base = AArch64::H0; break;
1606     case 32:  Base = AArch64::S0; break;
1607     case 64:  Base = AArch64::D0; break;
1608     case 128: Base = AArch64::Q0; break;
1609     default:
1610       llvm_unreachable("Unsupported width");
1611     }
1612     Inst.addOperand(MCOperand::createReg(AArch64::Z0 + getReg() - Base));
1613   }
1614 
1615   void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
1616     assert(N == 1 && "Invalid number of operands!");
1617     assert(
1618         AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1619     Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0));
1620   }
1621 
1622   void addVectorReg128Operands(MCInst &Inst, unsigned N) const {
1623     assert(N == 1 && "Invalid number of operands!");
1624     assert(
1625         AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1626     Inst.addOperand(MCOperand::createReg(getReg()));
1627   }
1628 
1629   void addVectorRegLoOperands(MCInst &Inst, unsigned N) const {
1630     assert(N == 1 && "Invalid number of operands!");
1631     Inst.addOperand(MCOperand::createReg(getReg()));
1632   }
1633 
1634   enum VecListIndexType {
1635     VecListIdx_DReg = 0,
1636     VecListIdx_QReg = 1,
1637     VecListIdx_ZReg = 2,
1638   };
1639 
1640   template <VecListIndexType RegTy, unsigned NumRegs>
1641   void addVectorListOperands(MCInst &Inst, unsigned N) const {
1642     assert(N == 1 && "Invalid number of operands!");
1643     static const unsigned FirstRegs[][5] = {
1644       /* DReg */ { AArch64::Q0,
1645                    AArch64::D0,       AArch64::D0_D1,
1646                    AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1647       /* QReg */ { AArch64::Q0,
1648                    AArch64::Q0,       AArch64::Q0_Q1,
1649                    AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1650       /* ZReg */ { AArch64::Z0,
1651                    AArch64::Z0,       AArch64::Z0_Z1,
1652                    AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 }
1653     };
1654 
1655     assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1656            " NumRegs must be <= 4 for ZRegs");
1657 
1658     unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1659     Inst.addOperand(MCOperand::createReg(FirstReg + getVectorListStart() -
1660                                          FirstRegs[(unsigned)RegTy][0]));
1661   }
1662 
1663   void addMatrixTileListOperands(MCInst &Inst, unsigned N) const {
1664     assert(N == 1 && "Invalid number of operands!");
1665     unsigned RegMask = getMatrixTileListRegMask();
1666     assert(RegMask <= 0xFF && "Invalid mask!");
1667     Inst.addOperand(MCOperand::createImm(RegMask));
1668   }
1669 
1670   void addVectorIndexOperands(MCInst &Inst, unsigned N) const {
1671     assert(N == 1 && "Invalid number of operands!");
1672     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1673   }
1674 
1675   template <unsigned ImmIs0, unsigned ImmIs1>
1676   void addExactFPImmOperands(MCInst &Inst, unsigned N) const {
1677     assert(N == 1 && "Invalid number of operands!");
1678     assert(bool(isExactFPImm<ImmIs0, ImmIs1>()) && "Invalid operand");
1679     Inst.addOperand(MCOperand::createImm(bool(isExactFPImm<ImmIs1>())));
1680   }
1681 
1682   void addImmOperands(MCInst &Inst, unsigned N) const {
1683     assert(N == 1 && "Invalid number of operands!");
1684     // If this is a pageoff symrefexpr with an addend, adjust the addend
1685     // to be only the page-offset portion. Otherwise, just add the expr
1686     // as-is.
1687     addExpr(Inst, getImm());
1688   }
1689 
1690   template <int Shift>
1691   void addImmWithOptionalShiftOperands(MCInst &Inst, unsigned N) const {
1692     assert(N == 2 && "Invalid number of operands!");
1693     if (auto ShiftedVal = getShiftedVal<Shift>()) {
1694       Inst.addOperand(MCOperand::createImm(ShiftedVal->first));
1695       Inst.addOperand(MCOperand::createImm(ShiftedVal->second));
1696     } else if (isShiftedImm()) {
1697       addExpr(Inst, getShiftedImmVal());
1698       Inst.addOperand(MCOperand::createImm(getShiftedImmShift()));
1699     } else {
1700       addExpr(Inst, getImm());
1701       Inst.addOperand(MCOperand::createImm(0));
1702     }
1703   }
1704 
1705   template <int Shift>
1706   void addImmNegWithOptionalShiftOperands(MCInst &Inst, unsigned N) const {
1707     assert(N == 2 && "Invalid number of operands!");
1708     if (auto ShiftedVal = getShiftedVal<Shift>()) {
1709       Inst.addOperand(MCOperand::createImm(-ShiftedVal->first));
1710       Inst.addOperand(MCOperand::createImm(ShiftedVal->second));
1711     } else
1712       llvm_unreachable("Not a shifted negative immediate");
1713   }
1714 
1715   void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1716     assert(N == 1 && "Invalid number of operands!");
1717     Inst.addOperand(MCOperand::createImm(getCondCode()));
1718   }
1719 
1720   void addAdrpLabelOperands(MCInst &Inst, unsigned N) const {
1721     assert(N == 1 && "Invalid number of operands!");
1722     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1723     if (!MCE)
1724       addExpr(Inst, getImm());
1725     else
1726       Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12));
1727   }
1728 
1729   void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1730     addImmOperands(Inst, N);
1731   }
1732 
1733   template<int Scale>
1734   void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1735     assert(N == 1 && "Invalid number of operands!");
1736     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1737 
1738     if (!MCE) {
1739       Inst.addOperand(MCOperand::createExpr(getImm()));
1740       return;
1741     }
1742     Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
1743   }
1744 
1745   void addUImm6Operands(MCInst &Inst, unsigned N) const {
1746     assert(N == 1 && "Invalid number of operands!");
1747     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1748     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1749   }
1750 
1751   template <int Scale>
1752   void addImmScaledOperands(MCInst &Inst, unsigned N) const {
1753     assert(N == 1 && "Invalid number of operands!");
1754     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1755     Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
1756   }
1757 
1758   template <typename T>
1759   void addLogicalImmOperands(MCInst &Inst, unsigned N) const {
1760     assert(N == 1 && "Invalid number of operands!");
1761     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1762     std::make_unsigned_t<T> Val = MCE->getValue();
1763     uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
1764     Inst.addOperand(MCOperand::createImm(encoding));
1765   }
1766 
1767   template <typename T>
1768   void addLogicalImmNotOperands(MCInst &Inst, unsigned N) const {
1769     assert(N == 1 && "Invalid number of operands!");
1770     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1771     std::make_unsigned_t<T> Val = ~MCE->getValue();
1772     uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
1773     Inst.addOperand(MCOperand::createImm(encoding));
1774   }
1775 
1776   void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const {
1777     assert(N == 1 && "Invalid number of operands!");
1778     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1779     uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
1780     Inst.addOperand(MCOperand::createImm(encoding));
1781   }
1782 
1783   void addBranchTarget26Operands(MCInst &Inst, unsigned N) const {
1784     // Branch operands don't encode the low bits, so shift them off
1785     // here. If it's a label, however, just put it on directly as there's
1786     // not enough information now to do anything.
1787     assert(N == 1 && "Invalid number of operands!");
1788     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1789     if (!MCE) {
1790       addExpr(Inst, getImm());
1791       return;
1792     }
1793     assert(MCE && "Invalid constant immediate operand!");
1794     Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1795   }
1796 
1797   void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const {
1798     // Branch operands don't encode the low bits, so shift them off
1799     // here. If it's a label, however, just put it on directly as there's
1800     // not enough information now to do anything.
1801     assert(N == 1 && "Invalid number of operands!");
1802     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1803     if (!MCE) {
1804       addExpr(Inst, getImm());
1805       return;
1806     }
1807     assert(MCE && "Invalid constant immediate operand!");
1808     Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1809   }
1810 
1811   void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
1812     // Branch operands don't encode the low bits, so shift them off
1813     // here. If it's a label, however, just put it on directly as there's
1814     // not enough information now to do anything.
1815     assert(N == 1 && "Invalid number of operands!");
1816     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1817     if (!MCE) {
1818       addExpr(Inst, getImm());
1819       return;
1820     }
1821     assert(MCE && "Invalid constant immediate operand!");
1822     Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1823   }
1824 
1825   void addFPImmOperands(MCInst &Inst, unsigned N) const {
1826     assert(N == 1 && "Invalid number of operands!");
1827     Inst.addOperand(MCOperand::createImm(
1828         AArch64_AM::getFP64Imm(getFPImm().bitcastToAPInt())));
1829   }
1830 
1831   void addBarrierOperands(MCInst &Inst, unsigned N) const {
1832     assert(N == 1 && "Invalid number of operands!");
1833     Inst.addOperand(MCOperand::createImm(getBarrier()));
1834   }
1835 
1836   void addBarriernXSOperands(MCInst &Inst, unsigned N) const {
1837     assert(N == 1 && "Invalid number of operands!");
1838     Inst.addOperand(MCOperand::createImm(getBarrier()));
1839   }
1840 
1841   void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1842     assert(N == 1 && "Invalid number of operands!");
1843 
1844     Inst.addOperand(MCOperand::createImm(SysReg.MRSReg));
1845   }
1846 
1847   void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1848     assert(N == 1 && "Invalid number of operands!");
1849 
1850     Inst.addOperand(MCOperand::createImm(SysReg.MSRReg));
1851   }
1852 
1853   void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst, unsigned N) const {
1854     assert(N == 1 && "Invalid number of operands!");
1855 
1856     Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1857   }
1858 
1859   void addSVCROperands(MCInst &Inst, unsigned N) const {
1860     assert(N == 1 && "Invalid number of operands!");
1861 
1862     Inst.addOperand(MCOperand::createImm(SVCR.PStateField));
1863   }
1864 
1865   void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const {
1866     assert(N == 1 && "Invalid number of operands!");
1867 
1868     Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1869   }
1870 
1871   void addSysCROperands(MCInst &Inst, unsigned N) const {
1872     assert(N == 1 && "Invalid number of operands!");
1873     Inst.addOperand(MCOperand::createImm(getSysCR()));
1874   }
1875 
1876   void addPrefetchOperands(MCInst &Inst, unsigned N) const {
1877     assert(N == 1 && "Invalid number of operands!");
1878     Inst.addOperand(MCOperand::createImm(getPrefetch()));
1879   }
1880 
1881   void addPSBHintOperands(MCInst &Inst, unsigned N) const {
1882     assert(N == 1 && "Invalid number of operands!");
1883     Inst.addOperand(MCOperand::createImm(getPSBHint()));
1884   }
1885 
1886   void addBTIHintOperands(MCInst &Inst, unsigned N) const {
1887     assert(N == 1 && "Invalid number of operands!");
1888     Inst.addOperand(MCOperand::createImm(getBTIHint()));
1889   }
1890 
1891   void addShifterOperands(MCInst &Inst, unsigned N) const {
1892     assert(N == 1 && "Invalid number of operands!");
1893     unsigned Imm =
1894         AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
1895     Inst.addOperand(MCOperand::createImm(Imm));
1896   }
1897 
1898   void addExtendOperands(MCInst &Inst, unsigned N) const {
1899     assert(N == 1 && "Invalid number of operands!");
1900     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1901     if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW;
1902     unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1903     Inst.addOperand(MCOperand::createImm(Imm));
1904   }
1905 
1906   void addExtend64Operands(MCInst &Inst, unsigned N) const {
1907     assert(N == 1 && "Invalid number of operands!");
1908     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1909     if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX;
1910     unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1911     Inst.addOperand(MCOperand::createImm(Imm));
1912   }
1913 
1914   void addMemExtendOperands(MCInst &Inst, unsigned N) const {
1915     assert(N == 2 && "Invalid number of operands!");
1916     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1917     bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1918     Inst.addOperand(MCOperand::createImm(IsSigned));
1919     Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0));
1920   }
1921 
1922   // For 8-bit load/store instructions with a register offset, both the
1923   // "DoShift" and "NoShift" variants have a shift of 0. Because of this,
1924   // they're disambiguated by whether the shift was explicit or implicit rather
1925   // than its size.
1926   void addMemExtend8Operands(MCInst &Inst, unsigned N) const {
1927     assert(N == 2 && "Invalid number of operands!");
1928     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1929     bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1930     Inst.addOperand(MCOperand::createImm(IsSigned));
1931     Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount()));
1932   }
1933 
1934   template<int Shift>
1935   void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const {
1936     assert(N == 1 && "Invalid number of operands!");
1937 
1938     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1939     if (CE) {
1940       uint64_t Value = CE->getValue();
1941       Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff));
1942     } else {
1943       addExpr(Inst, getImm());
1944     }
1945   }
1946 
1947   template<int Shift>
1948   void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const {
1949     assert(N == 1 && "Invalid number of operands!");
1950 
1951     const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1952     uint64_t Value = CE->getValue();
1953     Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff));
1954   }
1955 
1956   void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
1957     assert(N == 1 && "Invalid number of operands!");
1958     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1959     Inst.addOperand(MCOperand::createImm(MCE->getValue() / 90));
1960   }
1961 
1962   void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
1963     assert(N == 1 && "Invalid number of operands!");
1964     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1965     Inst.addOperand(MCOperand::createImm((MCE->getValue() - 90) / 180));
1966   }
1967 
1968   void print(raw_ostream &OS) const override;
1969 
1970   static std::unique_ptr<AArch64Operand>
1971   CreateToken(StringRef Str, SMLoc S, MCContext &Ctx, bool IsSuffix = false) {
1972     auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
1973     Op->Tok.Data = Str.data();
1974     Op->Tok.Length = Str.size();
1975     Op->Tok.IsSuffix = IsSuffix;
1976     Op->StartLoc = S;
1977     Op->EndLoc = S;
1978     return Op;
1979   }
1980 
1981   static std::unique_ptr<AArch64Operand>
1982   CreateReg(unsigned RegNum, RegKind Kind, SMLoc S, SMLoc E, MCContext &Ctx,
1983             RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
1984             AArch64_AM::ShiftExtendType ExtTy = AArch64_AM::LSL,
1985             unsigned ShiftAmount = 0,
1986             unsigned HasExplicitAmount = false) {
1987     auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
1988     Op->Reg.RegNum = RegNum;
1989     Op->Reg.Kind = Kind;
1990     Op->Reg.ElementWidth = 0;
1991     Op->Reg.EqualityTy = EqTy;
1992     Op->Reg.ShiftExtend.Type = ExtTy;
1993     Op->Reg.ShiftExtend.Amount = ShiftAmount;
1994     Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1995     Op->StartLoc = S;
1996     Op->EndLoc = E;
1997     return Op;
1998   }
1999 
2000   static std::unique_ptr<AArch64Operand>
2001   CreateVectorReg(unsigned RegNum, RegKind Kind, unsigned ElementWidth,
2002                   SMLoc S, SMLoc E, MCContext &Ctx,
2003                   AArch64_AM::ShiftExtendType ExtTy = AArch64_AM::LSL,
2004                   unsigned ShiftAmount = 0,
2005                   unsigned HasExplicitAmount = false) {
2006     assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2007             Kind == RegKind::SVEPredicateVector) &&
2008            "Invalid vector kind");
2009     auto Op = CreateReg(RegNum, Kind, S, E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2010                         HasExplicitAmount);
2011     Op->Reg.ElementWidth = ElementWidth;
2012     return Op;
2013   }
2014 
2015   static std::unique_ptr<AArch64Operand>
2016   CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements,
2017                    unsigned ElementWidth, RegKind RegisterKind, SMLoc S, SMLoc E,
2018                    MCContext &Ctx) {
2019     auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2020     Op->VectorList.RegNum = RegNum;
2021     Op->VectorList.Count = Count;
2022     Op->VectorList.NumElements = NumElements;
2023     Op->VectorList.ElementWidth = ElementWidth;
2024     Op->VectorList.RegisterKind = RegisterKind;
2025     Op->StartLoc = S;
2026     Op->EndLoc = E;
2027     return Op;
2028   }
2029 
2030   static std::unique_ptr<AArch64Operand>
2031   CreateVectorIndex(int Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
2032     auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2033     Op->VectorIndex.Val = Idx;
2034     Op->StartLoc = S;
2035     Op->EndLoc = E;
2036     return Op;
2037   }
2038 
2039   static std::unique_ptr<AArch64Operand>
2040   CreateMatrixTileList(unsigned RegMask, SMLoc S, SMLoc E, MCContext &Ctx) {
2041     auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2042     Op->MatrixTileList.RegMask = RegMask;
2043     Op->StartLoc = S;
2044     Op->EndLoc = E;
2045     return Op;
2046   }
2047 
2048   static void ComputeRegsForAlias(unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2049                                   const unsigned ElementWidth) {
2050     static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2051         RegMap = {
2052             {{0, AArch64::ZAB0},
2053              {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2054               AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2055             {{8, AArch64::ZAB0},
2056              {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2057               AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2058             {{16, AArch64::ZAH0},
2059              {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2060             {{16, AArch64::ZAH1},
2061              {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2062             {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2063             {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2064             {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2065             {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2066         };
2067 
2068     if (ElementWidth == 64)
2069       OutRegs.insert(Reg);
2070     else {
2071       std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth, Reg)];
2072       assert(!Regs.empty() && "Invalid tile or element width!");
2073       for (auto OutReg : Regs)
2074         OutRegs.insert(OutReg);
2075     }
2076   }
2077 
2078   static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S,
2079                                                    SMLoc E, MCContext &Ctx) {
2080     auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2081     Op->Imm.Val = Val;
2082     Op->StartLoc = S;
2083     Op->EndLoc = E;
2084     return Op;
2085   }
2086 
2087   static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val,
2088                                                           unsigned ShiftAmount,
2089                                                           SMLoc S, SMLoc E,
2090                                                           MCContext &Ctx) {
2091     auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2092     Op->ShiftedImm .Val = Val;
2093     Op->ShiftedImm.ShiftAmount = ShiftAmount;
2094     Op->StartLoc = S;
2095     Op->EndLoc = E;
2096     return Op;
2097   }
2098 
2099   static std::unique_ptr<AArch64Operand>
2100   CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
2101     auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2102     Op->CondCode.Code = Code;
2103     Op->StartLoc = S;
2104     Op->EndLoc = E;
2105     return Op;
2106   }
2107 
2108   static std::unique_ptr<AArch64Operand>
2109   CreateFPImm(APFloat Val, bool IsExact, SMLoc S, MCContext &Ctx) {
2110     auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2111     Op->FPImm.Val = Val.bitcastToAPInt().getSExtValue();
2112     Op->FPImm.IsExact = IsExact;
2113     Op->StartLoc = S;
2114     Op->EndLoc = S;
2115     return Op;
2116   }
2117 
2118   static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val,
2119                                                        StringRef Str,
2120                                                        SMLoc S,
2121                                                        MCContext &Ctx,
2122                                                        bool HasnXSModifier) {
2123     auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2124     Op->Barrier.Val = Val;
2125     Op->Barrier.Data = Str.data();
2126     Op->Barrier.Length = Str.size();
2127     Op->Barrier.HasnXSModifier = HasnXSModifier;
2128     Op->StartLoc = S;
2129     Op->EndLoc = S;
2130     return Op;
2131   }
2132 
2133   static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2134                                                       uint32_t MRSReg,
2135                                                       uint32_t MSRReg,
2136                                                       uint32_t PStateField,
2137                                                       MCContext &Ctx) {
2138     auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2139     Op->SysReg.Data = Str.data();
2140     Op->SysReg.Length = Str.size();
2141     Op->SysReg.MRSReg = MRSReg;
2142     Op->SysReg.MSRReg = MSRReg;
2143     Op->SysReg.PStateField = PStateField;
2144     Op->StartLoc = S;
2145     Op->EndLoc = S;
2146     return Op;
2147   }
2148 
2149   static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
2150                                                      SMLoc E, MCContext &Ctx) {
2151     auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2152     Op->SysCRImm.Val = Val;
2153     Op->StartLoc = S;
2154     Op->EndLoc = E;
2155     return Op;
2156   }
2157 
2158   static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val,
2159                                                         StringRef Str,
2160                                                         SMLoc S,
2161                                                         MCContext &Ctx) {
2162     auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2163     Op->Prefetch.Val = Val;
2164     Op->Barrier.Data = Str.data();
2165     Op->Barrier.Length = Str.size();
2166     Op->StartLoc = S;
2167     Op->EndLoc = S;
2168     return Op;
2169   }
2170 
2171   static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val,
2172                                                        StringRef Str,
2173                                                        SMLoc S,
2174                                                        MCContext &Ctx) {
2175     auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2176     Op->PSBHint.Val = Val;
2177     Op->PSBHint.Data = Str.data();
2178     Op->PSBHint.Length = Str.size();
2179     Op->StartLoc = S;
2180     Op->EndLoc = S;
2181     return Op;
2182   }
2183 
2184   static std::unique_ptr<AArch64Operand> CreateBTIHint(unsigned Val,
2185                                                        StringRef Str,
2186                                                        SMLoc S,
2187                                                        MCContext &Ctx) {
2188     auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2189     Op->BTIHint.Val = Val | 32;
2190     Op->BTIHint.Data = Str.data();
2191     Op->BTIHint.Length = Str.size();
2192     Op->StartLoc = S;
2193     Op->EndLoc = S;
2194     return Op;
2195   }
2196 
2197   static std::unique_ptr<AArch64Operand>
2198   CreateMatrixRegister(unsigned RegNum, unsigned ElementWidth, MatrixKind Kind,
2199                        SMLoc S, SMLoc E, MCContext &Ctx) {
2200     auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2201     Op->MatrixReg.RegNum = RegNum;
2202     Op->MatrixReg.ElementWidth = ElementWidth;
2203     Op->MatrixReg.Kind = Kind;
2204     Op->StartLoc = S;
2205     Op->EndLoc = E;
2206     return Op;
2207   }
2208 
2209   static std::unique_ptr<AArch64Operand>
2210   CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2211     auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2212     Op->SVCR.PStateField = PStateField;
2213     Op->SVCR.Data = Str.data();
2214     Op->SVCR.Length = Str.size();
2215     Op->StartLoc = S;
2216     Op->EndLoc = S;
2217     return Op;
2218   }
2219 
2220   static std::unique_ptr<AArch64Operand>
2221   CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
2222                     bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
2223     auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2224     Op->ShiftExtend.Type = ShOp;
2225     Op->ShiftExtend.Amount = Val;
2226     Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2227     Op->StartLoc = S;
2228     Op->EndLoc = E;
2229     return Op;
2230   }
2231 };
2232 
2233 } // end anonymous namespace.
2234 
2235 void AArch64Operand::print(raw_ostream &OS) const {
2236   switch (Kind) {
2237   case k_FPImm:
2238     OS << "<fpimm " << getFPImm().bitcastToAPInt().getZExtValue();
2239     if (!getFPImmIsExact())
2240       OS << " (inexact)";
2241     OS << ">";
2242     break;
2243   case k_Barrier: {
2244     StringRef Name = getBarrierName();
2245     if (!Name.empty())
2246       OS << "<barrier " << Name << ">";
2247     else
2248       OS << "<barrier invalid #" << getBarrier() << ">";
2249     break;
2250   }
2251   case k_Immediate:
2252     OS << *getImm();
2253     break;
2254   case k_ShiftedImm: {
2255     unsigned Shift = getShiftedImmShift();
2256     OS << "<shiftedimm ";
2257     OS << *getShiftedImmVal();
2258     OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
2259     break;
2260   }
2261   case k_CondCode:
2262     OS << "<condcode " << getCondCode() << ">";
2263     break;
2264   case k_VectorList: {
2265     OS << "<vectorlist ";
2266     unsigned Reg = getVectorListStart();
2267     for (unsigned i = 0, e = getVectorListCount(); i != e; ++i)
2268       OS << Reg + i << " ";
2269     OS << ">";
2270     break;
2271   }
2272   case k_VectorIndex:
2273     OS << "<vectorindex " << getVectorIndex() << ">";
2274     break;
2275   case k_SysReg:
2276     OS << "<sysreg: " << getSysReg() << '>';
2277     break;
2278   case k_Token:
2279     OS << "'" << getToken() << "'";
2280     break;
2281   case k_SysCR:
2282     OS << "c" << getSysCR();
2283     break;
2284   case k_Prefetch: {
2285     StringRef Name = getPrefetchName();
2286     if (!Name.empty())
2287       OS << "<prfop " << Name << ">";
2288     else
2289       OS << "<prfop invalid #" << getPrefetch() << ">";
2290     break;
2291   }
2292   case k_PSBHint:
2293     OS << getPSBHintName();
2294     break;
2295   case k_BTIHint:
2296     OS << getBTIHintName();
2297     break;
2298   case k_MatrixRegister:
2299     OS << "<matrix " << getMatrixReg() << ">";
2300     break;
2301   case k_MatrixTileList: {
2302     OS << "<matrixlist ";
2303     unsigned RegMask = getMatrixTileListRegMask();
2304     unsigned MaxBits = 8;
2305     for (unsigned I = MaxBits; I > 0; --I)
2306       OS << ((RegMask & (1 << (I - 1))) >> (I - 1));
2307     OS << '>';
2308     break;
2309   }
2310   case k_SVCR: {
2311     OS << getSVCR();
2312     break;
2313   }
2314   case k_Register:
2315     OS << "<register " << getReg() << ">";
2316     if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2317       break;
2318     LLVM_FALLTHROUGH;
2319   case k_ShiftExtend:
2320     OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
2321        << getShiftExtendAmount();
2322     if (!hasShiftExtendAmount())
2323       OS << "<imp>";
2324     OS << '>';
2325     break;
2326   }
2327 }
2328 
2329 /// @name Auto-generated Match Functions
2330 /// {
2331 
2332 static unsigned MatchRegisterName(StringRef Name);
2333 
2334 /// }
2335 
2336 static unsigned MatchNeonVectorRegName(StringRef Name) {
2337   return StringSwitch<unsigned>(Name.lower())
2338       .Case("v0", AArch64::Q0)
2339       .Case("v1", AArch64::Q1)
2340       .Case("v2", AArch64::Q2)
2341       .Case("v3", AArch64::Q3)
2342       .Case("v4", AArch64::Q4)
2343       .Case("v5", AArch64::Q5)
2344       .Case("v6", AArch64::Q6)
2345       .Case("v7", AArch64::Q7)
2346       .Case("v8", AArch64::Q8)
2347       .Case("v9", AArch64::Q9)
2348       .Case("v10", AArch64::Q10)
2349       .Case("v11", AArch64::Q11)
2350       .Case("v12", AArch64::Q12)
2351       .Case("v13", AArch64::Q13)
2352       .Case("v14", AArch64::Q14)
2353       .Case("v15", AArch64::Q15)
2354       .Case("v16", AArch64::Q16)
2355       .Case("v17", AArch64::Q17)
2356       .Case("v18", AArch64::Q18)
2357       .Case("v19", AArch64::Q19)
2358       .Case("v20", AArch64::Q20)
2359       .Case("v21", AArch64::Q21)
2360       .Case("v22", AArch64::Q22)
2361       .Case("v23", AArch64::Q23)
2362       .Case("v24", AArch64::Q24)
2363       .Case("v25", AArch64::Q25)
2364       .Case("v26", AArch64::Q26)
2365       .Case("v27", AArch64::Q27)
2366       .Case("v28", AArch64::Q28)
2367       .Case("v29", AArch64::Q29)
2368       .Case("v30", AArch64::Q30)
2369       .Case("v31", AArch64::Q31)
2370       .Default(0);
2371 }
2372 
2373 /// Returns an optional pair of (#elements, element-width) if Suffix
2374 /// is a valid vector kind. Where the number of elements in a vector
2375 /// or the vector width is implicit or explicitly unknown (but still a
2376 /// valid suffix kind), 0 is used.
2377 static Optional<std::pair<int, int>> parseVectorKind(StringRef Suffix,
2378                                                      RegKind VectorKind) {
2379   std::pair<int, int> Res = {-1, -1};
2380 
2381   switch (VectorKind) {
2382   case RegKind::NeonVector:
2383     Res =
2384         StringSwitch<std::pair<int, int>>(Suffix.lower())
2385             .Case("", {0, 0})
2386             .Case(".1d", {1, 64})
2387             .Case(".1q", {1, 128})
2388             // '.2h' needed for fp16 scalar pairwise reductions
2389             .Case(".2h", {2, 16})
2390             .Case(".2s", {2, 32})
2391             .Case(".2d", {2, 64})
2392             // '.4b' is another special case for the ARMv8.2a dot product
2393             // operand
2394             .Case(".4b", {4, 8})
2395             .Case(".4h", {4, 16})
2396             .Case(".4s", {4, 32})
2397             .Case(".8b", {8, 8})
2398             .Case(".8h", {8, 16})
2399             .Case(".16b", {16, 8})
2400             // Accept the width neutral ones, too, for verbose syntax. If those
2401             // aren't used in the right places, the token operand won't match so
2402             // all will work out.
2403             .Case(".b", {0, 8})
2404             .Case(".h", {0, 16})
2405             .Case(".s", {0, 32})
2406             .Case(".d", {0, 64})
2407             .Default({-1, -1});
2408     break;
2409   case RegKind::SVEPredicateVector:
2410   case RegKind::SVEDataVector:
2411   case RegKind::Matrix:
2412     Res = StringSwitch<std::pair<int, int>>(Suffix.lower())
2413               .Case("", {0, 0})
2414               .Case(".b", {0, 8})
2415               .Case(".h", {0, 16})
2416               .Case(".s", {0, 32})
2417               .Case(".d", {0, 64})
2418               .Case(".q", {0, 128})
2419               .Default({-1, -1});
2420     break;
2421   default:
2422     llvm_unreachable("Unsupported RegKind");
2423   }
2424 
2425   if (Res == std::make_pair(-1, -1))
2426     return Optional<std::pair<int, int>>();
2427 
2428   return Optional<std::pair<int, int>>(Res);
2429 }
2430 
2431 static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind) {
2432   return parseVectorKind(Suffix, VectorKind).hasValue();
2433 }
2434 
2435 static unsigned matchSVEDataVectorRegName(StringRef Name) {
2436   return StringSwitch<unsigned>(Name.lower())
2437       .Case("z0", AArch64::Z0)
2438       .Case("z1", AArch64::Z1)
2439       .Case("z2", AArch64::Z2)
2440       .Case("z3", AArch64::Z3)
2441       .Case("z4", AArch64::Z4)
2442       .Case("z5", AArch64::Z5)
2443       .Case("z6", AArch64::Z6)
2444       .Case("z7", AArch64::Z7)
2445       .Case("z8", AArch64::Z8)
2446       .Case("z9", AArch64::Z9)
2447       .Case("z10", AArch64::Z10)
2448       .Case("z11", AArch64::Z11)
2449       .Case("z12", AArch64::Z12)
2450       .Case("z13", AArch64::Z13)
2451       .Case("z14", AArch64::Z14)
2452       .Case("z15", AArch64::Z15)
2453       .Case("z16", AArch64::Z16)
2454       .Case("z17", AArch64::Z17)
2455       .Case("z18", AArch64::Z18)
2456       .Case("z19", AArch64::Z19)
2457       .Case("z20", AArch64::Z20)
2458       .Case("z21", AArch64::Z21)
2459       .Case("z22", AArch64::Z22)
2460       .Case("z23", AArch64::Z23)
2461       .Case("z24", AArch64::Z24)
2462       .Case("z25", AArch64::Z25)
2463       .Case("z26", AArch64::Z26)
2464       .Case("z27", AArch64::Z27)
2465       .Case("z28", AArch64::Z28)
2466       .Case("z29", AArch64::Z29)
2467       .Case("z30", AArch64::Z30)
2468       .Case("z31", AArch64::Z31)
2469       .Default(0);
2470 }
2471 
2472 static unsigned matchSVEPredicateVectorRegName(StringRef Name) {
2473   return StringSwitch<unsigned>(Name.lower())
2474       .Case("p0", AArch64::P0)
2475       .Case("p1", AArch64::P1)
2476       .Case("p2", AArch64::P2)
2477       .Case("p3", AArch64::P3)
2478       .Case("p4", AArch64::P4)
2479       .Case("p5", AArch64::P5)
2480       .Case("p6", AArch64::P6)
2481       .Case("p7", AArch64::P7)
2482       .Case("p8", AArch64::P8)
2483       .Case("p9", AArch64::P9)
2484       .Case("p10", AArch64::P10)
2485       .Case("p11", AArch64::P11)
2486       .Case("p12", AArch64::P12)
2487       .Case("p13", AArch64::P13)
2488       .Case("p14", AArch64::P14)
2489       .Case("p15", AArch64::P15)
2490       .Default(0);
2491 }
2492 
2493 static unsigned matchMatrixTileListRegName(StringRef Name) {
2494   return StringSwitch<unsigned>(Name.lower())
2495       .Case("za0.d", AArch64::ZAD0)
2496       .Case("za1.d", AArch64::ZAD1)
2497       .Case("za2.d", AArch64::ZAD2)
2498       .Case("za3.d", AArch64::ZAD3)
2499       .Case("za4.d", AArch64::ZAD4)
2500       .Case("za5.d", AArch64::ZAD5)
2501       .Case("za6.d", AArch64::ZAD6)
2502       .Case("za7.d", AArch64::ZAD7)
2503       .Case("za0.s", AArch64::ZAS0)
2504       .Case("za1.s", AArch64::ZAS1)
2505       .Case("za2.s", AArch64::ZAS2)
2506       .Case("za3.s", AArch64::ZAS3)
2507       .Case("za0.h", AArch64::ZAH0)
2508       .Case("za1.h", AArch64::ZAH1)
2509       .Case("za0.b", AArch64::ZAB0)
2510       .Default(0);
2511 }
2512 
2513 static unsigned matchMatrixRegName(StringRef Name) {
2514   return StringSwitch<unsigned>(Name.lower())
2515       .Case("za", AArch64::ZA)
2516       .Case("za0.q", AArch64::ZAQ0)
2517       .Case("za1.q", AArch64::ZAQ1)
2518       .Case("za2.q", AArch64::ZAQ2)
2519       .Case("za3.q", AArch64::ZAQ3)
2520       .Case("za4.q", AArch64::ZAQ4)
2521       .Case("za5.q", AArch64::ZAQ5)
2522       .Case("za6.q", AArch64::ZAQ6)
2523       .Case("za7.q", AArch64::ZAQ7)
2524       .Case("za8.q", AArch64::ZAQ8)
2525       .Case("za9.q", AArch64::ZAQ9)
2526       .Case("za10.q", AArch64::ZAQ10)
2527       .Case("za11.q", AArch64::ZAQ11)
2528       .Case("za12.q", AArch64::ZAQ12)
2529       .Case("za13.q", AArch64::ZAQ13)
2530       .Case("za14.q", AArch64::ZAQ14)
2531       .Case("za15.q", AArch64::ZAQ15)
2532       .Case("za0.d", AArch64::ZAD0)
2533       .Case("za1.d", AArch64::ZAD1)
2534       .Case("za2.d", AArch64::ZAD2)
2535       .Case("za3.d", AArch64::ZAD3)
2536       .Case("za4.d", AArch64::ZAD4)
2537       .Case("za5.d", AArch64::ZAD5)
2538       .Case("za6.d", AArch64::ZAD6)
2539       .Case("za7.d", AArch64::ZAD7)
2540       .Case("za0.s", AArch64::ZAS0)
2541       .Case("za1.s", AArch64::ZAS1)
2542       .Case("za2.s", AArch64::ZAS2)
2543       .Case("za3.s", AArch64::ZAS3)
2544       .Case("za0.h", AArch64::ZAH0)
2545       .Case("za1.h", AArch64::ZAH1)
2546       .Case("za0.b", AArch64::ZAB0)
2547       .Case("za0h.q", AArch64::ZAQ0)
2548       .Case("za1h.q", AArch64::ZAQ1)
2549       .Case("za2h.q", AArch64::ZAQ2)
2550       .Case("za3h.q", AArch64::ZAQ3)
2551       .Case("za4h.q", AArch64::ZAQ4)
2552       .Case("za5h.q", AArch64::ZAQ5)
2553       .Case("za6h.q", AArch64::ZAQ6)
2554       .Case("za7h.q", AArch64::ZAQ7)
2555       .Case("za8h.q", AArch64::ZAQ8)
2556       .Case("za9h.q", AArch64::ZAQ9)
2557       .Case("za10h.q", AArch64::ZAQ10)
2558       .Case("za11h.q", AArch64::ZAQ11)
2559       .Case("za12h.q", AArch64::ZAQ12)
2560       .Case("za13h.q", AArch64::ZAQ13)
2561       .Case("za14h.q", AArch64::ZAQ14)
2562       .Case("za15h.q", AArch64::ZAQ15)
2563       .Case("za0h.d", AArch64::ZAD0)
2564       .Case("za1h.d", AArch64::ZAD1)
2565       .Case("za2h.d", AArch64::ZAD2)
2566       .Case("za3h.d", AArch64::ZAD3)
2567       .Case("za4h.d", AArch64::ZAD4)
2568       .Case("za5h.d", AArch64::ZAD5)
2569       .Case("za6h.d", AArch64::ZAD6)
2570       .Case("za7h.d", AArch64::ZAD7)
2571       .Case("za0h.s", AArch64::ZAS0)
2572       .Case("za1h.s", AArch64::ZAS1)
2573       .Case("za2h.s", AArch64::ZAS2)
2574       .Case("za3h.s", AArch64::ZAS3)
2575       .Case("za0h.h", AArch64::ZAH0)
2576       .Case("za1h.h", AArch64::ZAH1)
2577       .Case("za0h.b", AArch64::ZAB0)
2578       .Case("za0v.q", AArch64::ZAQ0)
2579       .Case("za1v.q", AArch64::ZAQ1)
2580       .Case("za2v.q", AArch64::ZAQ2)
2581       .Case("za3v.q", AArch64::ZAQ3)
2582       .Case("za4v.q", AArch64::ZAQ4)
2583       .Case("za5v.q", AArch64::ZAQ5)
2584       .Case("za6v.q", AArch64::ZAQ6)
2585       .Case("za7v.q", AArch64::ZAQ7)
2586       .Case("za8v.q", AArch64::ZAQ8)
2587       .Case("za9v.q", AArch64::ZAQ9)
2588       .Case("za10v.q", AArch64::ZAQ10)
2589       .Case("za11v.q", AArch64::ZAQ11)
2590       .Case("za12v.q", AArch64::ZAQ12)
2591       .Case("za13v.q", AArch64::ZAQ13)
2592       .Case("za14v.q", AArch64::ZAQ14)
2593       .Case("za15v.q", AArch64::ZAQ15)
2594       .Case("za0v.d", AArch64::ZAD0)
2595       .Case("za1v.d", AArch64::ZAD1)
2596       .Case("za2v.d", AArch64::ZAD2)
2597       .Case("za3v.d", AArch64::ZAD3)
2598       .Case("za4v.d", AArch64::ZAD4)
2599       .Case("za5v.d", AArch64::ZAD5)
2600       .Case("za6v.d", AArch64::ZAD6)
2601       .Case("za7v.d", AArch64::ZAD7)
2602       .Case("za0v.s", AArch64::ZAS0)
2603       .Case("za1v.s", AArch64::ZAS1)
2604       .Case("za2v.s", AArch64::ZAS2)
2605       .Case("za3v.s", AArch64::ZAS3)
2606       .Case("za0v.h", AArch64::ZAH0)
2607       .Case("za1v.h", AArch64::ZAH1)
2608       .Case("za0v.b", AArch64::ZAB0)
2609       .Default(0);
2610 }
2611 
2612 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2613                                      SMLoc &EndLoc) {
2614   return tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success;
2615 }
2616 
2617 OperandMatchResultTy AArch64AsmParser::tryParseRegister(unsigned &RegNo,
2618                                                         SMLoc &StartLoc,
2619                                                         SMLoc &EndLoc) {
2620   StartLoc = getLoc();
2621   auto Res = tryParseScalarRegister(RegNo);
2622   EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2623   return Res;
2624 }
2625 
2626 // Matches a register name or register alias previously defined by '.req'
2627 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2628                                                   RegKind Kind) {
2629   unsigned RegNum = 0;
2630   if ((RegNum = matchSVEDataVectorRegName(Name)))
2631     return Kind == RegKind::SVEDataVector ? RegNum : 0;
2632 
2633   if ((RegNum = matchSVEPredicateVectorRegName(Name)))
2634     return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
2635 
2636   if ((RegNum = MatchNeonVectorRegName(Name)))
2637     return Kind == RegKind::NeonVector ? RegNum : 0;
2638 
2639   if ((RegNum = matchMatrixRegName(Name)))
2640     return Kind == RegKind::Matrix ? RegNum : 0;
2641 
2642   // The parsed register must be of RegKind Scalar
2643   if ((RegNum = MatchRegisterName(Name)))
2644     return Kind == RegKind::Scalar ? RegNum : 0;
2645 
2646   if (!RegNum) {
2647     // Handle a few common aliases of registers.
2648     if (auto RegNum = StringSwitch<unsigned>(Name.lower())
2649                     .Case("fp", AArch64::FP)
2650                     .Case("lr",  AArch64::LR)
2651                     .Case("x31", AArch64::XZR)
2652                     .Case("w31", AArch64::WZR)
2653                     .Default(0))
2654       return Kind == RegKind::Scalar ? RegNum : 0;
2655 
2656     // Check for aliases registered via .req. Canonicalize to lower case.
2657     // That's more consistent since register names are case insensitive, and
2658     // it's how the original entry was passed in from MC/MCParser/AsmParser.
2659     auto Entry = RegisterReqs.find(Name.lower());
2660     if (Entry == RegisterReqs.end())
2661       return 0;
2662 
2663     // set RegNum if the match is the right kind of register
2664     if (Kind == Entry->getValue().first)
2665       RegNum = Entry->getValue().second;
2666   }
2667   return RegNum;
2668 }
2669 
2670 /// tryParseScalarRegister - Try to parse a register name. The token must be an
2671 /// Identifier when called, and if it is a register name the token is eaten and
2672 /// the register is added to the operand list.
2673 OperandMatchResultTy
2674 AArch64AsmParser::tryParseScalarRegister(unsigned &RegNum) {
2675   const AsmToken &Tok = getTok();
2676   if (Tok.isNot(AsmToken::Identifier))
2677     return MatchOperand_NoMatch;
2678 
2679   std::string lowerCase = Tok.getString().lower();
2680   unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
2681   if (Reg == 0)
2682     return MatchOperand_NoMatch;
2683 
2684   RegNum = Reg;
2685   Lex(); // Eat identifier token.
2686   return MatchOperand_Success;
2687 }
2688 
2689 /// tryParseSysCROperand - Try to parse a system instruction CR operand name.
2690 OperandMatchResultTy
2691 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
2692   SMLoc S = getLoc();
2693 
2694   if (getTok().isNot(AsmToken::Identifier)) {
2695     Error(S, "Expected cN operand where 0 <= N <= 15");
2696     return MatchOperand_ParseFail;
2697   }
2698 
2699   StringRef Tok = getTok().getIdentifier();
2700   if (Tok[0] != 'c' && Tok[0] != 'C') {
2701     Error(S, "Expected cN operand where 0 <= N <= 15");
2702     return MatchOperand_ParseFail;
2703   }
2704 
2705   uint32_t CRNum;
2706   bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
2707   if (BadNum || CRNum > 15) {
2708     Error(S, "Expected cN operand where 0 <= N <= 15");
2709     return MatchOperand_ParseFail;
2710   }
2711 
2712   Lex(); // Eat identifier token.
2713   Operands.push_back(
2714       AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
2715   return MatchOperand_Success;
2716 }
2717 
2718 /// tryParsePrefetch - Try to parse a prefetch operand.
2719 template <bool IsSVEPrefetch>
2720 OperandMatchResultTy
2721 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
2722   SMLoc S = getLoc();
2723   const AsmToken &Tok = getTok();
2724 
2725   auto LookupByName = [](StringRef N) {
2726     if (IsSVEPrefetch) {
2727       if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(N))
2728         return Optional<unsigned>(Res->Encoding);
2729     } else if (auto Res = AArch64PRFM::lookupPRFMByName(N))
2730       return Optional<unsigned>(Res->Encoding);
2731     return Optional<unsigned>();
2732   };
2733 
2734   auto LookupByEncoding = [](unsigned E) {
2735     if (IsSVEPrefetch) {
2736       if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(E))
2737         return Optional<StringRef>(Res->Name);
2738     } else if (auto Res = AArch64PRFM::lookupPRFMByEncoding(E))
2739       return Optional<StringRef>(Res->Name);
2740     return Optional<StringRef>();
2741   };
2742   unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
2743 
2744   // Either an identifier for named values or a 5-bit immediate.
2745   // Eat optional hash.
2746   if (parseOptionalToken(AsmToken::Hash) ||
2747       Tok.is(AsmToken::Integer)) {
2748     const MCExpr *ImmVal;
2749     if (getParser().parseExpression(ImmVal))
2750       return MatchOperand_ParseFail;
2751 
2752     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2753     if (!MCE) {
2754       TokError("immediate value expected for prefetch operand");
2755       return MatchOperand_ParseFail;
2756     }
2757     unsigned prfop = MCE->getValue();
2758     if (prfop > MaxVal) {
2759       TokError("prefetch operand out of range, [0," + utostr(MaxVal) +
2760                "] expected");
2761       return MatchOperand_ParseFail;
2762     }
2763 
2764     auto PRFM = LookupByEncoding(MCE->getValue());
2765     Operands.push_back(AArch64Operand::CreatePrefetch(
2766         prfop, PRFM.getValueOr(""), S, getContext()));
2767     return MatchOperand_Success;
2768   }
2769 
2770   if (Tok.isNot(AsmToken::Identifier)) {
2771     TokError("prefetch hint expected");
2772     return MatchOperand_ParseFail;
2773   }
2774 
2775   auto PRFM = LookupByName(Tok.getString());
2776   if (!PRFM) {
2777     TokError("prefetch hint expected");
2778     return MatchOperand_ParseFail;
2779   }
2780 
2781   Operands.push_back(AArch64Operand::CreatePrefetch(
2782       *PRFM, Tok.getString(), S, getContext()));
2783   Lex(); // Eat identifier token.
2784   return MatchOperand_Success;
2785 }
2786 
2787 /// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command
2788 OperandMatchResultTy
2789 AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) {
2790   SMLoc S = getLoc();
2791   const AsmToken &Tok = getTok();
2792   if (Tok.isNot(AsmToken::Identifier)) {
2793     TokError("invalid operand for instruction");
2794     return MatchOperand_ParseFail;
2795   }
2796 
2797   auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString());
2798   if (!PSB) {
2799     TokError("invalid operand for instruction");
2800     return MatchOperand_ParseFail;
2801   }
2802 
2803   Operands.push_back(AArch64Operand::CreatePSBHint(
2804       PSB->Encoding, Tok.getString(), S, getContext()));
2805   Lex(); // Eat identifier token.
2806   return MatchOperand_Success;
2807 }
2808 
2809 /// tryParseBTIHint - Try to parse a BTI operand, mapped to Hint command
2810 OperandMatchResultTy
2811 AArch64AsmParser::tryParseBTIHint(OperandVector &Operands) {
2812   SMLoc S = getLoc();
2813   const AsmToken &Tok = getTok();
2814   if (Tok.isNot(AsmToken::Identifier)) {
2815     TokError("invalid operand for instruction");
2816     return MatchOperand_ParseFail;
2817   }
2818 
2819   auto BTI = AArch64BTIHint::lookupBTIByName(Tok.getString());
2820   if (!BTI) {
2821     TokError("invalid operand for instruction");
2822     return MatchOperand_ParseFail;
2823   }
2824 
2825   Operands.push_back(AArch64Operand::CreateBTIHint(
2826       BTI->Encoding, Tok.getString(), S, getContext()));
2827   Lex(); // Eat identifier token.
2828   return MatchOperand_Success;
2829 }
2830 
2831 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2832 /// instruction.
2833 OperandMatchResultTy
2834 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2835   SMLoc S = getLoc();
2836   const MCExpr *Expr = nullptr;
2837 
2838   if (getTok().is(AsmToken::Hash)) {
2839     Lex(); // Eat hash token.
2840   }
2841 
2842   if (parseSymbolicImmVal(Expr))
2843     return MatchOperand_ParseFail;
2844 
2845   AArch64MCExpr::VariantKind ELFRefKind;
2846   MCSymbolRefExpr::VariantKind DarwinRefKind;
2847   int64_t Addend;
2848   if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2849     if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2850         ELFRefKind == AArch64MCExpr::VK_INVALID) {
2851       // No modifier was specified at all; this is the syntax for an ELF basic
2852       // ADRP relocation (unfortunately).
2853       Expr =
2854           AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
2855     } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2856                 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2857                Addend != 0) {
2858       Error(S, "gotpage label reference not allowed an addend");
2859       return MatchOperand_ParseFail;
2860     } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2861                DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2862                DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2863                ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
2864                ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
2865                ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
2866                ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
2867                ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
2868       // The operand must be an @page or @gotpage qualified symbolref.
2869       Error(S, "page or gotpage label reference expected");
2870       return MatchOperand_ParseFail;
2871     }
2872   }
2873 
2874   // We have either a label reference possibly with addend or an immediate. The
2875   // addend is a raw value here. The linker will adjust it to only reference the
2876   // page.
2877   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2878   Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2879 
2880   return MatchOperand_Success;
2881 }
2882 
2883 /// tryParseAdrLabel - Parse and validate a source label for the ADR
2884 /// instruction.
2885 OperandMatchResultTy
2886 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2887   SMLoc S = getLoc();
2888   const MCExpr *Expr = nullptr;
2889 
2890   // Leave anything with a bracket to the default for SVE
2891   if (getTok().is(AsmToken::LBrac))
2892     return MatchOperand_NoMatch;
2893 
2894   if (getTok().is(AsmToken::Hash))
2895     Lex(); // Eat hash token.
2896 
2897   if (parseSymbolicImmVal(Expr))
2898     return MatchOperand_ParseFail;
2899 
2900   AArch64MCExpr::VariantKind ELFRefKind;
2901   MCSymbolRefExpr::VariantKind DarwinRefKind;
2902   int64_t Addend;
2903   if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2904     if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2905         ELFRefKind == AArch64MCExpr::VK_INVALID) {
2906       // No modifier was specified at all; this is the syntax for an ELF basic
2907       // ADR relocation (unfortunately).
2908       Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext());
2909     } else {
2910       Error(S, "unexpected adr label");
2911       return MatchOperand_ParseFail;
2912     }
2913   }
2914 
2915   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2916   Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2917   return MatchOperand_Success;
2918 }
2919 
2920 /// tryParseFPImm - A floating point immediate expression operand.
2921 template<bool AddFPZeroAsLiteral>
2922 OperandMatchResultTy
2923 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
2924   SMLoc S = getLoc();
2925 
2926   bool Hash = parseOptionalToken(AsmToken::Hash);
2927 
2928   // Handle negation, as that still comes through as a separate token.
2929   bool isNegative = parseOptionalToken(AsmToken::Minus);
2930 
2931   const AsmToken &Tok = getTok();
2932   if (!Tok.is(AsmToken::Real) && !Tok.is(AsmToken::Integer)) {
2933     if (!Hash)
2934       return MatchOperand_NoMatch;
2935     TokError("invalid floating point immediate");
2936     return MatchOperand_ParseFail;
2937   }
2938 
2939   // Parse hexadecimal representation.
2940   if (Tok.is(AsmToken::Integer) && Tok.getString().startswith("0x")) {
2941     if (Tok.getIntVal() > 255 || isNegative) {
2942       TokError("encoded floating point value out of range");
2943       return MatchOperand_ParseFail;
2944     }
2945 
2946     APFloat F((double)AArch64_AM::getFPImmFloat(Tok.getIntVal()));
2947     Operands.push_back(
2948         AArch64Operand::CreateFPImm(F, true, S, getContext()));
2949   } else {
2950     // Parse FP representation.
2951     APFloat RealVal(APFloat::IEEEdouble());
2952     auto StatusOrErr =
2953         RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero);
2954     if (errorToBool(StatusOrErr.takeError())) {
2955       TokError("invalid floating point representation");
2956       return MatchOperand_ParseFail;
2957     }
2958 
2959     if (isNegative)
2960       RealVal.changeSign();
2961 
2962     if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
2963       Operands.push_back(AArch64Operand::CreateToken("#0", S, getContext()));
2964       Operands.push_back(AArch64Operand::CreateToken(".0", S, getContext()));
2965     } else
2966       Operands.push_back(AArch64Operand::CreateFPImm(
2967           RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
2968   }
2969 
2970   Lex(); // Eat the token.
2971 
2972   return MatchOperand_Success;
2973 }
2974 
2975 /// tryParseImmWithOptionalShift - Parse immediate operand, optionally with
2976 /// a shift suffix, for example '#1, lsl #12'.
2977 OperandMatchResultTy
2978 AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) {
2979   SMLoc S = getLoc();
2980 
2981   if (getTok().is(AsmToken::Hash))
2982     Lex(); // Eat '#'
2983   else if (getTok().isNot(AsmToken::Integer))
2984     // Operand should start from # or should be integer, emit error otherwise.
2985     return MatchOperand_NoMatch;
2986 
2987   const MCExpr *Imm = nullptr;
2988   if (parseSymbolicImmVal(Imm))
2989     return MatchOperand_ParseFail;
2990   else if (getTok().isNot(AsmToken::Comma)) {
2991     Operands.push_back(
2992         AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
2993     return MatchOperand_Success;
2994   }
2995 
2996   // Eat ','
2997   Lex();
2998 
2999   // The optional operand must be "lsl #N" where N is non-negative.
3000   if (!getTok().is(AsmToken::Identifier) ||
3001       !getTok().getIdentifier().equals_insensitive("lsl")) {
3002     Error(getLoc(), "only 'lsl #+N' valid after immediate");
3003     return MatchOperand_ParseFail;
3004   }
3005 
3006   // Eat 'lsl'
3007   Lex();
3008 
3009   parseOptionalToken(AsmToken::Hash);
3010 
3011   if (getTok().isNot(AsmToken::Integer)) {
3012     Error(getLoc(), "only 'lsl #+N' valid after immediate");
3013     return MatchOperand_ParseFail;
3014   }
3015 
3016   int64_t ShiftAmount = getTok().getIntVal();
3017 
3018   if (ShiftAmount < 0) {
3019     Error(getLoc(), "positive shift amount required");
3020     return MatchOperand_ParseFail;
3021   }
3022   Lex(); // Eat the number
3023 
3024   // Just in case the optional lsl #0 is used for immediates other than zero.
3025   if (ShiftAmount == 0 && Imm != nullptr) {
3026     Operands.push_back(
3027         AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3028     return MatchOperand_Success;
3029   }
3030 
3031   Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3032                                                       getLoc(), getContext()));
3033   return MatchOperand_Success;
3034 }
3035 
3036 /// parseCondCodeString - Parse a Condition Code string.
3037 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
3038   AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
3039                     .Case("eq", AArch64CC::EQ)
3040                     .Case("ne", AArch64CC::NE)
3041                     .Case("cs", AArch64CC::HS)
3042                     .Case("hs", AArch64CC::HS)
3043                     .Case("cc", AArch64CC::LO)
3044                     .Case("lo", AArch64CC::LO)
3045                     .Case("mi", AArch64CC::MI)
3046                     .Case("pl", AArch64CC::PL)
3047                     .Case("vs", AArch64CC::VS)
3048                     .Case("vc", AArch64CC::VC)
3049                     .Case("hi", AArch64CC::HI)
3050                     .Case("ls", AArch64CC::LS)
3051                     .Case("ge", AArch64CC::GE)
3052                     .Case("lt", AArch64CC::LT)
3053                     .Case("gt", AArch64CC::GT)
3054                     .Case("le", AArch64CC::LE)
3055                     .Case("al", AArch64CC::AL)
3056                     .Case("nv", AArch64CC::NV)
3057                     .Default(AArch64CC::Invalid);
3058 
3059   if (CC == AArch64CC::Invalid &&
3060       getSTI().getFeatureBits()[AArch64::FeatureSVE])
3061     CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
3062                     .Case("none",  AArch64CC::EQ)
3063                     .Case("any",   AArch64CC::NE)
3064                     .Case("nlast", AArch64CC::HS)
3065                     .Case("last",  AArch64CC::LO)
3066                     .Case("first", AArch64CC::MI)
3067                     .Case("nfrst", AArch64CC::PL)
3068                     .Case("pmore", AArch64CC::HI)
3069                     .Case("plast", AArch64CC::LS)
3070                     .Case("tcont", AArch64CC::GE)
3071                     .Case("tstop", AArch64CC::LT)
3072                     .Default(AArch64CC::Invalid);
3073 
3074   return CC;
3075 }
3076 
3077 /// parseCondCode - Parse a Condition Code operand.
3078 bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
3079                                      bool invertCondCode) {
3080   SMLoc S = getLoc();
3081   const AsmToken &Tok = getTok();
3082   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3083 
3084   StringRef Cond = Tok.getString();
3085   AArch64CC::CondCode CC = parseCondCodeString(Cond);
3086   if (CC == AArch64CC::Invalid)
3087     return TokError("invalid condition code");
3088   Lex(); // Eat identifier token.
3089 
3090   if (invertCondCode) {
3091     if (CC == AArch64CC::AL || CC == AArch64CC::NV)
3092       return TokError("condition codes AL and NV are invalid for this instruction");
3093     CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
3094   }
3095 
3096   Operands.push_back(
3097       AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
3098   return false;
3099 }
3100 
3101 OperandMatchResultTy
3102 AArch64AsmParser::tryParseSVCR(OperandVector &Operands) {
3103   const AsmToken &Tok = getTok();
3104   SMLoc S = getLoc();
3105 
3106   if (Tok.isNot(AsmToken::Identifier)) {
3107     TokError("invalid operand for instruction");
3108     return MatchOperand_ParseFail;
3109   }
3110 
3111   unsigned PStateImm = -1;
3112   const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.getString());
3113   if (SVCR && SVCR->haveFeatures(getSTI().getFeatureBits()))
3114     PStateImm = SVCR->Encoding;
3115 
3116   Operands.push_back(
3117       AArch64Operand::CreateSVCR(PStateImm, Tok.getString(), S, getContext()));
3118   Lex(); // Eat identifier token.
3119   return MatchOperand_Success;
3120 }
3121 
3122 OperandMatchResultTy
3123 AArch64AsmParser::tryParseMatrixRegister(OperandVector &Operands) {
3124   const AsmToken &Tok = getTok();
3125   SMLoc S = getLoc();
3126 
3127   StringRef Name = Tok.getString();
3128 
3129   if (Name.equals_insensitive("za")) {
3130     Lex(); // eat "za"
3131     Operands.push_back(AArch64Operand::CreateMatrixRegister(
3132         AArch64::ZA, /*ElementWidth=*/0, MatrixKind::Array, S, getLoc(),
3133         getContext()));
3134     if (getLexer().is(AsmToken::LBrac)) {
3135       // There's no comma after matrix operand, so we can parse the next operand
3136       // immediately.
3137       if (parseOperand(Operands, false, false))
3138         return MatchOperand_NoMatch;
3139     }
3140     return MatchOperand_Success;
3141   }
3142 
3143   // Try to parse matrix register.
3144   unsigned Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3145   if (!Reg)
3146     return MatchOperand_NoMatch;
3147 
3148   size_t DotPosition = Name.find('.');
3149   assert(DotPosition != StringRef::npos && "Unexpected register");
3150 
3151   StringRef Head = Name.take_front(DotPosition);
3152   StringRef Tail = Name.drop_front(DotPosition);
3153   StringRef RowOrColumn = Head.take_back();
3154 
3155   MatrixKind Kind = StringSwitch<MatrixKind>(RowOrColumn)
3156                         .Case("h", MatrixKind::Row)
3157                         .Case("v", MatrixKind::Col)
3158                         .Default(MatrixKind::Tile);
3159 
3160   // Next up, parsing the suffix
3161   const auto &KindRes = parseVectorKind(Tail, RegKind::Matrix);
3162   if (!KindRes) {
3163     TokError("Expected the register to be followed by element width suffix");
3164     return MatchOperand_ParseFail;
3165   }
3166   unsigned ElementWidth = KindRes->second;
3167 
3168   Lex();
3169 
3170   Operands.push_back(AArch64Operand::CreateMatrixRegister(
3171       Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3172 
3173   if (getLexer().is(AsmToken::LBrac)) {
3174     // There's no comma after matrix operand, so we can parse the next operand
3175     // immediately.
3176     if (parseOperand(Operands, false, false))
3177       return MatchOperand_NoMatch;
3178   }
3179   return MatchOperand_Success;
3180 }
3181 
3182 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse
3183 /// them if present.
3184 OperandMatchResultTy
3185 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
3186   const AsmToken &Tok = getTok();
3187   std::string LowerID = Tok.getString().lower();
3188   AArch64_AM::ShiftExtendType ShOp =
3189       StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3190           .Case("lsl", AArch64_AM::LSL)
3191           .Case("lsr", AArch64_AM::LSR)
3192           .Case("asr", AArch64_AM::ASR)
3193           .Case("ror", AArch64_AM::ROR)
3194           .Case("msl", AArch64_AM::MSL)
3195           .Case("uxtb", AArch64_AM::UXTB)
3196           .Case("uxth", AArch64_AM::UXTH)
3197           .Case("uxtw", AArch64_AM::UXTW)
3198           .Case("uxtx", AArch64_AM::UXTX)
3199           .Case("sxtb", AArch64_AM::SXTB)
3200           .Case("sxth", AArch64_AM::SXTH)
3201           .Case("sxtw", AArch64_AM::SXTW)
3202           .Case("sxtx", AArch64_AM::SXTX)
3203           .Default(AArch64_AM::InvalidShiftExtend);
3204 
3205   if (ShOp == AArch64_AM::InvalidShiftExtend)
3206     return MatchOperand_NoMatch;
3207 
3208   SMLoc S = Tok.getLoc();
3209   Lex();
3210 
3211   bool Hash = parseOptionalToken(AsmToken::Hash);
3212 
3213   if (!Hash && getLexer().isNot(AsmToken::Integer)) {
3214     if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
3215         ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
3216         ShOp == AArch64_AM::MSL) {
3217       // We expect a number here.
3218       TokError("expected #imm after shift specifier");
3219       return MatchOperand_ParseFail;
3220     }
3221 
3222     // "extend" type operations don't need an immediate, #0 is implicit.
3223     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3224     Operands.push_back(
3225         AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
3226     return MatchOperand_Success;
3227   }
3228 
3229   // Make sure we do actually have a number, identifier or a parenthesized
3230   // expression.
3231   SMLoc E = getLoc();
3232   if (!getTok().is(AsmToken::Integer) && !getTok().is(AsmToken::LParen) &&
3233       !getTok().is(AsmToken::Identifier)) {
3234     Error(E, "expected integer shift amount");
3235     return MatchOperand_ParseFail;
3236   }
3237 
3238   const MCExpr *ImmVal;
3239   if (getParser().parseExpression(ImmVal))
3240     return MatchOperand_ParseFail;
3241 
3242   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3243   if (!MCE) {
3244     Error(E, "expected constant '#imm' after shift specifier");
3245     return MatchOperand_ParseFail;
3246   }
3247 
3248   E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3249   Operands.push_back(AArch64Operand::CreateShiftExtend(
3250       ShOp, MCE->getValue(), true, S, E, getContext()));
3251   return MatchOperand_Success;
3252 }
3253 
3254 static const struct Extension {
3255   const char *Name;
3256   const FeatureBitset Features;
3257 } ExtensionMap[] = {
3258     {"crc", {AArch64::FeatureCRC}},
3259     {"sm4", {AArch64::FeatureSM4}},
3260     {"sha3", {AArch64::FeatureSHA3}},
3261     {"sha2", {AArch64::FeatureSHA2}},
3262     {"aes", {AArch64::FeatureAES}},
3263     {"crypto", {AArch64::FeatureCrypto}},
3264     {"fp", {AArch64::FeatureFPARMv8}},
3265     {"simd", {AArch64::FeatureNEON}},
3266     {"ras", {AArch64::FeatureRAS}},
3267     {"lse", {AArch64::FeatureLSE}},
3268     {"predres", {AArch64::FeaturePredRes}},
3269     {"ccdp", {AArch64::FeatureCacheDeepPersist}},
3270     {"mte", {AArch64::FeatureMTE}},
3271     {"memtag", {AArch64::FeatureMTE}},
3272     {"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3273     {"pan", {AArch64::FeaturePAN}},
3274     {"pan-rwv", {AArch64::FeaturePAN_RWV}},
3275     {"ccpp", {AArch64::FeatureCCPP}},
3276     {"rcpc", {AArch64::FeatureRCPC}},
3277     {"rng", {AArch64::FeatureRandGen}},
3278     {"sve", {AArch64::FeatureSVE}},
3279     {"sve2", {AArch64::FeatureSVE2}},
3280     {"sve2-aes", {AArch64::FeatureSVE2AES}},
3281     {"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3282     {"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3283     {"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
3284     {"ls64", {AArch64::FeatureLS64}},
3285     {"xs", {AArch64::FeatureXS}},
3286     {"pauth", {AArch64::FeaturePAuth}},
3287     {"flagm", {AArch64::FeatureFlagM}},
3288     {"rme", {AArch64::FeatureRME}},
3289     {"sme", {AArch64::FeatureSME}},
3290     {"sme-f64", {AArch64::FeatureSMEF64}},
3291     {"sme-i64", {AArch64::FeatureSMEI64}},
3292     // FIXME: Unsupported extensions
3293     {"lor", {}},
3294     {"rdma", {}},
3295     {"profile", {}},
3296 };
3297 
3298 static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
3299   if (FBS[AArch64::HasV8_1aOps])
3300     Str += "ARMv8.1a";
3301   else if (FBS[AArch64::HasV8_2aOps])
3302     Str += "ARMv8.2a";
3303   else if (FBS[AArch64::HasV8_3aOps])
3304     Str += "ARMv8.3a";
3305   else if (FBS[AArch64::HasV8_4aOps])
3306     Str += "ARMv8.4a";
3307   else if (FBS[AArch64::HasV8_5aOps])
3308     Str += "ARMv8.5a";
3309   else if (FBS[AArch64::HasV8_6aOps])
3310     Str += "ARMv8.6a";
3311   else if (FBS[AArch64::HasV8_7aOps])
3312     Str += "ARMv8.7a";
3313   else if (FBS[AArch64::HasV9_0aOps])
3314     Str += "ARMv9-a";
3315   else if (FBS[AArch64::HasV9_1aOps])
3316     Str += "ARMv9.1a";
3317   else if (FBS[AArch64::HasV9_2aOps])
3318     Str += "ARMv9.2a";
3319   else {
3320     SmallVector<std::string, 2> ExtMatches;
3321     for (const auto& Ext : ExtensionMap) {
3322       // Use & in case multiple features are enabled
3323       if ((FBS & Ext.Features) != FeatureBitset())
3324         ExtMatches.push_back(Ext.Name);
3325     }
3326     Str += !ExtMatches.empty() ? llvm::join(ExtMatches, ", ") : "(unknown)";
3327   }
3328 }
3329 
3330 void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands,
3331                                       SMLoc S) {
3332   const uint16_t Op2 = Encoding & 7;
3333   const uint16_t Cm = (Encoding & 0x78) >> 3;
3334   const uint16_t Cn = (Encoding & 0x780) >> 7;
3335   const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3336 
3337   const MCExpr *Expr = MCConstantExpr::create(Op1, getContext());
3338 
3339   Operands.push_back(
3340       AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3341   Operands.push_back(
3342       AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3343   Operands.push_back(
3344       AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3345   Expr = MCConstantExpr::create(Op2, getContext());
3346   Operands.push_back(
3347       AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3348 }
3349 
3350 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
3351 /// the SYS instruction. Parse them specially so that we create a SYS MCInst.
3352 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3353                                    OperandVector &Operands) {
3354   if (Name.contains('.'))
3355     return TokError("invalid operand");
3356 
3357   Mnemonic = Name;
3358   Operands.push_back(AArch64Operand::CreateToken("sys", NameLoc, getContext()));
3359 
3360   const AsmToken &Tok = getTok();
3361   StringRef Op = Tok.getString();
3362   SMLoc S = Tok.getLoc();
3363 
3364   if (Mnemonic == "ic") {
3365     const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op);
3366     if (!IC)
3367       return TokError("invalid operand for IC instruction");
3368     else if (!IC->haveFeatures(getSTI().getFeatureBits())) {
3369       std::string Str("IC " + std::string(IC->Name) + " requires: ");
3370       setRequiredFeatureString(IC->getRequiredFeatures(), Str);
3371       return TokError(Str);
3372     }
3373     createSysAlias(IC->Encoding, Operands, S);
3374   } else if (Mnemonic == "dc") {
3375     const AArch64DC::DC *DC = AArch64DC::lookupDCByName(Op);
3376     if (!DC)
3377       return TokError("invalid operand for DC instruction");
3378     else if (!DC->haveFeatures(getSTI().getFeatureBits())) {
3379       std::string Str("DC " + std::string(DC->Name) + " requires: ");
3380       setRequiredFeatureString(DC->getRequiredFeatures(), Str);
3381       return TokError(Str);
3382     }
3383     createSysAlias(DC->Encoding, Operands, S);
3384   } else if (Mnemonic == "at") {
3385     const AArch64AT::AT *AT = AArch64AT::lookupATByName(Op);
3386     if (!AT)
3387       return TokError("invalid operand for AT instruction");
3388     else if (!AT->haveFeatures(getSTI().getFeatureBits())) {
3389       std::string Str("AT " + std::string(AT->Name) + " requires: ");
3390       setRequiredFeatureString(AT->getRequiredFeatures(), Str);
3391       return TokError(Str);
3392     }
3393     createSysAlias(AT->Encoding, Operands, S);
3394   } else if (Mnemonic == "tlbi") {
3395     const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(Op);
3396     if (!TLBI)
3397       return TokError("invalid operand for TLBI instruction");
3398     else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) {
3399       std::string Str("TLBI " + std::string(TLBI->Name) + " requires: ");
3400       setRequiredFeatureString(TLBI->getRequiredFeatures(), Str);
3401       return TokError(Str);
3402     }
3403     createSysAlias(TLBI->Encoding, Operands, S);
3404   } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp") {
3405     const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByName(Op);
3406     if (!PRCTX)
3407       return TokError("invalid operand for prediction restriction instruction");
3408     else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) {
3409       std::string Str(
3410           Mnemonic.upper() + std::string(PRCTX->Name) + " requires: ");
3411       setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str);
3412       return TokError(Str);
3413     }
3414     uint16_t PRCTX_Op2 =
3415       Mnemonic == "cfp" ? 4 :
3416       Mnemonic == "dvp" ? 5 :
3417       Mnemonic == "cpp" ? 7 :
3418       0;
3419     assert(PRCTX_Op2 && "Invalid mnemonic for prediction restriction instruction");
3420     createSysAlias(PRCTX->Encoding << 3 | PRCTX_Op2 , Operands, S);
3421   }
3422 
3423   Lex(); // Eat operand.
3424 
3425   bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
3426   bool HasRegister = false;
3427 
3428   // Check for the optional register operand.
3429   if (parseOptionalToken(AsmToken::Comma)) {
3430     if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
3431       return TokError("expected register operand");
3432     HasRegister = true;
3433   }
3434 
3435   if (ExpectRegister && !HasRegister)
3436     return TokError("specified " + Mnemonic + " op requires a register");
3437   else if (!ExpectRegister && HasRegister)
3438     return TokError("specified " + Mnemonic + " op does not use a register");
3439 
3440   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
3441     return true;
3442 
3443   return false;
3444 }
3445 
3446 OperandMatchResultTy
3447 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
3448   MCAsmParser &Parser = getParser();
3449   const AsmToken &Tok = getTok();
3450 
3451   if (Mnemonic == "tsb" && Tok.isNot(AsmToken::Identifier)) {
3452     TokError("'csync' operand expected");
3453     return MatchOperand_ParseFail;
3454   } else if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
3455     // Immediate operand.
3456     const MCExpr *ImmVal;
3457     SMLoc ExprLoc = getLoc();
3458     AsmToken IntTok = Tok;
3459     if (getParser().parseExpression(ImmVal))
3460       return MatchOperand_ParseFail;
3461     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3462     if (!MCE) {
3463       Error(ExprLoc, "immediate value expected for barrier operand");
3464       return MatchOperand_ParseFail;
3465     }
3466     int64_t Value = MCE->getValue();
3467     if (Mnemonic == "dsb" && Value > 15) {
3468       // This case is a no match here, but it might be matched by the nXS
3469       // variant. Deliberately not unlex the optional '#' as it is not necessary
3470       // to characterize an integer immediate.
3471       Parser.getLexer().UnLex(IntTok);
3472       return MatchOperand_NoMatch;
3473     }
3474     if (Value < 0 || Value > 15) {
3475       Error(ExprLoc, "barrier operand out of range");
3476       return MatchOperand_ParseFail;
3477     }
3478     auto DB = AArch64DB::lookupDBByEncoding(Value);
3479     Operands.push_back(AArch64Operand::CreateBarrier(Value, DB ? DB->Name : "",
3480                                                      ExprLoc, getContext(),
3481                                                      false /*hasnXSModifier*/));
3482     return MatchOperand_Success;
3483   }
3484 
3485   if (Tok.isNot(AsmToken::Identifier)) {
3486     TokError("invalid operand for instruction");
3487     return MatchOperand_ParseFail;
3488   }
3489 
3490   StringRef Operand = Tok.getString();
3491   auto TSB = AArch64TSB::lookupTSBByName(Operand);
3492   auto DB = AArch64DB::lookupDBByName(Operand);
3493   // The only valid named option for ISB is 'sy'
3494   if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) {
3495     TokError("'sy' or #imm operand expected");
3496     return MatchOperand_ParseFail;
3497   // The only valid named option for TSB is 'csync'
3498   } else if (Mnemonic == "tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync)) {
3499     TokError("'csync' operand expected");
3500     return MatchOperand_ParseFail;
3501   } else if (!DB && !TSB) {
3502     if (Mnemonic == "dsb") {
3503       // This case is a no match here, but it might be matched by the nXS
3504       // variant.
3505       return MatchOperand_NoMatch;
3506     }
3507     TokError("invalid barrier option name");
3508     return MatchOperand_ParseFail;
3509   }
3510 
3511   Operands.push_back(AArch64Operand::CreateBarrier(
3512       DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(),
3513       getContext(), false /*hasnXSModifier*/));
3514   Lex(); // Consume the option
3515 
3516   return MatchOperand_Success;
3517 }
3518 
3519 OperandMatchResultTy
3520 AArch64AsmParser::tryParseBarriernXSOperand(OperandVector &Operands) {
3521   const AsmToken &Tok = getTok();
3522 
3523   assert(Mnemonic == "dsb" && "Instruction does not accept nXS operands");
3524   if (Mnemonic != "dsb")
3525     return MatchOperand_ParseFail;
3526 
3527   if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
3528     // Immediate operand.
3529     const MCExpr *ImmVal;
3530     SMLoc ExprLoc = getLoc();
3531     if (getParser().parseExpression(ImmVal))
3532       return MatchOperand_ParseFail;
3533     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3534     if (!MCE) {
3535       Error(ExprLoc, "immediate value expected for barrier operand");
3536       return MatchOperand_ParseFail;
3537     }
3538     int64_t Value = MCE->getValue();
3539     // v8.7-A DSB in the nXS variant accepts only the following immediate
3540     // values: 16, 20, 24, 28.
3541     if (Value != 16 && Value != 20 && Value != 24 && Value != 28) {
3542       Error(ExprLoc, "barrier operand out of range");
3543       return MatchOperand_ParseFail;
3544     }
3545     auto DB = AArch64DBnXS::lookupDBnXSByImmValue(Value);
3546     Operands.push_back(AArch64Operand::CreateBarrier(DB->Encoding, DB->Name,
3547                                                      ExprLoc, getContext(),
3548                                                      true /*hasnXSModifier*/));
3549     return MatchOperand_Success;
3550   }
3551 
3552   if (Tok.isNot(AsmToken::Identifier)) {
3553     TokError("invalid operand for instruction");
3554     return MatchOperand_ParseFail;
3555   }
3556 
3557   StringRef Operand = Tok.getString();
3558   auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
3559 
3560   if (!DB) {
3561     TokError("invalid barrier option name");
3562     return MatchOperand_ParseFail;
3563   }
3564 
3565   Operands.push_back(
3566       AArch64Operand::CreateBarrier(DB->Encoding, Tok.getString(), getLoc(),
3567                                     getContext(), true /*hasnXSModifier*/));
3568   Lex(); // Consume the option
3569 
3570   return MatchOperand_Success;
3571 }
3572 
3573 OperandMatchResultTy
3574 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
3575   const AsmToken &Tok = getTok();
3576 
3577   if (Tok.isNot(AsmToken::Identifier))
3578     return MatchOperand_NoMatch;
3579 
3580   if (AArch64SVCR::lookupSVCRByName(Tok.getString()))
3581     return MatchOperand_NoMatch;
3582 
3583   int MRSReg, MSRReg;
3584   auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString());
3585   if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
3586     MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
3587     MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
3588   } else
3589     MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString());
3590 
3591   auto PState = AArch64PState::lookupPStateByName(Tok.getString());
3592   unsigned PStateImm = -1;
3593   if (PState && PState->haveFeatures(getSTI().getFeatureBits()))
3594     PStateImm = PState->Encoding;
3595 
3596   Operands.push_back(
3597       AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg,
3598                                    PStateImm, getContext()));
3599   Lex(); // Eat identifier
3600 
3601   return MatchOperand_Success;
3602 }
3603 
3604 /// tryParseNeonVectorRegister - Parse a vector register operand.
3605 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) {
3606   if (getTok().isNot(AsmToken::Identifier))
3607     return true;
3608 
3609   SMLoc S = getLoc();
3610   // Check for a vector register specifier first.
3611   StringRef Kind;
3612   unsigned Reg;
3613   OperandMatchResultTy Res =
3614       tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
3615   if (Res != MatchOperand_Success)
3616     return true;
3617 
3618   const auto &KindRes = parseVectorKind(Kind, RegKind::NeonVector);
3619   if (!KindRes)
3620     return true;
3621 
3622   unsigned ElementWidth = KindRes->second;
3623   Operands.push_back(
3624       AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
3625                                       S, getLoc(), getContext()));
3626 
3627   // If there was an explicit qualifier, that goes on as a literal text
3628   // operand.
3629   if (!Kind.empty())
3630     Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
3631 
3632   return tryParseVectorIndex(Operands) == MatchOperand_ParseFail;
3633 }
3634 
3635 OperandMatchResultTy
3636 AArch64AsmParser::tryParseVectorIndex(OperandVector &Operands) {
3637   SMLoc SIdx = getLoc();
3638   if (parseOptionalToken(AsmToken::LBrac)) {
3639     const MCExpr *ImmVal;
3640     if (getParser().parseExpression(ImmVal))
3641       return MatchOperand_NoMatch;
3642     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3643     if (!MCE) {
3644       TokError("immediate value expected for vector index");
3645       return MatchOperand_ParseFail;;
3646     }
3647 
3648     SMLoc E = getLoc();
3649 
3650     if (parseToken(AsmToken::RBrac, "']' expected"))
3651       return MatchOperand_ParseFail;;
3652 
3653     Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
3654                                                          E, getContext()));
3655     return MatchOperand_Success;
3656   }
3657 
3658   return MatchOperand_NoMatch;
3659 }
3660 
3661 // tryParseVectorRegister - Try to parse a vector register name with
3662 // optional kind specifier. If it is a register specifier, eat the token
3663 // and return it.
3664 OperandMatchResultTy
3665 AArch64AsmParser::tryParseVectorRegister(unsigned &Reg, StringRef &Kind,
3666                                          RegKind MatchKind) {
3667   const AsmToken &Tok = getTok();
3668 
3669   if (Tok.isNot(AsmToken::Identifier))
3670     return MatchOperand_NoMatch;
3671 
3672   StringRef Name = Tok.getString();
3673   // If there is a kind specifier, it's separated from the register name by
3674   // a '.'.
3675   size_t Start = 0, Next = Name.find('.');
3676   StringRef Head = Name.slice(Start, Next);
3677   unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
3678 
3679   if (RegNum) {
3680     if (Next != StringRef::npos) {
3681       Kind = Name.slice(Next, StringRef::npos);
3682       if (!isValidVectorKind(Kind, MatchKind)) {
3683         TokError("invalid vector kind qualifier");
3684         return MatchOperand_ParseFail;
3685       }
3686     }
3687     Lex(); // Eat the register token.
3688 
3689     Reg = RegNum;
3690     return MatchOperand_Success;
3691   }
3692 
3693   return MatchOperand_NoMatch;
3694 }
3695 
3696 /// tryParseSVEPredicateVector - Parse a SVE predicate register operand.
3697 OperandMatchResultTy
3698 AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) {
3699   // Check for a SVE predicate register specifier first.
3700   const SMLoc S = getLoc();
3701   StringRef Kind;
3702   unsigned RegNum;
3703   auto Res = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
3704   if (Res != MatchOperand_Success)
3705     return Res;
3706 
3707   const auto &KindRes = parseVectorKind(Kind, RegKind::SVEPredicateVector);
3708   if (!KindRes)
3709     return MatchOperand_NoMatch;
3710 
3711   unsigned ElementWidth = KindRes->second;
3712   Operands.push_back(AArch64Operand::CreateVectorReg(
3713       RegNum, RegKind::SVEPredicateVector, ElementWidth, S,
3714       getLoc(), getContext()));
3715 
3716   if (getLexer().is(AsmToken::LBrac)) {
3717     // Indexed predicate, there's no comma so try parse the next operand
3718     // immediately.
3719     if (parseOperand(Operands, false, false))
3720       return MatchOperand_NoMatch;
3721   }
3722 
3723   // Not all predicates are followed by a '/m' or '/z'.
3724   if (getTok().isNot(AsmToken::Slash))
3725     return MatchOperand_Success;
3726 
3727   // But when they do they shouldn't have an element type suffix.
3728   if (!Kind.empty()) {
3729     Error(S, "not expecting size suffix");
3730     return MatchOperand_ParseFail;
3731   }
3732 
3733   // Add a literal slash as operand
3734   Operands.push_back(AArch64Operand::CreateToken("/", getLoc(), getContext()));
3735 
3736   Lex(); // Eat the slash.
3737 
3738   // Zeroing or merging?
3739   auto Pred = getTok().getString().lower();
3740   if (Pred != "z" && Pred != "m") {
3741     Error(getLoc(), "expecting 'm' or 'z' predication");
3742     return MatchOperand_ParseFail;
3743   }
3744 
3745   // Add zero/merge token.
3746   const char *ZM = Pred == "z" ? "z" : "m";
3747   Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
3748 
3749   Lex(); // Eat zero/merge token.
3750   return MatchOperand_Success;
3751 }
3752 
3753 /// parseRegister - Parse a register operand.
3754 bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
3755   // Try for a Neon vector register.
3756   if (!tryParseNeonVectorRegister(Operands))
3757     return false;
3758 
3759   // Otherwise try for a scalar register.
3760   if (tryParseGPROperand<false>(Operands) == MatchOperand_Success)
3761     return false;
3762 
3763   return true;
3764 }
3765 
3766 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
3767   bool HasELFModifier = false;
3768   AArch64MCExpr::VariantKind RefKind;
3769 
3770   if (parseOptionalToken(AsmToken::Colon)) {
3771     HasELFModifier = true;
3772 
3773     if (getTok().isNot(AsmToken::Identifier))
3774       return TokError("expect relocation specifier in operand after ':'");
3775 
3776     std::string LowerCase = getTok().getIdentifier().lower();
3777     RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
3778                   .Case("lo12", AArch64MCExpr::VK_LO12)
3779                   .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
3780                   .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
3781                   .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
3782                   .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
3783                   .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
3784                   .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
3785                   .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
3786                   .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
3787                   .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
3788                   .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
3789                   .Case("prel_g3", AArch64MCExpr::VK_PREL_G3)
3790                   .Case("prel_g2", AArch64MCExpr::VK_PREL_G2)
3791                   .Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC)
3792                   .Case("prel_g1", AArch64MCExpr::VK_PREL_G1)
3793                   .Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC)
3794                   .Case("prel_g0", AArch64MCExpr::VK_PREL_G0)
3795                   .Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC)
3796                   .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
3797                   .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
3798                   .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
3799                   .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
3800                   .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
3801                   .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
3802                   .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
3803                   .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
3804                   .Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC)
3805                   .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
3806                   .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
3807                   .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
3808                   .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
3809                   .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
3810                   .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
3811                   .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
3812                   .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
3813                   .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
3814                   .Case("got", AArch64MCExpr::VK_GOT_PAGE)
3815                   .Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
3816                   .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
3817                   .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
3818                   .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
3819                   .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
3820                   .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
3821                   .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
3822                   .Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12)
3823                   .Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12)
3824                   .Default(AArch64MCExpr::VK_INVALID);
3825 
3826     if (RefKind == AArch64MCExpr::VK_INVALID)
3827       return TokError("expect relocation specifier in operand after ':'");
3828 
3829     Lex(); // Eat identifier
3830 
3831     if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier"))
3832       return true;
3833   }
3834 
3835   if (getParser().parseExpression(ImmVal))
3836     return true;
3837 
3838   if (HasELFModifier)
3839     ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext());
3840 
3841   return false;
3842 }
3843 
3844 OperandMatchResultTy
3845 AArch64AsmParser::tryParseMatrixTileList(OperandVector &Operands) {
3846   if (getTok().isNot(AsmToken::LCurly))
3847     return MatchOperand_NoMatch;
3848 
3849   auto ParseMatrixTile = [this](unsigned &Reg, unsigned &ElementWidth) {
3850     StringRef Name = getTok().getString();
3851     size_t DotPosition = Name.find('.');
3852     if (DotPosition == StringRef::npos)
3853       return MatchOperand_NoMatch;
3854 
3855     unsigned RegNum = matchMatrixTileListRegName(Name);
3856     if (!RegNum)
3857       return MatchOperand_NoMatch;
3858 
3859     StringRef Tail = Name.drop_front(DotPosition);
3860     const Optional<std::pair<int, int>> &KindRes =
3861         parseVectorKind(Tail, RegKind::Matrix);
3862     if (!KindRes) {
3863       TokError("Expected the register to be followed by element width suffix");
3864       return MatchOperand_ParseFail;
3865     }
3866     ElementWidth = KindRes->second;
3867     Reg = RegNum;
3868     Lex(); // Eat the register.
3869     return MatchOperand_Success;
3870   };
3871 
3872   SMLoc S = getLoc();
3873   auto LCurly = getTok();
3874   Lex(); // Eat left bracket token.
3875 
3876   // Empty matrix list
3877   if (parseOptionalToken(AsmToken::RCurly)) {
3878     Operands.push_back(AArch64Operand::CreateMatrixTileList(
3879         /*RegMask=*/0, S, getLoc(), getContext()));
3880     return MatchOperand_Success;
3881   }
3882 
3883   // Try parse {za} alias early
3884   if (getTok().getString().equals_insensitive("za")) {
3885     Lex(); // Eat 'za'
3886 
3887     if (parseToken(AsmToken::RCurly, "'}' expected"))
3888       return MatchOperand_ParseFail;
3889 
3890     Operands.push_back(AArch64Operand::CreateMatrixTileList(
3891         /*RegMask=*/0xFF, S, getLoc(), getContext()));
3892     return MatchOperand_Success;
3893   }
3894 
3895   SMLoc TileLoc = getLoc();
3896 
3897   unsigned FirstReg, ElementWidth;
3898   auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
3899   if (ParseRes != MatchOperand_Success) {
3900     getLexer().UnLex(LCurly);
3901     return ParseRes;
3902   }
3903 
3904   const MCRegisterInfo *RI = getContext().getRegisterInfo();
3905 
3906   unsigned PrevReg = FirstReg;
3907   unsigned Count = 1;
3908 
3909   SmallSet<unsigned, 8> DRegs;
3910   AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
3911 
3912   SmallSet<unsigned, 8> SeenRegs;
3913   SeenRegs.insert(FirstReg);
3914 
3915   while (parseOptionalToken(AsmToken::Comma)) {
3916     TileLoc = getLoc();
3917     unsigned Reg, NextElementWidth;
3918     ParseRes = ParseMatrixTile(Reg, NextElementWidth);
3919     if (ParseRes != MatchOperand_Success)
3920       return ParseRes;
3921 
3922     // Element size must match on all regs in the list.
3923     if (ElementWidth != NextElementWidth) {
3924       Error(TileLoc, "mismatched register size suffix");
3925       return MatchOperand_ParseFail;
3926     }
3927 
3928     if (RI->getEncodingValue(Reg) <= (RI->getEncodingValue(PrevReg)))
3929       Warning(TileLoc, "tile list not in ascending order");
3930 
3931     if (SeenRegs.contains(Reg))
3932       Warning(TileLoc, "duplicate tile in list");
3933     else {
3934       SeenRegs.insert(Reg);
3935       AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
3936     }
3937 
3938     PrevReg = Reg;
3939     ++Count;
3940   }
3941 
3942   if (parseToken(AsmToken::RCurly, "'}' expected"))
3943     return MatchOperand_ParseFail;
3944 
3945   unsigned RegMask = 0;
3946   for (auto Reg : DRegs)
3947     RegMask |= 0x1 << (RI->getEncodingValue(Reg) -
3948                        RI->getEncodingValue(AArch64::ZAD0));
3949   Operands.push_back(
3950       AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
3951 
3952   return MatchOperand_Success;
3953 }
3954 
3955 template <RegKind VectorKind>
3956 OperandMatchResultTy
3957 AArch64AsmParser::tryParseVectorList(OperandVector &Operands,
3958                                      bool ExpectMatch) {
3959   MCAsmParser &Parser = getParser();
3960   if (!getTok().is(AsmToken::LCurly))
3961     return MatchOperand_NoMatch;
3962 
3963   // Wrapper around parse function
3964   auto ParseVector = [this](unsigned &Reg, StringRef &Kind, SMLoc Loc,
3965                             bool NoMatchIsError) {
3966     auto RegTok = getTok();
3967     auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
3968     if (ParseRes == MatchOperand_Success) {
3969       if (parseVectorKind(Kind, VectorKind))
3970         return ParseRes;
3971       llvm_unreachable("Expected a valid vector kind");
3972     }
3973 
3974     if (RegTok.isNot(AsmToken::Identifier) ||
3975         ParseRes == MatchOperand_ParseFail ||
3976         (ParseRes == MatchOperand_NoMatch && NoMatchIsError &&
3977          !RegTok.getString().startswith_insensitive("za"))) {
3978       Error(Loc, "vector register expected");
3979       return MatchOperand_ParseFail;
3980     }
3981 
3982     return MatchOperand_NoMatch;
3983   };
3984 
3985   SMLoc S = getLoc();
3986   auto LCurly = getTok();
3987   Lex(); // Eat left bracket token.
3988 
3989   StringRef Kind;
3990   unsigned FirstReg;
3991   auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
3992 
3993   // Put back the original left bracket if there was no match, so that
3994   // different types of list-operands can be matched (e.g. SVE, Neon).
3995   if (ParseRes == MatchOperand_NoMatch)
3996     Parser.getLexer().UnLex(LCurly);
3997 
3998   if (ParseRes != MatchOperand_Success)
3999     return ParseRes;
4000 
4001   int64_t PrevReg = FirstReg;
4002   unsigned Count = 1;
4003 
4004   if (parseOptionalToken(AsmToken::Minus)) {
4005     SMLoc Loc = getLoc();
4006     StringRef NextKind;
4007 
4008     unsigned Reg;
4009     ParseRes = ParseVector(Reg, NextKind, getLoc(), true);
4010     if (ParseRes != MatchOperand_Success)
4011       return ParseRes;
4012 
4013     // Any Kind suffices must match on all regs in the list.
4014     if (Kind != NextKind) {
4015       Error(Loc, "mismatched register size suffix");
4016       return MatchOperand_ParseFail;
4017     }
4018 
4019     unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
4020 
4021     if (Space == 0 || Space > 3) {
4022       Error(Loc, "invalid number of vectors");
4023       return MatchOperand_ParseFail;
4024     }
4025 
4026     Count += Space;
4027   }
4028   else {
4029     while (parseOptionalToken(AsmToken::Comma)) {
4030       SMLoc Loc = getLoc();
4031       StringRef NextKind;
4032       unsigned Reg;
4033       ParseRes = ParseVector(Reg, NextKind, getLoc(), true);
4034       if (ParseRes != MatchOperand_Success)
4035         return ParseRes;
4036 
4037       // Any Kind suffices must match on all regs in the list.
4038       if (Kind != NextKind) {
4039         Error(Loc, "mismatched register size suffix");
4040         return MatchOperand_ParseFail;
4041       }
4042 
4043       // Registers must be incremental (with wraparound at 31)
4044       if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
4045           (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32) {
4046         Error(Loc, "registers must be sequential");
4047         return MatchOperand_ParseFail;
4048       }
4049 
4050       PrevReg = Reg;
4051       ++Count;
4052     }
4053   }
4054 
4055   if (parseToken(AsmToken::RCurly, "'}' expected"))
4056     return MatchOperand_ParseFail;
4057 
4058   if (Count > 4) {
4059     Error(S, "invalid number of vectors");
4060     return MatchOperand_ParseFail;
4061   }
4062 
4063   unsigned NumElements = 0;
4064   unsigned ElementWidth = 0;
4065   if (!Kind.empty()) {
4066     if (const auto &VK = parseVectorKind(Kind, VectorKind))
4067       std::tie(NumElements, ElementWidth) = *VK;
4068   }
4069 
4070   Operands.push_back(AArch64Operand::CreateVectorList(
4071       FirstReg, Count, NumElements, ElementWidth, VectorKind, S, getLoc(),
4072       getContext()));
4073 
4074   return MatchOperand_Success;
4075 }
4076 
4077 /// parseNeonVectorList - Parse a vector list operand for AdvSIMD instructions.
4078 bool AArch64AsmParser::parseNeonVectorList(OperandVector &Operands) {
4079   auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands, true);
4080   if (ParseRes != MatchOperand_Success)
4081     return true;
4082 
4083   return tryParseVectorIndex(Operands) == MatchOperand_ParseFail;
4084 }
4085 
4086 OperandMatchResultTy
4087 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
4088   SMLoc StartLoc = getLoc();
4089 
4090   unsigned RegNum;
4091   OperandMatchResultTy Res = tryParseScalarRegister(RegNum);
4092   if (Res != MatchOperand_Success)
4093     return Res;
4094 
4095   if (!parseOptionalToken(AsmToken::Comma)) {
4096     Operands.push_back(AArch64Operand::CreateReg(
4097         RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4098     return MatchOperand_Success;
4099   }
4100 
4101   parseOptionalToken(AsmToken::Hash);
4102 
4103   if (getTok().isNot(AsmToken::Integer)) {
4104     Error(getLoc(), "index must be absent or #0");
4105     return MatchOperand_ParseFail;
4106   }
4107 
4108   const MCExpr *ImmVal;
4109   if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4110       cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
4111     Error(getLoc(), "index must be absent or #0");
4112     return MatchOperand_ParseFail;
4113   }
4114 
4115   Operands.push_back(AArch64Operand::CreateReg(
4116       RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4117   return MatchOperand_Success;
4118 }
4119 
4120 template <bool ParseShiftExtend, RegConstraintEqualityTy EqTy>
4121 OperandMatchResultTy
4122 AArch64AsmParser::tryParseGPROperand(OperandVector &Operands) {
4123   SMLoc StartLoc = getLoc();
4124 
4125   unsigned RegNum;
4126   OperandMatchResultTy Res = tryParseScalarRegister(RegNum);
4127   if (Res != MatchOperand_Success)
4128     return Res;
4129 
4130   // No shift/extend is the default.
4131   if (!ParseShiftExtend || getTok().isNot(AsmToken::Comma)) {
4132     Operands.push_back(AArch64Operand::CreateReg(
4133         RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4134     return MatchOperand_Success;
4135   }
4136 
4137   // Eat the comma
4138   Lex();
4139 
4140   // Match the shift
4141   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd;
4142   Res = tryParseOptionalShiftExtend(ExtOpnd);
4143   if (Res != MatchOperand_Success)
4144     return Res;
4145 
4146   auto Ext = static_cast<AArch64Operand*>(ExtOpnd.back().get());
4147   Operands.push_back(AArch64Operand::CreateReg(
4148       RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(), getContext(), EqTy,
4149       Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4150       Ext->hasShiftExtendAmount()));
4151 
4152   return MatchOperand_Success;
4153 }
4154 
4155 bool AArch64AsmParser::parseOptionalMulOperand(OperandVector &Operands) {
4156   MCAsmParser &Parser = getParser();
4157 
4158   // Some SVE instructions have a decoration after the immediate, i.e.
4159   // "mul vl". We parse them here and add tokens, which must be present in the
4160   // asm string in the tablegen instruction.
4161   bool NextIsVL =
4162       Parser.getLexer().peekTok().getString().equals_insensitive("vl");
4163   bool NextIsHash = Parser.getLexer().peekTok().is(AsmToken::Hash);
4164   if (!getTok().getString().equals_insensitive("mul") ||
4165       !(NextIsVL || NextIsHash))
4166     return true;
4167 
4168   Operands.push_back(
4169       AArch64Operand::CreateToken("mul", getLoc(), getContext()));
4170   Lex(); // Eat the "mul"
4171 
4172   if (NextIsVL) {
4173     Operands.push_back(
4174         AArch64Operand::CreateToken("vl", getLoc(), getContext()));
4175     Lex(); // Eat the "vl"
4176     return false;
4177   }
4178 
4179   if (NextIsHash) {
4180     Lex(); // Eat the #
4181     SMLoc S = getLoc();
4182 
4183     // Parse immediate operand.
4184     const MCExpr *ImmVal;
4185     if (!Parser.parseExpression(ImmVal))
4186       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4187         Operands.push_back(AArch64Operand::CreateImm(
4188             MCConstantExpr::create(MCE->getValue(), getContext()), S, getLoc(),
4189             getContext()));
4190         return MatchOperand_Success;
4191       }
4192   }
4193 
4194   return Error(getLoc(), "expected 'vl' or '#<imm>'");
4195 }
4196 
4197 bool AArch64AsmParser::parseKeywordOperand(OperandVector &Operands) {
4198   auto Tok = getTok();
4199   if (Tok.isNot(AsmToken::Identifier))
4200     return true;
4201 
4202   auto Keyword = Tok.getString();
4203   Keyword = StringSwitch<StringRef>(Keyword.lower())
4204                 .Case("sm", "sm")
4205                 .Case("za", "za")
4206                 .Default(Keyword);
4207   Operands.push_back(
4208       AArch64Operand::CreateToken(Keyword, Tok.getLoc(), getContext()));
4209 
4210   Lex();
4211   return false;
4212 }
4213 
4214 /// parseOperand - Parse a arm instruction operand.  For now this parses the
4215 /// operand regardless of the mnemonic.
4216 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
4217                                   bool invertCondCode) {
4218   MCAsmParser &Parser = getParser();
4219 
4220   OperandMatchResultTy ResTy =
4221       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/ true);
4222 
4223   // Check if the current operand has a custom associated parser, if so, try to
4224   // custom parse the operand, or fallback to the general approach.
4225   if (ResTy == MatchOperand_Success)
4226     return false;
4227   // If there wasn't a custom match, try the generic matcher below. Otherwise,
4228   // there was a match, but an error occurred, in which case, just return that
4229   // the operand parsing failed.
4230   if (ResTy == MatchOperand_ParseFail)
4231     return true;
4232 
4233   // Nothing custom, so do general case parsing.
4234   SMLoc S, E;
4235   switch (getLexer().getKind()) {
4236   default: {
4237     SMLoc S = getLoc();
4238     const MCExpr *Expr;
4239     if (parseSymbolicImmVal(Expr))
4240       return Error(S, "invalid operand");
4241 
4242     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
4243     Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4244     return false;
4245   }
4246   case AsmToken::LBrac: {
4247     Operands.push_back(
4248         AArch64Operand::CreateToken("[", getLoc(), getContext()));
4249     Lex(); // Eat '['
4250 
4251     // There's no comma after a '[', so we can parse the next operand
4252     // immediately.
4253     return parseOperand(Operands, false, false);
4254   }
4255   case AsmToken::LCurly: {
4256     if (!parseNeonVectorList(Operands))
4257       return false;
4258 
4259     Operands.push_back(
4260         AArch64Operand::CreateToken("{", getLoc(), getContext()));
4261     Lex(); // Eat '{'
4262 
4263     // There's no comma after a '{', so we can parse the next operand
4264     // immediately.
4265     return parseOperand(Operands, false, false);
4266   }
4267   case AsmToken::Identifier: {
4268     // If we're expecting a Condition Code operand, then just parse that.
4269     if (isCondCode)
4270       return parseCondCode(Operands, invertCondCode);
4271 
4272     // If it's a register name, parse it.
4273     if (!parseRegister(Operands))
4274       return false;
4275 
4276     // See if this is a "mul vl" decoration or "mul #<int>" operand used
4277     // by SVE instructions.
4278     if (!parseOptionalMulOperand(Operands))
4279       return false;
4280 
4281     // If this is an "smstart" or "smstop" instruction, parse its special
4282     // keyword operand as an identifier.
4283     if (Mnemonic == "smstart" || Mnemonic == "smstop")
4284       return parseKeywordOperand(Operands);
4285 
4286     // This could be an optional "shift" or "extend" operand.
4287     OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
4288     // We can only continue if no tokens were eaten.
4289     if (GotShift != MatchOperand_NoMatch)
4290       return GotShift;
4291 
4292     // If this is a two-word mnemonic, parse its special keyword
4293     // operand as an identifier.
4294     if (Mnemonic == "brb")
4295       return parseKeywordOperand(Operands);
4296 
4297     // This was not a register so parse other operands that start with an
4298     // identifier (like labels) as expressions and create them as immediates.
4299     const MCExpr *IdVal;
4300     S = getLoc();
4301     if (getParser().parseExpression(IdVal))
4302       return true;
4303     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
4304     Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
4305     return false;
4306   }
4307   case AsmToken::Integer:
4308   case AsmToken::Real:
4309   case AsmToken::Hash: {
4310     // #42 -> immediate.
4311     S = getLoc();
4312 
4313     parseOptionalToken(AsmToken::Hash);
4314 
4315     // Parse a negative sign
4316     bool isNegative = false;
4317     if (getTok().is(AsmToken::Minus)) {
4318       isNegative = true;
4319       // We need to consume this token only when we have a Real, otherwise
4320       // we let parseSymbolicImmVal take care of it
4321       if (Parser.getLexer().peekTok().is(AsmToken::Real))
4322         Lex();
4323     }
4324 
4325     // The only Real that should come through here is a literal #0.0 for
4326     // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
4327     // so convert the value.
4328     const AsmToken &Tok = getTok();
4329     if (Tok.is(AsmToken::Real)) {
4330       APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
4331       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
4332       if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
4333           Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
4334           Mnemonic != "fcmlt" && Mnemonic != "fcmne")
4335         return TokError("unexpected floating point literal");
4336       else if (IntVal != 0 || isNegative)
4337         return TokError("expected floating-point constant #0.0");
4338       Lex(); // Eat the token.
4339 
4340       Operands.push_back(AArch64Operand::CreateToken("#0", S, getContext()));
4341       Operands.push_back(AArch64Operand::CreateToken(".0", S, getContext()));
4342       return false;
4343     }
4344 
4345     const MCExpr *ImmVal;
4346     if (parseSymbolicImmVal(ImmVal))
4347       return true;
4348 
4349     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
4350     Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
4351     return false;
4352   }
4353   case AsmToken::Equal: {
4354     SMLoc Loc = getLoc();
4355     if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
4356       return TokError("unexpected token in operand");
4357     Lex(); // Eat '='
4358     const MCExpr *SubExprVal;
4359     if (getParser().parseExpression(SubExprVal))
4360       return true;
4361 
4362     if (Operands.size() < 2 ||
4363         !static_cast<AArch64Operand &>(*Operands[1]).isScalarReg())
4364       return Error(Loc, "Only valid when first operand is register");
4365 
4366     bool IsXReg =
4367         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4368             Operands[1]->getReg());
4369 
4370     MCContext& Ctx = getContext();
4371     E = SMLoc::getFromPointer(Loc.getPointer() - 1);
4372     // If the op is an imm and can be fit into a mov, then replace ldr with mov.
4373     if (isa<MCConstantExpr>(SubExprVal)) {
4374       uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
4375       uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
4376       while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
4377         ShiftAmt += 16;
4378         Imm >>= 16;
4379       }
4380       if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
4381         Operands[0] = AArch64Operand::CreateToken("movz", Loc, Ctx);
4382         Operands.push_back(AArch64Operand::CreateImm(
4383             MCConstantExpr::create(Imm, Ctx), S, E, Ctx));
4384         if (ShiftAmt)
4385           Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
4386                      ShiftAmt, true, S, E, Ctx));
4387         return false;
4388       }
4389       APInt Simm = APInt(64, Imm << ShiftAmt);
4390       // check if the immediate is an unsigned or signed 32-bit int for W regs
4391       if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
4392         return Error(Loc, "Immediate too large for register");
4393     }
4394     // If it is a label or an imm that cannot fit in a movz, put it into CP.
4395     const MCExpr *CPLoc =
4396         getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
4397     Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
4398     return false;
4399   }
4400   }
4401 }
4402 
4403 bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
4404   const MCExpr *Expr = nullptr;
4405   SMLoc L = getLoc();
4406   if (check(getParser().parseExpression(Expr), L, "expected expression"))
4407     return true;
4408   const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4409   if (check(!Value, L, "expected constant expression"))
4410     return true;
4411   Out = Value->getValue();
4412   return false;
4413 }
4414 
4415 bool AArch64AsmParser::parseComma() {
4416   if (check(getTok().isNot(AsmToken::Comma), getLoc(), "expected comma"))
4417     return true;
4418   // Eat the comma
4419   Lex();
4420   return false;
4421 }
4422 
4423 bool AArch64AsmParser::parseRegisterInRange(unsigned &Out, unsigned Base,
4424                                             unsigned First, unsigned Last) {
4425   unsigned Reg;
4426   SMLoc Start, End;
4427   if (check(ParseRegister(Reg, Start, End), getLoc(), "expected register"))
4428     return true;
4429 
4430   // Special handling for FP and LR; they aren't linearly after x28 in
4431   // the registers enum.
4432   unsigned RangeEnd = Last;
4433   if (Base == AArch64::X0) {
4434     if (Last == AArch64::FP) {
4435       RangeEnd = AArch64::X28;
4436       if (Reg == AArch64::FP) {
4437         Out = 29;
4438         return false;
4439       }
4440     }
4441     if (Last == AArch64::LR) {
4442       RangeEnd = AArch64::X28;
4443       if (Reg == AArch64::FP) {
4444         Out = 29;
4445         return false;
4446       } else if (Reg == AArch64::LR) {
4447         Out = 30;
4448         return false;
4449       }
4450     }
4451   }
4452 
4453   if (check(Reg < First || Reg > RangeEnd, Start,
4454             Twine("expected register in range ") +
4455                 AArch64InstPrinter::getRegisterName(First) + " to " +
4456                 AArch64InstPrinter::getRegisterName(Last)))
4457     return true;
4458   Out = Reg - Base;
4459   return false;
4460 }
4461 
4462 bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1,
4463                                  const MCParsedAsmOperand &Op2) const {
4464   auto &AOp1 = static_cast<const AArch64Operand&>(Op1);
4465   auto &AOp2 = static_cast<const AArch64Operand&>(Op2);
4466   if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
4467       AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
4468     return MCTargetAsmParser::regsEqual(Op1, Op2);
4469 
4470   assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
4471          "Testing equality of non-scalar registers not supported");
4472 
4473   // Check if a registers match their sub/super register classes.
4474   if (AOp1.getRegEqualityTy() == EqualsSuperReg)
4475     return getXRegFromWReg(Op1.getReg()) == Op2.getReg();
4476   if (AOp1.getRegEqualityTy() == EqualsSubReg)
4477     return getWRegFromXReg(Op1.getReg()) == Op2.getReg();
4478   if (AOp2.getRegEqualityTy() == EqualsSuperReg)
4479     return getXRegFromWReg(Op2.getReg()) == Op1.getReg();
4480   if (AOp2.getRegEqualityTy() == EqualsSubReg)
4481     return getWRegFromXReg(Op2.getReg()) == Op1.getReg();
4482 
4483   return false;
4484 }
4485 
4486 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
4487 /// operands.
4488 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
4489                                         StringRef Name, SMLoc NameLoc,
4490                                         OperandVector &Operands) {
4491   Name = StringSwitch<StringRef>(Name.lower())
4492              .Case("beq", "b.eq")
4493              .Case("bne", "b.ne")
4494              .Case("bhs", "b.hs")
4495              .Case("bcs", "b.cs")
4496              .Case("blo", "b.lo")
4497              .Case("bcc", "b.cc")
4498              .Case("bmi", "b.mi")
4499              .Case("bpl", "b.pl")
4500              .Case("bvs", "b.vs")
4501              .Case("bvc", "b.vc")
4502              .Case("bhi", "b.hi")
4503              .Case("bls", "b.ls")
4504              .Case("bge", "b.ge")
4505              .Case("blt", "b.lt")
4506              .Case("bgt", "b.gt")
4507              .Case("ble", "b.le")
4508              .Case("bal", "b.al")
4509              .Case("bnv", "b.nv")
4510              .Default(Name);
4511 
4512   // First check for the AArch64-specific .req directive.
4513   if (getTok().is(AsmToken::Identifier) &&
4514       getTok().getIdentifier().lower() == ".req") {
4515     parseDirectiveReq(Name, NameLoc);
4516     // We always return 'error' for this, as we're done with this
4517     // statement and don't need to match the 'instruction."
4518     return true;
4519   }
4520 
4521   // Create the leading tokens for the mnemonic, split by '.' characters.
4522   size_t Start = 0, Next = Name.find('.');
4523   StringRef Head = Name.slice(Start, Next);
4524 
4525   // IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for
4526   // the SYS instruction.
4527   if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" ||
4528       Head == "cfp" || Head == "dvp" || Head == "cpp")
4529     return parseSysAlias(Head, NameLoc, Operands);
4530 
4531   Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
4532   Mnemonic = Head;
4533 
4534   // Handle condition codes for a branch mnemonic
4535   if (Head == "b" && Next != StringRef::npos) {
4536     Start = Next;
4537     Next = Name.find('.', Start + 1);
4538     Head = Name.slice(Start + 1, Next);
4539 
4540     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
4541                                             (Head.data() - Name.data()));
4542     AArch64CC::CondCode CC = parseCondCodeString(Head);
4543     if (CC == AArch64CC::Invalid)
4544       return Error(SuffixLoc, "invalid condition code");
4545     Operands.push_back(AArch64Operand::CreateToken(".", SuffixLoc, getContext(),
4546                                                    /*IsSuffix=*/true));
4547     Operands.push_back(
4548         AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
4549   }
4550 
4551   // Add the remaining tokens in the mnemonic.
4552   while (Next != StringRef::npos) {
4553     Start = Next;
4554     Next = Name.find('.', Start + 1);
4555     Head = Name.slice(Start, Next);
4556     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
4557                                             (Head.data() - Name.data()) + 1);
4558     Operands.push_back(AArch64Operand::CreateToken(
4559         Head, SuffixLoc, getContext(), /*IsSuffix=*/true));
4560   }
4561 
4562   // Conditional compare instructions have a Condition Code operand, which needs
4563   // to be parsed and an immediate operand created.
4564   bool condCodeFourthOperand =
4565       (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
4566        Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
4567        Head == "csinc" || Head == "csinv" || Head == "csneg");
4568 
4569   // These instructions are aliases to some of the conditional select
4570   // instructions. However, the condition code is inverted in the aliased
4571   // instruction.
4572   //
4573   // FIXME: Is this the correct way to handle these? Or should the parser
4574   //        generate the aliased instructions directly?
4575   bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
4576   bool condCodeThirdOperand =
4577       (Head == "cinc" || Head == "cinv" || Head == "cneg");
4578 
4579   // Read the remaining operands.
4580   if (getLexer().isNot(AsmToken::EndOfStatement)) {
4581 
4582     unsigned N = 1;
4583     do {
4584       // Parse and remember the operand.
4585       if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
4586                                      (N == 3 && condCodeThirdOperand) ||
4587                                      (N == 2 && condCodeSecondOperand),
4588                        condCodeSecondOperand || condCodeThirdOperand)) {
4589         return true;
4590       }
4591 
4592       // After successfully parsing some operands there are three special cases
4593       // to consider (i.e. notional operands not separated by commas). Two are
4594       // due to memory specifiers:
4595       //  + An RBrac will end an address for load/store/prefetch
4596       //  + An '!' will indicate a pre-indexed operation.
4597       //
4598       // And a further case is '}', which ends a group of tokens specifying the
4599       // SME accumulator array 'ZA' or tile vector, i.e.
4600       //
4601       //   '{ ZA }' or '{ <ZAt><HV>.<BHSDQ>[<Wv>, #<imm>] }'
4602       //
4603       // It's someone else's responsibility to make sure these tokens are sane
4604       // in the given context!
4605 
4606       if (parseOptionalToken(AsmToken::RBrac))
4607         Operands.push_back(
4608             AArch64Operand::CreateToken("]", getLoc(), getContext()));
4609       if (parseOptionalToken(AsmToken::Exclaim))
4610         Operands.push_back(
4611             AArch64Operand::CreateToken("!", getLoc(), getContext()));
4612       if (parseOptionalToken(AsmToken::RCurly))
4613         Operands.push_back(
4614             AArch64Operand::CreateToken("}", getLoc(), getContext()));
4615 
4616       ++N;
4617     } while (parseOptionalToken(AsmToken::Comma));
4618   }
4619 
4620   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
4621     return true;
4622 
4623   return false;
4624 }
4625 
4626 static inline bool isMatchingOrAlias(unsigned ZReg, unsigned Reg) {
4627   assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
4628   return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
4629          (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
4630          (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
4631          (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
4632          (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
4633          (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
4634 }
4635 
4636 // FIXME: This entire function is a giant hack to provide us with decent
4637 // operand range validation/diagnostics until TableGen/MC can be extended
4638 // to support autogeneration of this kind of validation.
4639 bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
4640                                            SmallVectorImpl<SMLoc> &Loc) {
4641   const MCRegisterInfo *RI = getContext().getRegisterInfo();
4642   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
4643 
4644   // A prefix only applies to the instruction following it.  Here we extract
4645   // prefix information for the next instruction before validating the current
4646   // one so that in the case of failure we don't erronously continue using the
4647   // current prefix.
4648   PrefixInfo Prefix = NextPrefix;
4649   NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.TSFlags);
4650 
4651   // Before validating the instruction in isolation we run through the rules
4652   // applicable when it follows a prefix instruction.
4653   // NOTE: brk & hlt can be prefixed but require no additional validation.
4654   if (Prefix.isActive() &&
4655       (Inst.getOpcode() != AArch64::BRK) &&
4656       (Inst.getOpcode() != AArch64::HLT)) {
4657 
4658     // Prefixed intructions must have a destructive operand.
4659     if ((MCID.TSFlags & AArch64::DestructiveInstTypeMask) ==
4660         AArch64::NotDestructive)
4661       return Error(IDLoc, "instruction is unpredictable when following a"
4662                    " movprfx, suggest replacing movprfx with mov");
4663 
4664     // Destination operands must match.
4665     if (Inst.getOperand(0).getReg() != Prefix.getDstReg())
4666       return Error(Loc[0], "instruction is unpredictable when following a"
4667                    " movprfx writing to a different destination");
4668 
4669     // Destination operand must not be used in any other location.
4670     for (unsigned i = 1; i < Inst.getNumOperands(); ++i) {
4671       if (Inst.getOperand(i).isReg() &&
4672           (MCID.getOperandConstraint(i, MCOI::TIED_TO) == -1) &&
4673           isMatchingOrAlias(Prefix.getDstReg(), Inst.getOperand(i).getReg()))
4674         return Error(Loc[0], "instruction is unpredictable when following a"
4675                      " movprfx and destination also used as non-destructive"
4676                      " source");
4677     }
4678 
4679     auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
4680     if (Prefix.isPredicated()) {
4681       int PgIdx = -1;
4682 
4683       // Find the instructions general predicate.
4684       for (unsigned i = 1; i < Inst.getNumOperands(); ++i)
4685         if (Inst.getOperand(i).isReg() &&
4686             PPRRegClass.contains(Inst.getOperand(i).getReg())) {
4687           PgIdx = i;
4688           break;
4689         }
4690 
4691       // Instruction must be predicated if the movprfx is predicated.
4692       if (PgIdx == -1 ||
4693           (MCID.TSFlags & AArch64::ElementSizeMask) == AArch64::ElementSizeNone)
4694         return Error(IDLoc, "instruction is unpredictable when following a"
4695                      " predicated movprfx, suggest using unpredicated movprfx");
4696 
4697       // Instruction must use same general predicate as the movprfx.
4698       if (Inst.getOperand(PgIdx).getReg() != Prefix.getPgReg())
4699         return Error(IDLoc, "instruction is unpredictable when following a"
4700                      " predicated movprfx using a different general predicate");
4701 
4702       // Instruction element type must match the movprfx.
4703       if ((MCID.TSFlags & AArch64::ElementSizeMask) != Prefix.getElementSize())
4704         return Error(IDLoc, "instruction is unpredictable when following a"
4705                      " predicated movprfx with a different element size");
4706     }
4707   }
4708 
4709   // Check for indexed addressing modes w/ the base register being the
4710   // same as a destination/source register or pair load where
4711   // the Rt == Rt2. All of those are undefined behaviour.
4712   switch (Inst.getOpcode()) {
4713   case AArch64::LDPSWpre:
4714   case AArch64::LDPWpost:
4715   case AArch64::LDPWpre:
4716   case AArch64::LDPXpost:
4717   case AArch64::LDPXpre: {
4718     unsigned Rt = Inst.getOperand(1).getReg();
4719     unsigned Rt2 = Inst.getOperand(2).getReg();
4720     unsigned Rn = Inst.getOperand(3).getReg();
4721     if (RI->isSubRegisterEq(Rn, Rt))
4722       return Error(Loc[0], "unpredictable LDP instruction, writeback base "
4723                            "is also a destination");
4724     if (RI->isSubRegisterEq(Rn, Rt2))
4725       return Error(Loc[1], "unpredictable LDP instruction, writeback base "
4726                            "is also a destination");
4727     LLVM_FALLTHROUGH;
4728   }
4729   case AArch64::LDPDi:
4730   case AArch64::LDPQi:
4731   case AArch64::LDPSi:
4732   case AArch64::LDPSWi:
4733   case AArch64::LDPWi:
4734   case AArch64::LDPXi: {
4735     unsigned Rt = Inst.getOperand(0).getReg();
4736     unsigned Rt2 = Inst.getOperand(1).getReg();
4737     if (Rt == Rt2)
4738       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
4739     break;
4740   }
4741   case AArch64::LDPDpost:
4742   case AArch64::LDPDpre:
4743   case AArch64::LDPQpost:
4744   case AArch64::LDPQpre:
4745   case AArch64::LDPSpost:
4746   case AArch64::LDPSpre:
4747   case AArch64::LDPSWpost: {
4748     unsigned Rt = Inst.getOperand(1).getReg();
4749     unsigned Rt2 = Inst.getOperand(2).getReg();
4750     if (Rt == Rt2)
4751       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
4752     break;
4753   }
4754   case AArch64::STPDpost:
4755   case AArch64::STPDpre:
4756   case AArch64::STPQpost:
4757   case AArch64::STPQpre:
4758   case AArch64::STPSpost:
4759   case AArch64::STPSpre:
4760   case AArch64::STPWpost:
4761   case AArch64::STPWpre:
4762   case AArch64::STPXpost:
4763   case AArch64::STPXpre: {
4764     unsigned Rt = Inst.getOperand(1).getReg();
4765     unsigned Rt2 = Inst.getOperand(2).getReg();
4766     unsigned Rn = Inst.getOperand(3).getReg();
4767     if (RI->isSubRegisterEq(Rn, Rt))
4768       return Error(Loc[0], "unpredictable STP instruction, writeback base "
4769                            "is also a source");
4770     if (RI->isSubRegisterEq(Rn, Rt2))
4771       return Error(Loc[1], "unpredictable STP instruction, writeback base "
4772                            "is also a source");
4773     break;
4774   }
4775   case AArch64::LDRBBpre:
4776   case AArch64::LDRBpre:
4777   case AArch64::LDRHHpre:
4778   case AArch64::LDRHpre:
4779   case AArch64::LDRSBWpre:
4780   case AArch64::LDRSBXpre:
4781   case AArch64::LDRSHWpre:
4782   case AArch64::LDRSHXpre:
4783   case AArch64::LDRSWpre:
4784   case AArch64::LDRWpre:
4785   case AArch64::LDRXpre:
4786   case AArch64::LDRBBpost:
4787   case AArch64::LDRBpost:
4788   case AArch64::LDRHHpost:
4789   case AArch64::LDRHpost:
4790   case AArch64::LDRSBWpost:
4791   case AArch64::LDRSBXpost:
4792   case AArch64::LDRSHWpost:
4793   case AArch64::LDRSHXpost:
4794   case AArch64::LDRSWpost:
4795   case AArch64::LDRWpost:
4796   case AArch64::LDRXpost: {
4797     unsigned Rt = Inst.getOperand(1).getReg();
4798     unsigned Rn = Inst.getOperand(2).getReg();
4799     if (RI->isSubRegisterEq(Rn, Rt))
4800       return Error(Loc[0], "unpredictable LDR instruction, writeback base "
4801                            "is also a source");
4802     break;
4803   }
4804   case AArch64::STRBBpost:
4805   case AArch64::STRBpost:
4806   case AArch64::STRHHpost:
4807   case AArch64::STRHpost:
4808   case AArch64::STRWpost:
4809   case AArch64::STRXpost:
4810   case AArch64::STRBBpre:
4811   case AArch64::STRBpre:
4812   case AArch64::STRHHpre:
4813   case AArch64::STRHpre:
4814   case AArch64::STRWpre:
4815   case AArch64::STRXpre: {
4816     unsigned Rt = Inst.getOperand(1).getReg();
4817     unsigned Rn = Inst.getOperand(2).getReg();
4818     if (RI->isSubRegisterEq(Rn, Rt))
4819       return Error(Loc[0], "unpredictable STR instruction, writeback base "
4820                            "is also a source");
4821     break;
4822   }
4823   case AArch64::STXRB:
4824   case AArch64::STXRH:
4825   case AArch64::STXRW:
4826   case AArch64::STXRX:
4827   case AArch64::STLXRB:
4828   case AArch64::STLXRH:
4829   case AArch64::STLXRW:
4830   case AArch64::STLXRX: {
4831     unsigned Rs = Inst.getOperand(0).getReg();
4832     unsigned Rt = Inst.getOperand(1).getReg();
4833     unsigned Rn = Inst.getOperand(2).getReg();
4834     if (RI->isSubRegisterEq(Rt, Rs) ||
4835         (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP))
4836       return Error(Loc[0],
4837                    "unpredictable STXR instruction, status is also a source");
4838     break;
4839   }
4840   case AArch64::STXPW:
4841   case AArch64::STXPX:
4842   case AArch64::STLXPW:
4843   case AArch64::STLXPX: {
4844     unsigned Rs = Inst.getOperand(0).getReg();
4845     unsigned Rt1 = Inst.getOperand(1).getReg();
4846     unsigned Rt2 = Inst.getOperand(2).getReg();
4847     unsigned Rn = Inst.getOperand(3).getReg();
4848     if (RI->isSubRegisterEq(Rt1, Rs) || RI->isSubRegisterEq(Rt2, Rs) ||
4849         (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP))
4850       return Error(Loc[0],
4851                    "unpredictable STXP instruction, status is also a source");
4852     break;
4853   }
4854   case AArch64::LDRABwriteback:
4855   case AArch64::LDRAAwriteback: {
4856     unsigned Xt = Inst.getOperand(0).getReg();
4857     unsigned Xn = Inst.getOperand(1).getReg();
4858     if (Xt == Xn)
4859       return Error(Loc[0],
4860           "unpredictable LDRA instruction, writeback base"
4861           " is also a destination");
4862     break;
4863   }
4864   }
4865 
4866 
4867   // Now check immediate ranges. Separate from the above as there is overlap
4868   // in the instructions being checked and this keeps the nested conditionals
4869   // to a minimum.
4870   switch (Inst.getOpcode()) {
4871   case AArch64::ADDSWri:
4872   case AArch64::ADDSXri:
4873   case AArch64::ADDWri:
4874   case AArch64::ADDXri:
4875   case AArch64::SUBSWri:
4876   case AArch64::SUBSXri:
4877   case AArch64::SUBWri:
4878   case AArch64::SUBXri: {
4879     // Annoyingly we can't do this in the isAddSubImm predicate, so there is
4880     // some slight duplication here.
4881     if (Inst.getOperand(2).isExpr()) {
4882       const MCExpr *Expr = Inst.getOperand(2).getExpr();
4883       AArch64MCExpr::VariantKind ELFRefKind;
4884       MCSymbolRefExpr::VariantKind DarwinRefKind;
4885       int64_t Addend;
4886       if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
4887 
4888         // Only allow these with ADDXri.
4889         if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
4890              DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
4891             Inst.getOpcode() == AArch64::ADDXri)
4892           return false;
4893 
4894         // Only allow these with ADDXri/ADDWri
4895         if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
4896              ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
4897              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
4898              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
4899              ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
4900              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
4901              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
4902              ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
4903              ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
4904              ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) &&
4905             (Inst.getOpcode() == AArch64::ADDXri ||
4906              Inst.getOpcode() == AArch64::ADDWri))
4907           return false;
4908 
4909         // Don't allow symbol refs in the immediate field otherwise
4910         // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of
4911         // operands of the original instruction (i.e. 'add w0, w1, borked' vs
4912         // 'cmp w0, 'borked')
4913         return Error(Loc.back(), "invalid immediate expression");
4914       }
4915       // We don't validate more complex expressions here
4916     }
4917     return false;
4918   }
4919   default:
4920     return false;
4921   }
4922 }
4923 
4924 static std::string AArch64MnemonicSpellCheck(StringRef S,
4925                                              const FeatureBitset &FBS,
4926                                              unsigned VariantID = 0);
4927 
4928 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
4929                                       uint64_t ErrorInfo,
4930                                       OperandVector &Operands) {
4931   switch (ErrCode) {
4932   case Match_InvalidTiedOperand: {
4933     RegConstraintEqualityTy EqTy =
4934         static_cast<const AArch64Operand &>(*Operands[ErrorInfo])
4935             .getRegEqualityTy();
4936     switch (EqTy) {
4937     case RegConstraintEqualityTy::EqualsSubReg:
4938       return Error(Loc, "operand must be 64-bit form of destination register");
4939     case RegConstraintEqualityTy::EqualsSuperReg:
4940       return Error(Loc, "operand must be 32-bit form of destination register");
4941     case RegConstraintEqualityTy::EqualsReg:
4942       return Error(Loc, "operand must match destination register");
4943     }
4944     llvm_unreachable("Unknown RegConstraintEqualityTy");
4945   }
4946   case Match_MissingFeature:
4947     return Error(Loc,
4948                  "instruction requires a CPU feature not currently enabled");
4949   case Match_InvalidOperand:
4950     return Error(Loc, "invalid operand for instruction");
4951   case Match_InvalidSuffix:
4952     return Error(Loc, "invalid type suffix for instruction");
4953   case Match_InvalidCondCode:
4954     return Error(Loc, "expected AArch64 condition code");
4955   case Match_AddSubRegExtendSmall:
4956     return Error(Loc,
4957       "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
4958   case Match_AddSubRegExtendLarge:
4959     return Error(Loc,
4960       "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
4961   case Match_AddSubSecondSource:
4962     return Error(Loc,
4963       "expected compatible register, symbol or integer in range [0, 4095]");
4964   case Match_LogicalSecondSource:
4965     return Error(Loc, "expected compatible register or logical immediate");
4966   case Match_InvalidMovImm32Shift:
4967     return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
4968   case Match_InvalidMovImm64Shift:
4969     return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
4970   case Match_AddSubRegShift32:
4971     return Error(Loc,
4972        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
4973   case Match_AddSubRegShift64:
4974     return Error(Loc,
4975        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
4976   case Match_InvalidFPImm:
4977     return Error(Loc,
4978                  "expected compatible register or floating-point constant");
4979   case Match_InvalidMemoryIndexedSImm6:
4980     return Error(Loc, "index must be an integer in range [-32, 31].");
4981   case Match_InvalidMemoryIndexedSImm5:
4982     return Error(Loc, "index must be an integer in range [-16, 15].");
4983   case Match_InvalidMemoryIndexed1SImm4:
4984     return Error(Loc, "index must be an integer in range [-8, 7].");
4985   case Match_InvalidMemoryIndexed2SImm4:
4986     return Error(Loc, "index must be a multiple of 2 in range [-16, 14].");
4987   case Match_InvalidMemoryIndexed3SImm4:
4988     return Error(Loc, "index must be a multiple of 3 in range [-24, 21].");
4989   case Match_InvalidMemoryIndexed4SImm4:
4990     return Error(Loc, "index must be a multiple of 4 in range [-32, 28].");
4991   case Match_InvalidMemoryIndexed16SImm4:
4992     return Error(Loc, "index must be a multiple of 16 in range [-128, 112].");
4993   case Match_InvalidMemoryIndexed32SImm4:
4994     return Error(Loc, "index must be a multiple of 32 in range [-256, 224].");
4995   case Match_InvalidMemoryIndexed1SImm6:
4996     return Error(Loc, "index must be an integer in range [-32, 31].");
4997   case Match_InvalidMemoryIndexedSImm8:
4998     return Error(Loc, "index must be an integer in range [-128, 127].");
4999   case Match_InvalidMemoryIndexedSImm9:
5000     return Error(Loc, "index must be an integer in range [-256, 255].");
5001   case Match_InvalidMemoryIndexed16SImm9:
5002     return Error(Loc, "index must be a multiple of 16 in range [-4096, 4080].");
5003   case Match_InvalidMemoryIndexed8SImm10:
5004     return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088].");
5005   case Match_InvalidMemoryIndexed4SImm7:
5006     return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
5007   case Match_InvalidMemoryIndexed8SImm7:
5008     return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
5009   case Match_InvalidMemoryIndexed16SImm7:
5010     return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
5011   case Match_InvalidMemoryIndexed8UImm5:
5012     return Error(Loc, "index must be a multiple of 8 in range [0, 248].");
5013   case Match_InvalidMemoryIndexed4UImm5:
5014     return Error(Loc, "index must be a multiple of 4 in range [0, 124].");
5015   case Match_InvalidMemoryIndexed2UImm5:
5016     return Error(Loc, "index must be a multiple of 2 in range [0, 62].");
5017   case Match_InvalidMemoryIndexed8UImm6:
5018     return Error(Loc, "index must be a multiple of 8 in range [0, 504].");
5019   case Match_InvalidMemoryIndexed16UImm6:
5020     return Error(Loc, "index must be a multiple of 16 in range [0, 1008].");
5021   case Match_InvalidMemoryIndexed4UImm6:
5022     return Error(Loc, "index must be a multiple of 4 in range [0, 252].");
5023   case Match_InvalidMemoryIndexed2UImm6:
5024     return Error(Loc, "index must be a multiple of 2 in range [0, 126].");
5025   case Match_InvalidMemoryIndexed1UImm6:
5026     return Error(Loc, "index must be in range [0, 63].");
5027   case Match_InvalidMemoryWExtend8:
5028     return Error(Loc,
5029                  "expected 'uxtw' or 'sxtw' with optional shift of #0");
5030   case Match_InvalidMemoryWExtend16:
5031     return Error(Loc,
5032                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5033   case Match_InvalidMemoryWExtend32:
5034     return Error(Loc,
5035                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5036   case Match_InvalidMemoryWExtend64:
5037     return Error(Loc,
5038                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5039   case Match_InvalidMemoryWExtend128:
5040     return Error(Loc,
5041                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5042   case Match_InvalidMemoryXExtend8:
5043     return Error(Loc,
5044                  "expected 'lsl' or 'sxtx' with optional shift of #0");
5045   case Match_InvalidMemoryXExtend16:
5046     return Error(Loc,
5047                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5048   case Match_InvalidMemoryXExtend32:
5049     return Error(Loc,
5050                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5051   case Match_InvalidMemoryXExtend64:
5052     return Error(Loc,
5053                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5054   case Match_InvalidMemoryXExtend128:
5055     return Error(Loc,
5056                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5057   case Match_InvalidMemoryIndexed1:
5058     return Error(Loc, "index must be an integer in range [0, 4095].");
5059   case Match_InvalidMemoryIndexed2:
5060     return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
5061   case Match_InvalidMemoryIndexed4:
5062     return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
5063   case Match_InvalidMemoryIndexed8:
5064     return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
5065   case Match_InvalidMemoryIndexed16:
5066     return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
5067   case Match_InvalidImm0_0:
5068     return Error(Loc, "immediate must be 0.");
5069   case Match_InvalidImm0_1:
5070     return Error(Loc, "immediate must be an integer in range [0, 1].");
5071   case Match_InvalidImm0_3:
5072     return Error(Loc, "immediate must be an integer in range [0, 3].");
5073   case Match_InvalidImm0_7:
5074     return Error(Loc, "immediate must be an integer in range [0, 7].");
5075   case Match_InvalidImm0_15:
5076     return Error(Loc, "immediate must be an integer in range [0, 15].");
5077   case Match_InvalidImm0_31:
5078     return Error(Loc, "immediate must be an integer in range [0, 31].");
5079   case Match_InvalidImm0_63:
5080     return Error(Loc, "immediate must be an integer in range [0, 63].");
5081   case Match_InvalidImm0_127:
5082     return Error(Loc, "immediate must be an integer in range [0, 127].");
5083   case Match_InvalidImm0_255:
5084     return Error(Loc, "immediate must be an integer in range [0, 255].");
5085   case Match_InvalidImm0_65535:
5086     return Error(Loc, "immediate must be an integer in range [0, 65535].");
5087   case Match_InvalidImm1_8:
5088     return Error(Loc, "immediate must be an integer in range [1, 8].");
5089   case Match_InvalidImm1_16:
5090     return Error(Loc, "immediate must be an integer in range [1, 16].");
5091   case Match_InvalidImm1_32:
5092     return Error(Loc, "immediate must be an integer in range [1, 32].");
5093   case Match_InvalidImm1_64:
5094     return Error(Loc, "immediate must be an integer in range [1, 64].");
5095   case Match_InvalidSVEAddSubImm8:
5096     return Error(Loc, "immediate must be an integer in range [0, 255]"
5097                       " with a shift amount of 0");
5098   case Match_InvalidSVEAddSubImm16:
5099   case Match_InvalidSVEAddSubImm32:
5100   case Match_InvalidSVEAddSubImm64:
5101     return Error(Loc, "immediate must be an integer in range [0, 255] or a "
5102                       "multiple of 256 in range [256, 65280]");
5103   case Match_InvalidSVECpyImm8:
5104     return Error(Loc, "immediate must be an integer in range [-128, 255]"
5105                       " with a shift amount of 0");
5106   case Match_InvalidSVECpyImm16:
5107     return Error(Loc, "immediate must be an integer in range [-128, 127] or a "
5108                       "multiple of 256 in range [-32768, 65280]");
5109   case Match_InvalidSVECpyImm32:
5110   case Match_InvalidSVECpyImm64:
5111     return Error(Loc, "immediate must be an integer in range [-128, 127] or a "
5112                       "multiple of 256 in range [-32768, 32512]");
5113   case Match_InvalidIndexRange0_0:
5114     return Error(Loc, "expected lane specifier '[0]'");
5115   case Match_InvalidIndexRange1_1:
5116     return Error(Loc, "expected lane specifier '[1]'");
5117   case Match_InvalidIndexRange0_15:
5118     return Error(Loc, "vector lane must be an integer in range [0, 15].");
5119   case Match_InvalidIndexRange0_7:
5120     return Error(Loc, "vector lane must be an integer in range [0, 7].");
5121   case Match_InvalidIndexRange0_3:
5122     return Error(Loc, "vector lane must be an integer in range [0, 3].");
5123   case Match_InvalidIndexRange0_1:
5124     return Error(Loc, "vector lane must be an integer in range [0, 1].");
5125   case Match_InvalidSVEIndexRange0_63:
5126     return Error(Loc, "vector lane must be an integer in range [0, 63].");
5127   case Match_InvalidSVEIndexRange0_31:
5128     return Error(Loc, "vector lane must be an integer in range [0, 31].");
5129   case Match_InvalidSVEIndexRange0_15:
5130     return Error(Loc, "vector lane must be an integer in range [0, 15].");
5131   case Match_InvalidSVEIndexRange0_7:
5132     return Error(Loc, "vector lane must be an integer in range [0, 7].");
5133   case Match_InvalidSVEIndexRange0_3:
5134     return Error(Loc, "vector lane must be an integer in range [0, 3].");
5135   case Match_InvalidLabel:
5136     return Error(Loc, "expected label or encodable integer pc offset");
5137   case Match_MRS:
5138     return Error(Loc, "expected readable system register");
5139   case Match_MSR:
5140   case Match_InvalidSVCR:
5141     return Error(Loc, "expected writable system register or pstate");
5142   case Match_InvalidComplexRotationEven:
5143     return Error(Loc, "complex rotation must be 0, 90, 180 or 270.");
5144   case Match_InvalidComplexRotationOdd:
5145     return Error(Loc, "complex rotation must be 90 or 270.");
5146   case Match_MnemonicFail: {
5147     std::string Suggestion = AArch64MnemonicSpellCheck(
5148         ((AArch64Operand &)*Operands[0]).getToken(),
5149         ComputeAvailableFeatures(STI->getFeatureBits()));
5150     return Error(Loc, "unrecognized instruction mnemonic" + Suggestion);
5151   }
5152   case Match_InvalidGPR64shifted8:
5153     return Error(Loc, "register must be x0..x30 or xzr, without shift");
5154   case Match_InvalidGPR64shifted16:
5155     return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #1'");
5156   case Match_InvalidGPR64shifted32:
5157     return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #2'");
5158   case Match_InvalidGPR64shifted64:
5159     return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #3'");
5160   case Match_InvalidGPR64shifted128:
5161     return Error(
5162         Loc, "register must be x0..x30 or xzr, with required shift 'lsl #4'");
5163   case Match_InvalidGPR64NoXZRshifted8:
5164     return Error(Loc, "register must be x0..x30 without shift");
5165   case Match_InvalidGPR64NoXZRshifted16:
5166     return Error(Loc, "register must be x0..x30 with required shift 'lsl #1'");
5167   case Match_InvalidGPR64NoXZRshifted32:
5168     return Error(Loc, "register must be x0..x30 with required shift 'lsl #2'");
5169   case Match_InvalidGPR64NoXZRshifted64:
5170     return Error(Loc, "register must be x0..x30 with required shift 'lsl #3'");
5171   case Match_InvalidGPR64NoXZRshifted128:
5172     return Error(Loc, "register must be x0..x30 with required shift 'lsl #4'");
5173   case Match_InvalidZPR32UXTW8:
5174   case Match_InvalidZPR32SXTW8:
5175     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
5176   case Match_InvalidZPR32UXTW16:
5177   case Match_InvalidZPR32SXTW16:
5178     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
5179   case Match_InvalidZPR32UXTW32:
5180   case Match_InvalidZPR32SXTW32:
5181     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
5182   case Match_InvalidZPR32UXTW64:
5183   case Match_InvalidZPR32SXTW64:
5184     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
5185   case Match_InvalidZPR64UXTW8:
5186   case Match_InvalidZPR64SXTW8:
5187     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
5188   case Match_InvalidZPR64UXTW16:
5189   case Match_InvalidZPR64SXTW16:
5190     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
5191   case Match_InvalidZPR64UXTW32:
5192   case Match_InvalidZPR64SXTW32:
5193     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
5194   case Match_InvalidZPR64UXTW64:
5195   case Match_InvalidZPR64SXTW64:
5196     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
5197   case Match_InvalidZPR32LSL8:
5198     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s'");
5199   case Match_InvalidZPR32LSL16:
5200     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
5201   case Match_InvalidZPR32LSL32:
5202     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
5203   case Match_InvalidZPR32LSL64:
5204     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
5205   case Match_InvalidZPR64LSL8:
5206     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d'");
5207   case Match_InvalidZPR64LSL16:
5208     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
5209   case Match_InvalidZPR64LSL32:
5210     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
5211   case Match_InvalidZPR64LSL64:
5212     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
5213   case Match_InvalidZPR0:
5214     return Error(Loc, "expected register without element width suffix");
5215   case Match_InvalidZPR8:
5216   case Match_InvalidZPR16:
5217   case Match_InvalidZPR32:
5218   case Match_InvalidZPR64:
5219   case Match_InvalidZPR128:
5220     return Error(Loc, "invalid element width");
5221   case Match_InvalidZPR_3b8:
5222     return Error(Loc, "Invalid restricted vector register, expected z0.b..z7.b");
5223   case Match_InvalidZPR_3b16:
5224     return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h");
5225   case Match_InvalidZPR_3b32:
5226     return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s");
5227   case Match_InvalidZPR_4b16:
5228     return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h");
5229   case Match_InvalidZPR_4b32:
5230     return Error(Loc, "Invalid restricted vector register, expected z0.s..z15.s");
5231   case Match_InvalidZPR_4b64:
5232     return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d");
5233   case Match_InvalidSVEPattern:
5234     return Error(Loc, "invalid predicate pattern");
5235   case Match_InvalidSVEPredicateAnyReg:
5236   case Match_InvalidSVEPredicateBReg:
5237   case Match_InvalidSVEPredicateHReg:
5238   case Match_InvalidSVEPredicateSReg:
5239   case Match_InvalidSVEPredicateDReg:
5240     return Error(Loc, "invalid predicate register.");
5241   case Match_InvalidSVEPredicate3bAnyReg:
5242     return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)");
5243   case Match_InvalidSVEExactFPImmOperandHalfOne:
5244     return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0.");
5245   case Match_InvalidSVEExactFPImmOperandHalfTwo:
5246     return Error(Loc, "Invalid floating point constant, expected 0.5 or 2.0.");
5247   case Match_InvalidSVEExactFPImmOperandZeroOne:
5248     return Error(Loc, "Invalid floating point constant, expected 0.0 or 1.0.");
5249   case Match_InvalidMatrixTileVectorH8:
5250   case Match_InvalidMatrixTileVectorV8:
5251     return Error(Loc, "invalid matrix operand, expected za0h.b or za0v.b");
5252   case Match_InvalidMatrixTileVectorH16:
5253   case Match_InvalidMatrixTileVectorV16:
5254     return Error(Loc,
5255                  "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
5256   case Match_InvalidMatrixTileVectorH32:
5257   case Match_InvalidMatrixTileVectorV32:
5258     return Error(Loc,
5259                  "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
5260   case Match_InvalidMatrixTileVectorH64:
5261   case Match_InvalidMatrixTileVectorV64:
5262     return Error(Loc,
5263                  "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
5264   case Match_InvalidMatrixTileVectorH128:
5265   case Match_InvalidMatrixTileVectorV128:
5266     return Error(Loc,
5267                  "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
5268   case Match_InvalidMatrixTile32:
5269     return Error(Loc, "invalid matrix operand, expected za[0-3].s");
5270   case Match_InvalidMatrixTile64:
5271     return Error(Loc, "invalid matrix operand, expected za[0-7].d");
5272   case Match_InvalidMatrix:
5273     return Error(Loc, "invalid matrix operand, expected za");
5274   case Match_InvalidMatrixIndexGPR32_12_15:
5275     return Error(Loc, "operand must be a register in range [w12, w15]");
5276   default:
5277     llvm_unreachable("unexpected error code!");
5278   }
5279 }
5280 
5281 static const char *getSubtargetFeatureName(uint64_t Val);
5282 
5283 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5284                                                OperandVector &Operands,
5285                                                MCStreamer &Out,
5286                                                uint64_t &ErrorInfo,
5287                                                bool MatchingInlineAsm) {
5288   assert(!Operands.empty() && "Unexpect empty operand list!");
5289   AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
5290   assert(Op.isToken() && "Leading operand should always be a mnemonic!");
5291 
5292   StringRef Tok = Op.getToken();
5293   unsigned NumOperands = Operands.size();
5294 
5295   if (NumOperands == 4 && Tok == "lsl") {
5296     AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
5297     AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5298     if (Op2.isScalarReg() && Op3.isImm()) {
5299       const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
5300       if (Op3CE) {
5301         uint64_t Op3Val = Op3CE->getValue();
5302         uint64_t NewOp3Val = 0;
5303         uint64_t NewOp4Val = 0;
5304         if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
5305                 Op2.getReg())) {
5306           NewOp3Val = (32 - Op3Val) & 0x1f;
5307           NewOp4Val = 31 - Op3Val;
5308         } else {
5309           NewOp3Val = (64 - Op3Val) & 0x3f;
5310           NewOp4Val = 63 - Op3Val;
5311         }
5312 
5313         const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext());
5314         const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext());
5315 
5316         Operands[0] =
5317             AArch64Operand::CreateToken("ubfm", Op.getStartLoc(), getContext());
5318         Operands.push_back(AArch64Operand::CreateImm(
5319             NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
5320         Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
5321                                                 Op3.getEndLoc(), getContext());
5322       }
5323     }
5324   } else if (NumOperands == 4 && Tok == "bfc") {
5325     // FIXME: Horrible hack to handle BFC->BFM alias.
5326     AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5327     AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]);
5328     AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]);
5329 
5330     if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
5331       const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
5332       const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
5333 
5334       if (LSBCE && WidthCE) {
5335         uint64_t LSB = LSBCE->getValue();
5336         uint64_t Width = WidthCE->getValue();
5337 
5338         uint64_t RegWidth = 0;
5339         if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5340                 Op1.getReg()))
5341           RegWidth = 64;
5342         else
5343           RegWidth = 32;
5344 
5345         if (LSB >= RegWidth)
5346           return Error(LSBOp.getStartLoc(),
5347                        "expected integer in range [0, 31]");
5348         if (Width < 1 || Width > RegWidth)
5349           return Error(WidthOp.getStartLoc(),
5350                        "expected integer in range [1, 32]");
5351 
5352         uint64_t ImmR = 0;
5353         if (RegWidth == 32)
5354           ImmR = (32 - LSB) & 0x1f;
5355         else
5356           ImmR = (64 - LSB) & 0x3f;
5357 
5358         uint64_t ImmS = Width - 1;
5359 
5360         if (ImmR != 0 && ImmS >= ImmR)
5361           return Error(WidthOp.getStartLoc(),
5362                        "requested insert overflows register");
5363 
5364         const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext());
5365         const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext());
5366         Operands[0] =
5367             AArch64Operand::CreateToken("bfm", Op.getStartLoc(), getContext());
5368         Operands[2] = AArch64Operand::CreateReg(
5369             RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
5370             SMLoc(), SMLoc(), getContext());
5371         Operands[3] = AArch64Operand::CreateImm(
5372             ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
5373         Operands.emplace_back(
5374             AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
5375                                       WidthOp.getEndLoc(), getContext()));
5376       }
5377     }
5378   } else if (NumOperands == 5) {
5379     // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
5380     // UBFIZ -> UBFM aliases.
5381     if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
5382       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5383       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5384       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
5385 
5386       if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
5387         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
5388         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
5389 
5390         if (Op3CE && Op4CE) {
5391           uint64_t Op3Val = Op3CE->getValue();
5392           uint64_t Op4Val = Op4CE->getValue();
5393 
5394           uint64_t RegWidth = 0;
5395           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5396                   Op1.getReg()))
5397             RegWidth = 64;
5398           else
5399             RegWidth = 32;
5400 
5401           if (Op3Val >= RegWidth)
5402             return Error(Op3.getStartLoc(),
5403                          "expected integer in range [0, 31]");
5404           if (Op4Val < 1 || Op4Val > RegWidth)
5405             return Error(Op4.getStartLoc(),
5406                          "expected integer in range [1, 32]");
5407 
5408           uint64_t NewOp3Val = 0;
5409           if (RegWidth == 32)
5410             NewOp3Val = (32 - Op3Val) & 0x1f;
5411           else
5412             NewOp3Val = (64 - Op3Val) & 0x3f;
5413 
5414           uint64_t NewOp4Val = Op4Val - 1;
5415 
5416           if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
5417             return Error(Op4.getStartLoc(),
5418                          "requested insert overflows register");
5419 
5420           const MCExpr *NewOp3 =
5421               MCConstantExpr::create(NewOp3Val, getContext());
5422           const MCExpr *NewOp4 =
5423               MCConstantExpr::create(NewOp4Val, getContext());
5424           Operands[3] = AArch64Operand::CreateImm(
5425               NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
5426           Operands[4] = AArch64Operand::CreateImm(
5427               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
5428           if (Tok == "bfi")
5429             Operands[0] = AArch64Operand::CreateToken("bfm", Op.getStartLoc(),
5430                                                       getContext());
5431           else if (Tok == "sbfiz")
5432             Operands[0] = AArch64Operand::CreateToken("sbfm", Op.getStartLoc(),
5433                                                       getContext());
5434           else if (Tok == "ubfiz")
5435             Operands[0] = AArch64Operand::CreateToken("ubfm", Op.getStartLoc(),
5436                                                       getContext());
5437           else
5438             llvm_unreachable("No valid mnemonic for alias?");
5439         }
5440       }
5441 
5442       // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
5443       // UBFX -> UBFM aliases.
5444     } else if (NumOperands == 5 &&
5445                (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
5446       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5447       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5448       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
5449 
5450       if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
5451         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
5452         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
5453 
5454         if (Op3CE && Op4CE) {
5455           uint64_t Op3Val = Op3CE->getValue();
5456           uint64_t Op4Val = Op4CE->getValue();
5457 
5458           uint64_t RegWidth = 0;
5459           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5460                   Op1.getReg()))
5461             RegWidth = 64;
5462           else
5463             RegWidth = 32;
5464 
5465           if (Op3Val >= RegWidth)
5466             return Error(Op3.getStartLoc(),
5467                          "expected integer in range [0, 31]");
5468           if (Op4Val < 1 || Op4Val > RegWidth)
5469             return Error(Op4.getStartLoc(),
5470                          "expected integer in range [1, 32]");
5471 
5472           uint64_t NewOp4Val = Op3Val + Op4Val - 1;
5473 
5474           if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
5475             return Error(Op4.getStartLoc(),
5476                          "requested extract overflows register");
5477 
5478           const MCExpr *NewOp4 =
5479               MCConstantExpr::create(NewOp4Val, getContext());
5480           Operands[4] = AArch64Operand::CreateImm(
5481               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
5482           if (Tok == "bfxil")
5483             Operands[0] = AArch64Operand::CreateToken("bfm", Op.getStartLoc(),
5484                                                       getContext());
5485           else if (Tok == "sbfx")
5486             Operands[0] = AArch64Operand::CreateToken("sbfm", Op.getStartLoc(),
5487                                                       getContext());
5488           else if (Tok == "ubfx")
5489             Operands[0] = AArch64Operand::CreateToken("ubfm", Op.getStartLoc(),
5490                                                       getContext());
5491           else
5492             llvm_unreachable("No valid mnemonic for alias?");
5493         }
5494       }
5495     }
5496   }
5497 
5498   // The Cyclone CPU and early successors didn't execute the zero-cycle zeroing
5499   // instruction for FP registers correctly in some rare circumstances. Convert
5500   // it to a safe instruction and warn (because silently changing someone's
5501   // assembly is rude).
5502   if (getSTI().getFeatureBits()[AArch64::FeatureZCZeroingFPWorkaround] &&
5503       NumOperands == 4 && Tok == "movi") {
5504     AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5505     AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
5506     AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5507     if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
5508         (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
5509       StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
5510       if (Suffix.lower() == ".2d" &&
5511           cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
5512         Warning(IDLoc, "instruction movi.2d with immediate #0 may not function"
5513                 " correctly on this CPU, converting to equivalent movi.16b");
5514         // Switch the suffix to .16b.
5515         unsigned Idx = Op1.isToken() ? 1 : 2;
5516         Operands[Idx] =
5517             AArch64Operand::CreateToken(".16b", IDLoc, getContext());
5518       }
5519     }
5520   }
5521 
5522   // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
5523   //        InstAlias can't quite handle this since the reg classes aren't
5524   //        subclasses.
5525   if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
5526     // The source register can be Wn here, but the matcher expects a
5527     // GPR64. Twiddle it here if necessary.
5528     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
5529     if (Op.isScalarReg()) {
5530       unsigned Reg = getXRegFromWReg(Op.getReg());
5531       Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
5532                                               Op.getStartLoc(), Op.getEndLoc(),
5533                                               getContext());
5534     }
5535   }
5536   // FIXME: Likewise for sxt[bh] with a Xd dst operand
5537   else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
5538     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
5539     if (Op.isScalarReg() &&
5540         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5541             Op.getReg())) {
5542       // The source register can be Wn here, but the matcher expects a
5543       // GPR64. Twiddle it here if necessary.
5544       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
5545       if (Op.isScalarReg()) {
5546         unsigned Reg = getXRegFromWReg(Op.getReg());
5547         Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
5548                                                 Op.getStartLoc(),
5549                                                 Op.getEndLoc(), getContext());
5550       }
5551     }
5552   }
5553   // FIXME: Likewise for uxt[bh] with a Xd dst operand
5554   else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
5555     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
5556     if (Op.isScalarReg() &&
5557         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5558             Op.getReg())) {
5559       // The source register can be Wn here, but the matcher expects a
5560       // GPR32. Twiddle it here if necessary.
5561       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
5562       if (Op.isScalarReg()) {
5563         unsigned Reg = getWRegFromXReg(Op.getReg());
5564         Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
5565                                                 Op.getStartLoc(),
5566                                                 Op.getEndLoc(), getContext());
5567       }
5568     }
5569   }
5570 
5571   MCInst Inst;
5572   FeatureBitset MissingFeatures;
5573   // First try to match against the secondary set of tables containing the
5574   // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
5575   unsigned MatchResult =
5576       MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
5577                            MatchingInlineAsm, 1);
5578 
5579   // If that fails, try against the alternate table containing long-form NEON:
5580   // "fadd v0.2s, v1.2s, v2.2s"
5581   if (MatchResult != Match_Success) {
5582     // But first, save the short-form match result: we can use it in case the
5583     // long-form match also fails.
5584     auto ShortFormNEONErrorInfo = ErrorInfo;
5585     auto ShortFormNEONMatchResult = MatchResult;
5586     auto ShortFormNEONMissingFeatures = MissingFeatures;
5587 
5588     MatchResult =
5589         MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
5590                              MatchingInlineAsm, 0);
5591 
5592     // Now, both matches failed, and the long-form match failed on the mnemonic
5593     // suffix token operand.  The short-form match failure is probably more
5594     // relevant: use it instead.
5595     if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
5596         Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
5597         ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
5598       MatchResult = ShortFormNEONMatchResult;
5599       ErrorInfo = ShortFormNEONErrorInfo;
5600       MissingFeatures = ShortFormNEONMissingFeatures;
5601     }
5602   }
5603 
5604   switch (MatchResult) {
5605   case Match_Success: {
5606     // Perform range checking and other semantic validations
5607     SmallVector<SMLoc, 8> OperandLocs;
5608     NumOperands = Operands.size();
5609     for (unsigned i = 1; i < NumOperands; ++i)
5610       OperandLocs.push_back(Operands[i]->getStartLoc());
5611     if (validateInstruction(Inst, IDLoc, OperandLocs))
5612       return true;
5613 
5614     Inst.setLoc(IDLoc);
5615     Out.emitInstruction(Inst, getSTI());
5616     return false;
5617   }
5618   case Match_MissingFeature: {
5619     assert(MissingFeatures.any() && "Unknown missing feature!");
5620     // Special case the error message for the very common case where only
5621     // a single subtarget feature is missing (neon, e.g.).
5622     std::string Msg = "instruction requires:";
5623     for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
5624       if (MissingFeatures[i]) {
5625         Msg += " ";
5626         Msg += getSubtargetFeatureName(i);
5627       }
5628     }
5629     return Error(IDLoc, Msg);
5630   }
5631   case Match_MnemonicFail:
5632     return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
5633   case Match_InvalidOperand: {
5634     SMLoc ErrorLoc = IDLoc;
5635 
5636     if (ErrorInfo != ~0ULL) {
5637       if (ErrorInfo >= Operands.size())
5638         return Error(IDLoc, "too few operands for instruction",
5639                      SMRange(IDLoc, getTok().getLoc()));
5640 
5641       ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
5642       if (ErrorLoc == SMLoc())
5643         ErrorLoc = IDLoc;
5644     }
5645     // If the match failed on a suffix token operand, tweak the diagnostic
5646     // accordingly.
5647     if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
5648         ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
5649       MatchResult = Match_InvalidSuffix;
5650 
5651     return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
5652   }
5653   case Match_InvalidTiedOperand:
5654   case Match_InvalidMemoryIndexed1:
5655   case Match_InvalidMemoryIndexed2:
5656   case Match_InvalidMemoryIndexed4:
5657   case Match_InvalidMemoryIndexed8:
5658   case Match_InvalidMemoryIndexed16:
5659   case Match_InvalidCondCode:
5660   case Match_AddSubRegExtendSmall:
5661   case Match_AddSubRegExtendLarge:
5662   case Match_AddSubSecondSource:
5663   case Match_LogicalSecondSource:
5664   case Match_AddSubRegShift32:
5665   case Match_AddSubRegShift64:
5666   case Match_InvalidMovImm32Shift:
5667   case Match_InvalidMovImm64Shift:
5668   case Match_InvalidFPImm:
5669   case Match_InvalidMemoryWExtend8:
5670   case Match_InvalidMemoryWExtend16:
5671   case Match_InvalidMemoryWExtend32:
5672   case Match_InvalidMemoryWExtend64:
5673   case Match_InvalidMemoryWExtend128:
5674   case Match_InvalidMemoryXExtend8:
5675   case Match_InvalidMemoryXExtend16:
5676   case Match_InvalidMemoryXExtend32:
5677   case Match_InvalidMemoryXExtend64:
5678   case Match_InvalidMemoryXExtend128:
5679   case Match_InvalidMemoryIndexed1SImm4:
5680   case Match_InvalidMemoryIndexed2SImm4:
5681   case Match_InvalidMemoryIndexed3SImm4:
5682   case Match_InvalidMemoryIndexed4SImm4:
5683   case Match_InvalidMemoryIndexed1SImm6:
5684   case Match_InvalidMemoryIndexed16SImm4:
5685   case Match_InvalidMemoryIndexed32SImm4:
5686   case Match_InvalidMemoryIndexed4SImm7:
5687   case Match_InvalidMemoryIndexed8SImm7:
5688   case Match_InvalidMemoryIndexed16SImm7:
5689   case Match_InvalidMemoryIndexed8UImm5:
5690   case Match_InvalidMemoryIndexed4UImm5:
5691   case Match_InvalidMemoryIndexed2UImm5:
5692   case Match_InvalidMemoryIndexed1UImm6:
5693   case Match_InvalidMemoryIndexed2UImm6:
5694   case Match_InvalidMemoryIndexed4UImm6:
5695   case Match_InvalidMemoryIndexed8UImm6:
5696   case Match_InvalidMemoryIndexed16UImm6:
5697   case Match_InvalidMemoryIndexedSImm6:
5698   case Match_InvalidMemoryIndexedSImm5:
5699   case Match_InvalidMemoryIndexedSImm8:
5700   case Match_InvalidMemoryIndexedSImm9:
5701   case Match_InvalidMemoryIndexed16SImm9:
5702   case Match_InvalidMemoryIndexed8SImm10:
5703   case Match_InvalidImm0_0:
5704   case Match_InvalidImm0_1:
5705   case Match_InvalidImm0_3:
5706   case Match_InvalidImm0_7:
5707   case Match_InvalidImm0_15:
5708   case Match_InvalidImm0_31:
5709   case Match_InvalidImm0_63:
5710   case Match_InvalidImm0_127:
5711   case Match_InvalidImm0_255:
5712   case Match_InvalidImm0_65535:
5713   case Match_InvalidImm1_8:
5714   case Match_InvalidImm1_16:
5715   case Match_InvalidImm1_32:
5716   case Match_InvalidImm1_64:
5717   case Match_InvalidSVEAddSubImm8:
5718   case Match_InvalidSVEAddSubImm16:
5719   case Match_InvalidSVEAddSubImm32:
5720   case Match_InvalidSVEAddSubImm64:
5721   case Match_InvalidSVECpyImm8:
5722   case Match_InvalidSVECpyImm16:
5723   case Match_InvalidSVECpyImm32:
5724   case Match_InvalidSVECpyImm64:
5725   case Match_InvalidIndexRange0_0:
5726   case Match_InvalidIndexRange1_1:
5727   case Match_InvalidIndexRange0_15:
5728   case Match_InvalidIndexRange0_7:
5729   case Match_InvalidIndexRange0_3:
5730   case Match_InvalidIndexRange0_1:
5731   case Match_InvalidSVEIndexRange0_63:
5732   case Match_InvalidSVEIndexRange0_31:
5733   case Match_InvalidSVEIndexRange0_15:
5734   case Match_InvalidSVEIndexRange0_7:
5735   case Match_InvalidSVEIndexRange0_3:
5736   case Match_InvalidLabel:
5737   case Match_InvalidComplexRotationEven:
5738   case Match_InvalidComplexRotationOdd:
5739   case Match_InvalidGPR64shifted8:
5740   case Match_InvalidGPR64shifted16:
5741   case Match_InvalidGPR64shifted32:
5742   case Match_InvalidGPR64shifted64:
5743   case Match_InvalidGPR64shifted128:
5744   case Match_InvalidGPR64NoXZRshifted8:
5745   case Match_InvalidGPR64NoXZRshifted16:
5746   case Match_InvalidGPR64NoXZRshifted32:
5747   case Match_InvalidGPR64NoXZRshifted64:
5748   case Match_InvalidGPR64NoXZRshifted128:
5749   case Match_InvalidZPR32UXTW8:
5750   case Match_InvalidZPR32UXTW16:
5751   case Match_InvalidZPR32UXTW32:
5752   case Match_InvalidZPR32UXTW64:
5753   case Match_InvalidZPR32SXTW8:
5754   case Match_InvalidZPR32SXTW16:
5755   case Match_InvalidZPR32SXTW32:
5756   case Match_InvalidZPR32SXTW64:
5757   case Match_InvalidZPR64UXTW8:
5758   case Match_InvalidZPR64SXTW8:
5759   case Match_InvalidZPR64UXTW16:
5760   case Match_InvalidZPR64SXTW16:
5761   case Match_InvalidZPR64UXTW32:
5762   case Match_InvalidZPR64SXTW32:
5763   case Match_InvalidZPR64UXTW64:
5764   case Match_InvalidZPR64SXTW64:
5765   case Match_InvalidZPR32LSL8:
5766   case Match_InvalidZPR32LSL16:
5767   case Match_InvalidZPR32LSL32:
5768   case Match_InvalidZPR32LSL64:
5769   case Match_InvalidZPR64LSL8:
5770   case Match_InvalidZPR64LSL16:
5771   case Match_InvalidZPR64LSL32:
5772   case Match_InvalidZPR64LSL64:
5773   case Match_InvalidZPR0:
5774   case Match_InvalidZPR8:
5775   case Match_InvalidZPR16:
5776   case Match_InvalidZPR32:
5777   case Match_InvalidZPR64:
5778   case Match_InvalidZPR128:
5779   case Match_InvalidZPR_3b8:
5780   case Match_InvalidZPR_3b16:
5781   case Match_InvalidZPR_3b32:
5782   case Match_InvalidZPR_4b16:
5783   case Match_InvalidZPR_4b32:
5784   case Match_InvalidZPR_4b64:
5785   case Match_InvalidSVEPredicateAnyReg:
5786   case Match_InvalidSVEPattern:
5787   case Match_InvalidSVEPredicateBReg:
5788   case Match_InvalidSVEPredicateHReg:
5789   case Match_InvalidSVEPredicateSReg:
5790   case Match_InvalidSVEPredicateDReg:
5791   case Match_InvalidSVEPredicate3bAnyReg:
5792   case Match_InvalidSVEExactFPImmOperandHalfOne:
5793   case Match_InvalidSVEExactFPImmOperandHalfTwo:
5794   case Match_InvalidSVEExactFPImmOperandZeroOne:
5795   case Match_InvalidMatrixTile32:
5796   case Match_InvalidMatrixTile64:
5797   case Match_InvalidMatrix:
5798   case Match_InvalidMatrixTileVectorH8:
5799   case Match_InvalidMatrixTileVectorH16:
5800   case Match_InvalidMatrixTileVectorH32:
5801   case Match_InvalidMatrixTileVectorH64:
5802   case Match_InvalidMatrixTileVectorH128:
5803   case Match_InvalidMatrixTileVectorV8:
5804   case Match_InvalidMatrixTileVectorV16:
5805   case Match_InvalidMatrixTileVectorV32:
5806   case Match_InvalidMatrixTileVectorV64:
5807   case Match_InvalidMatrixTileVectorV128:
5808   case Match_InvalidSVCR:
5809   case Match_InvalidMatrixIndexGPR32_12_15:
5810   case Match_MSR:
5811   case Match_MRS: {
5812     if (ErrorInfo >= Operands.size())
5813       return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc()));
5814     // Any time we get here, there's nothing fancy to do. Just get the
5815     // operand SMLoc and display the diagnostic.
5816     SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
5817     if (ErrorLoc == SMLoc())
5818       ErrorLoc = IDLoc;
5819     return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
5820   }
5821   }
5822 
5823   llvm_unreachable("Implement any new match types added!");
5824 }
5825 
5826 /// ParseDirective parses the arm specific directives
5827 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
5828   const MCContext::Environment Format = getContext().getObjectFileType();
5829   bool IsMachO = Format == MCContext::IsMachO;
5830   bool IsCOFF = Format == MCContext::IsCOFF;
5831 
5832   auto IDVal = DirectiveID.getIdentifier().lower();
5833   SMLoc Loc = DirectiveID.getLoc();
5834   if (IDVal == ".arch")
5835     parseDirectiveArch(Loc);
5836   else if (IDVal == ".cpu")
5837     parseDirectiveCPU(Loc);
5838   else if (IDVal == ".tlsdesccall")
5839     parseDirectiveTLSDescCall(Loc);
5840   else if (IDVal == ".ltorg" || IDVal == ".pool")
5841     parseDirectiveLtorg(Loc);
5842   else if (IDVal == ".unreq")
5843     parseDirectiveUnreq(Loc);
5844   else if (IDVal == ".inst")
5845     parseDirectiveInst(Loc);
5846   else if (IDVal == ".cfi_negate_ra_state")
5847     parseDirectiveCFINegateRAState();
5848   else if (IDVal == ".cfi_b_key_frame")
5849     parseDirectiveCFIBKeyFrame();
5850   else if (IDVal == ".arch_extension")
5851     parseDirectiveArchExtension(Loc);
5852   else if (IDVal == ".variant_pcs")
5853     parseDirectiveVariantPCS(Loc);
5854   else if (IsMachO) {
5855     if (IDVal == MCLOHDirectiveName())
5856       parseDirectiveLOH(IDVal, Loc);
5857     else
5858       return true;
5859   } else if (IsCOFF) {
5860     if (IDVal == ".seh_stackalloc")
5861       parseDirectiveSEHAllocStack(Loc);
5862     else if (IDVal == ".seh_endprologue")
5863       parseDirectiveSEHPrologEnd(Loc);
5864     else if (IDVal == ".seh_save_r19r20_x")
5865       parseDirectiveSEHSaveR19R20X(Loc);
5866     else if (IDVal == ".seh_save_fplr")
5867       parseDirectiveSEHSaveFPLR(Loc);
5868     else if (IDVal == ".seh_save_fplr_x")
5869       parseDirectiveSEHSaveFPLRX(Loc);
5870     else if (IDVal == ".seh_save_reg")
5871       parseDirectiveSEHSaveReg(Loc);
5872     else if (IDVal == ".seh_save_reg_x")
5873       parseDirectiveSEHSaveRegX(Loc);
5874     else if (IDVal == ".seh_save_regp")
5875       parseDirectiveSEHSaveRegP(Loc);
5876     else if (IDVal == ".seh_save_regp_x")
5877       parseDirectiveSEHSaveRegPX(Loc);
5878     else if (IDVal == ".seh_save_lrpair")
5879       parseDirectiveSEHSaveLRPair(Loc);
5880     else if (IDVal == ".seh_save_freg")
5881       parseDirectiveSEHSaveFReg(Loc);
5882     else if (IDVal == ".seh_save_freg_x")
5883       parseDirectiveSEHSaveFRegX(Loc);
5884     else if (IDVal == ".seh_save_fregp")
5885       parseDirectiveSEHSaveFRegP(Loc);
5886     else if (IDVal == ".seh_save_fregp_x")
5887       parseDirectiveSEHSaveFRegPX(Loc);
5888     else if (IDVal == ".seh_set_fp")
5889       parseDirectiveSEHSetFP(Loc);
5890     else if (IDVal == ".seh_add_fp")
5891       parseDirectiveSEHAddFP(Loc);
5892     else if (IDVal == ".seh_nop")
5893       parseDirectiveSEHNop(Loc);
5894     else if (IDVal == ".seh_save_next")
5895       parseDirectiveSEHSaveNext(Loc);
5896     else if (IDVal == ".seh_startepilogue")
5897       parseDirectiveSEHEpilogStart(Loc);
5898     else if (IDVal == ".seh_endepilogue")
5899       parseDirectiveSEHEpilogEnd(Loc);
5900     else if (IDVal == ".seh_trap_frame")
5901       parseDirectiveSEHTrapFrame(Loc);
5902     else if (IDVal == ".seh_pushframe")
5903       parseDirectiveSEHMachineFrame(Loc);
5904     else if (IDVal == ".seh_context")
5905       parseDirectiveSEHContext(Loc);
5906     else if (IDVal == ".seh_clear_unwound_to_call")
5907       parseDirectiveSEHClearUnwoundToCall(Loc);
5908     else
5909       return true;
5910   } else
5911     return true;
5912   return false;
5913 }
5914 
5915 static void ExpandCryptoAEK(AArch64::ArchKind ArchKind,
5916                             SmallVector<StringRef, 4> &RequestedExtensions) {
5917   const bool NoCrypto = llvm::is_contained(RequestedExtensions, "nocrypto");
5918   const bool Crypto = llvm::is_contained(RequestedExtensions, "crypto");
5919 
5920   if (!NoCrypto && Crypto) {
5921     switch (ArchKind) {
5922     default:
5923       // Map 'generic' (and others) to sha2 and aes, because
5924       // that was the traditional meaning of crypto.
5925     case AArch64::ArchKind::ARMV8_1A:
5926     case AArch64::ArchKind::ARMV8_2A:
5927     case AArch64::ArchKind::ARMV8_3A:
5928       RequestedExtensions.push_back("sha2");
5929       RequestedExtensions.push_back("aes");
5930       break;
5931     case AArch64::ArchKind::ARMV8_4A:
5932     case AArch64::ArchKind::ARMV8_5A:
5933     case AArch64::ArchKind::ARMV8_6A:
5934     case AArch64::ArchKind::ARMV8_7A:
5935     case AArch64::ArchKind::ARMV9A:
5936     case AArch64::ArchKind::ARMV9_1A:
5937     case AArch64::ArchKind::ARMV9_2A:
5938     case AArch64::ArchKind::ARMV8R:
5939       RequestedExtensions.push_back("sm4");
5940       RequestedExtensions.push_back("sha3");
5941       RequestedExtensions.push_back("sha2");
5942       RequestedExtensions.push_back("aes");
5943       break;
5944     }
5945   } else if (NoCrypto) {
5946     switch (ArchKind) {
5947     default:
5948       // Map 'generic' (and others) to sha2 and aes, because
5949       // that was the traditional meaning of crypto.
5950     case AArch64::ArchKind::ARMV8_1A:
5951     case AArch64::ArchKind::ARMV8_2A:
5952     case AArch64::ArchKind::ARMV8_3A:
5953       RequestedExtensions.push_back("nosha2");
5954       RequestedExtensions.push_back("noaes");
5955       break;
5956     case AArch64::ArchKind::ARMV8_4A:
5957     case AArch64::ArchKind::ARMV8_5A:
5958     case AArch64::ArchKind::ARMV8_6A:
5959     case AArch64::ArchKind::ARMV8_7A:
5960     case AArch64::ArchKind::ARMV9A:
5961     case AArch64::ArchKind::ARMV9_1A:
5962     case AArch64::ArchKind::ARMV9_2A:
5963       RequestedExtensions.push_back("nosm4");
5964       RequestedExtensions.push_back("nosha3");
5965       RequestedExtensions.push_back("nosha2");
5966       RequestedExtensions.push_back("noaes");
5967       break;
5968     }
5969   }
5970 }
5971 
5972 /// parseDirectiveArch
5973 ///   ::= .arch token
5974 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
5975   SMLoc ArchLoc = getLoc();
5976 
5977   StringRef Arch, ExtensionString;
5978   std::tie(Arch, ExtensionString) =
5979       getParser().parseStringToEndOfStatement().trim().split('+');
5980 
5981   AArch64::ArchKind ID = AArch64::parseArch(Arch);
5982   if (ID == AArch64::ArchKind::INVALID)
5983     return Error(ArchLoc, "unknown arch name");
5984 
5985   if (parseToken(AsmToken::EndOfStatement))
5986     return true;
5987 
5988   // Get the architecture and extension features.
5989   std::vector<StringRef> AArch64Features;
5990   AArch64::getArchFeatures(ID, AArch64Features);
5991   AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID),
5992                                 AArch64Features);
5993 
5994   MCSubtargetInfo &STI = copySTI();
5995   std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
5996   STI.setDefaultFeatures("generic", /*TuneCPU*/ "generic",
5997                          join(ArchFeatures.begin(), ArchFeatures.end(), ","));
5998 
5999   SmallVector<StringRef, 4> RequestedExtensions;
6000   if (!ExtensionString.empty())
6001     ExtensionString.split(RequestedExtensions, '+');
6002 
6003   ExpandCryptoAEK(ID, RequestedExtensions);
6004 
6005   FeatureBitset Features = STI.getFeatureBits();
6006   for (auto Name : RequestedExtensions) {
6007     bool EnableFeature = true;
6008 
6009     if (Name.startswith_insensitive("no")) {
6010       EnableFeature = false;
6011       Name = Name.substr(2);
6012     }
6013 
6014     for (const auto &Extension : ExtensionMap) {
6015       if (Extension.Name != Name)
6016         continue;
6017 
6018       if (Extension.Features.none())
6019         report_fatal_error("unsupported architectural extension: " + Name);
6020 
6021       FeatureBitset ToggleFeatures = EnableFeature
6022                                          ? (~Features & Extension.Features)
6023                                          : ( Features & Extension.Features);
6024       FeatureBitset Features =
6025           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
6026       setAvailableFeatures(Features);
6027       break;
6028     }
6029   }
6030   return false;
6031 }
6032 
6033 /// parseDirectiveArchExtension
6034 ///   ::= .arch_extension [no]feature
6035 bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
6036   SMLoc ExtLoc = getLoc();
6037 
6038   StringRef Name = getParser().parseStringToEndOfStatement().trim();
6039 
6040   if (parseToken(AsmToken::EndOfStatement,
6041                  "unexpected token in '.arch_extension' directive"))
6042     return true;
6043 
6044   bool EnableFeature = true;
6045   if (Name.startswith_insensitive("no")) {
6046     EnableFeature = false;
6047     Name = Name.substr(2);
6048   }
6049 
6050   MCSubtargetInfo &STI = copySTI();
6051   FeatureBitset Features = STI.getFeatureBits();
6052   for (const auto &Extension : ExtensionMap) {
6053     if (Extension.Name != Name)
6054       continue;
6055 
6056     if (Extension.Features.none())
6057       return Error(ExtLoc, "unsupported architectural extension: " + Name);
6058 
6059     FeatureBitset ToggleFeatures = EnableFeature
6060                                        ? (~Features & Extension.Features)
6061                                        : (Features & Extension.Features);
6062     FeatureBitset Features =
6063         ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
6064     setAvailableFeatures(Features);
6065     return false;
6066   }
6067 
6068   return Error(ExtLoc, "unknown architectural extension: " + Name);
6069 }
6070 
6071 static SMLoc incrementLoc(SMLoc L, int Offset) {
6072   return SMLoc::getFromPointer(L.getPointer() + Offset);
6073 }
6074 
6075 /// parseDirectiveCPU
6076 ///   ::= .cpu id
6077 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
6078   SMLoc CurLoc = getLoc();
6079 
6080   StringRef CPU, ExtensionString;
6081   std::tie(CPU, ExtensionString) =
6082       getParser().parseStringToEndOfStatement().trim().split('+');
6083 
6084   if (parseToken(AsmToken::EndOfStatement))
6085     return true;
6086 
6087   SmallVector<StringRef, 4> RequestedExtensions;
6088   if (!ExtensionString.empty())
6089     ExtensionString.split(RequestedExtensions, '+');
6090 
6091   // FIXME This is using tablegen data, but should be moved to ARMTargetParser
6092   // once that is tablegen'ed
6093   if (!getSTI().isCPUStringValid(CPU)) {
6094     Error(CurLoc, "unknown CPU name");
6095     return false;
6096   }
6097 
6098   MCSubtargetInfo &STI = copySTI();
6099   STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
6100   CurLoc = incrementLoc(CurLoc, CPU.size());
6101 
6102   ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions);
6103 
6104   FeatureBitset Features = STI.getFeatureBits();
6105   for (auto Name : RequestedExtensions) {
6106     // Advance source location past '+'.
6107     CurLoc = incrementLoc(CurLoc, 1);
6108 
6109     bool EnableFeature = true;
6110 
6111     if (Name.startswith_insensitive("no")) {
6112       EnableFeature = false;
6113       Name = Name.substr(2);
6114     }
6115 
6116     bool FoundExtension = false;
6117     for (const auto &Extension : ExtensionMap) {
6118       if (Extension.Name != Name)
6119         continue;
6120 
6121       if (Extension.Features.none())
6122         report_fatal_error("unsupported architectural extension: " + Name);
6123 
6124       FeatureBitset ToggleFeatures = EnableFeature
6125                                          ? (~Features & Extension.Features)
6126                                          : ( Features & Extension.Features);
6127       FeatureBitset Features =
6128           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
6129       setAvailableFeatures(Features);
6130       FoundExtension = true;
6131 
6132       break;
6133     }
6134 
6135     if (!FoundExtension)
6136       Error(CurLoc, "unsupported architectural extension");
6137 
6138     CurLoc = incrementLoc(CurLoc, Name.size());
6139   }
6140   return false;
6141 }
6142 
6143 /// parseDirectiveInst
6144 ///  ::= .inst opcode [, ...]
6145 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
6146   if (getLexer().is(AsmToken::EndOfStatement))
6147     return Error(Loc, "expected expression following '.inst' directive");
6148 
6149   auto parseOp = [&]() -> bool {
6150     SMLoc L = getLoc();
6151     const MCExpr *Expr = nullptr;
6152     if (check(getParser().parseExpression(Expr), L, "expected expression"))
6153       return true;
6154     const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
6155     if (check(!Value, L, "expected constant expression"))
6156       return true;
6157     getTargetStreamer().emitInst(Value->getValue());
6158     return false;
6159   };
6160 
6161   return parseMany(parseOp);
6162 }
6163 
6164 // parseDirectiveTLSDescCall:
6165 //   ::= .tlsdesccall symbol
6166 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
6167   StringRef Name;
6168   if (check(getParser().parseIdentifier(Name), L,
6169             "expected symbol after directive") ||
6170       parseToken(AsmToken::EndOfStatement))
6171     return true;
6172 
6173   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6174   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
6175   Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
6176 
6177   MCInst Inst;
6178   Inst.setOpcode(AArch64::TLSDESCCALL);
6179   Inst.addOperand(MCOperand::createExpr(Expr));
6180 
6181   getParser().getStreamer().emitInstruction(Inst, getSTI());
6182   return false;
6183 }
6184 
6185 /// ::= .loh <lohName | lohId> label1, ..., labelN
6186 /// The number of arguments depends on the loh identifier.
6187 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
6188   MCLOHType Kind;
6189   if (getTok().isNot(AsmToken::Identifier)) {
6190     if (getTok().isNot(AsmToken::Integer))
6191       return TokError("expected an identifier or a number in directive");
6192     // We successfully get a numeric value for the identifier.
6193     // Check if it is valid.
6194     int64_t Id = getTok().getIntVal();
6195     if (Id <= -1U && !isValidMCLOHType(Id))
6196       return TokError("invalid numeric identifier in directive");
6197     Kind = (MCLOHType)Id;
6198   } else {
6199     StringRef Name = getTok().getIdentifier();
6200     // We successfully parse an identifier.
6201     // Check if it is a recognized one.
6202     int Id = MCLOHNameToId(Name);
6203 
6204     if (Id == -1)
6205       return TokError("invalid identifier in directive");
6206     Kind = (MCLOHType)Id;
6207   }
6208   // Consume the identifier.
6209   Lex();
6210   // Get the number of arguments of this LOH.
6211   int NbArgs = MCLOHIdToNbArgs(Kind);
6212 
6213   assert(NbArgs != -1 && "Invalid number of arguments");
6214 
6215   SmallVector<MCSymbol *, 3> Args;
6216   for (int Idx = 0; Idx < NbArgs; ++Idx) {
6217     StringRef Name;
6218     if (getParser().parseIdentifier(Name))
6219       return TokError("expected identifier in directive");
6220     Args.push_back(getContext().getOrCreateSymbol(Name));
6221 
6222     if (Idx + 1 == NbArgs)
6223       break;
6224     if (parseToken(AsmToken::Comma,
6225                    "unexpected token in '" + Twine(IDVal) + "' directive"))
6226       return true;
6227   }
6228   if (parseToken(AsmToken::EndOfStatement,
6229                  "unexpected token in '" + Twine(IDVal) + "' directive"))
6230     return true;
6231 
6232   getStreamer().emitLOHDirective((MCLOHType)Kind, Args);
6233   return false;
6234 }
6235 
6236 /// parseDirectiveLtorg
6237 ///  ::= .ltorg | .pool
6238 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
6239   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
6240     return true;
6241   getTargetStreamer().emitCurrentConstantPool();
6242   return false;
6243 }
6244 
6245 /// parseDirectiveReq
6246 ///  ::= name .req registername
6247 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
6248   Lex(); // Eat the '.req' token.
6249   SMLoc SRegLoc = getLoc();
6250   RegKind RegisterKind = RegKind::Scalar;
6251   unsigned RegNum;
6252   OperandMatchResultTy ParseRes = tryParseScalarRegister(RegNum);
6253 
6254   if (ParseRes != MatchOperand_Success) {
6255     StringRef Kind;
6256     RegisterKind = RegKind::NeonVector;
6257     ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
6258 
6259     if (ParseRes == MatchOperand_ParseFail)
6260       return true;
6261 
6262     if (ParseRes == MatchOperand_Success && !Kind.empty())
6263       return Error(SRegLoc, "vector register without type specifier expected");
6264   }
6265 
6266   if (ParseRes != MatchOperand_Success) {
6267     StringRef Kind;
6268     RegisterKind = RegKind::SVEDataVector;
6269     ParseRes =
6270         tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
6271 
6272     if (ParseRes == MatchOperand_ParseFail)
6273       return true;
6274 
6275     if (ParseRes == MatchOperand_Success && !Kind.empty())
6276       return Error(SRegLoc,
6277                    "sve vector register without type specifier expected");
6278   }
6279 
6280   if (ParseRes != MatchOperand_Success) {
6281     StringRef Kind;
6282     RegisterKind = RegKind::SVEPredicateVector;
6283     ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
6284 
6285     if (ParseRes == MatchOperand_ParseFail)
6286       return true;
6287 
6288     if (ParseRes == MatchOperand_Success && !Kind.empty())
6289       return Error(SRegLoc,
6290                    "sve predicate register without type specifier expected");
6291   }
6292 
6293   if (ParseRes != MatchOperand_Success)
6294     return Error(SRegLoc, "register name or alias expected");
6295 
6296   // Shouldn't be anything else.
6297   if (parseToken(AsmToken::EndOfStatement,
6298                  "unexpected input in .req directive"))
6299     return true;
6300 
6301   auto pair = std::make_pair(RegisterKind, (unsigned) RegNum);
6302   if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
6303     Warning(L, "ignoring redefinition of register alias '" + Name + "'");
6304 
6305   return false;
6306 }
6307 
6308 /// parseDirectiveUneq
6309 ///  ::= .unreq registername
6310 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
6311   if (getTok().isNot(AsmToken::Identifier))
6312     return TokError("unexpected input in .unreq directive.");
6313   RegisterReqs.erase(getTok().getIdentifier().lower());
6314   Lex(); // Eat the identifier.
6315   return parseToken(AsmToken::EndOfStatement);
6316 }
6317 
6318 bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
6319   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
6320     return true;
6321   getStreamer().emitCFINegateRAState();
6322   return false;
6323 }
6324 
6325 /// parseDirectiveCFIBKeyFrame
6326 /// ::= .cfi_b_key
6327 bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
6328   if (parseToken(AsmToken::EndOfStatement,
6329                  "unexpected token in '.cfi_b_key_frame'"))
6330     return true;
6331   getStreamer().emitCFIBKeyFrame();
6332   return false;
6333 }
6334 
6335 /// parseDirectiveVariantPCS
6336 /// ::= .variant_pcs symbolname
6337 bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
6338   const AsmToken &Tok = getTok();
6339   if (Tok.isNot(AsmToken::Identifier))
6340     return TokError("expected symbol name");
6341 
6342   StringRef SymbolName = Tok.getIdentifier();
6343 
6344   MCSymbol *Sym = getContext().lookupSymbol(SymbolName);
6345   if (!Sym)
6346     return TokError("unknown symbol");
6347 
6348   Lex(); // Eat the symbol
6349 
6350   if (parseEOL())
6351     return true;
6352   getTargetStreamer().emitDirectiveVariantPCS(Sym);
6353   return false;
6354 }
6355 
6356 /// parseDirectiveSEHAllocStack
6357 /// ::= .seh_stackalloc
6358 bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
6359   int64_t Size;
6360   if (parseImmExpr(Size))
6361     return true;
6362   getTargetStreamer().emitARM64WinCFIAllocStack(Size);
6363   return false;
6364 }
6365 
6366 /// parseDirectiveSEHPrologEnd
6367 /// ::= .seh_endprologue
6368 bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
6369   getTargetStreamer().emitARM64WinCFIPrologEnd();
6370   return false;
6371 }
6372 
6373 /// parseDirectiveSEHSaveR19R20X
6374 /// ::= .seh_save_r19r20_x
6375 bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
6376   int64_t Offset;
6377   if (parseImmExpr(Offset))
6378     return true;
6379   getTargetStreamer().emitARM64WinCFISaveR19R20X(Offset);
6380   return false;
6381 }
6382 
6383 /// parseDirectiveSEHSaveFPLR
6384 /// ::= .seh_save_fplr
6385 bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
6386   int64_t Offset;
6387   if (parseImmExpr(Offset))
6388     return true;
6389   getTargetStreamer().emitARM64WinCFISaveFPLR(Offset);
6390   return false;
6391 }
6392 
6393 /// parseDirectiveSEHSaveFPLRX
6394 /// ::= .seh_save_fplr_x
6395 bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
6396   int64_t Offset;
6397   if (parseImmExpr(Offset))
6398     return true;
6399   getTargetStreamer().emitARM64WinCFISaveFPLRX(Offset);
6400   return false;
6401 }
6402 
6403 /// parseDirectiveSEHSaveReg
6404 /// ::= .seh_save_reg
6405 bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
6406   unsigned Reg;
6407   int64_t Offset;
6408   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
6409       parseComma() || parseImmExpr(Offset))
6410     return true;
6411   getTargetStreamer().emitARM64WinCFISaveReg(Reg, Offset);
6412   return false;
6413 }
6414 
6415 /// parseDirectiveSEHSaveRegX
6416 /// ::= .seh_save_reg_x
6417 bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
6418   unsigned Reg;
6419   int64_t Offset;
6420   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
6421       parseComma() || parseImmExpr(Offset))
6422     return true;
6423   getTargetStreamer().emitARM64WinCFISaveRegX(Reg, Offset);
6424   return false;
6425 }
6426 
6427 /// parseDirectiveSEHSaveRegP
6428 /// ::= .seh_save_regp
6429 bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
6430   unsigned Reg;
6431   int64_t Offset;
6432   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
6433       parseComma() || parseImmExpr(Offset))
6434     return true;
6435   getTargetStreamer().emitARM64WinCFISaveRegP(Reg, Offset);
6436   return false;
6437 }
6438 
6439 /// parseDirectiveSEHSaveRegPX
6440 /// ::= .seh_save_regp_x
6441 bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
6442   unsigned Reg;
6443   int64_t Offset;
6444   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
6445       parseComma() || parseImmExpr(Offset))
6446     return true;
6447   getTargetStreamer().emitARM64WinCFISaveRegPX(Reg, Offset);
6448   return false;
6449 }
6450 
6451 /// parseDirectiveSEHSaveLRPair
6452 /// ::= .seh_save_lrpair
6453 bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
6454   unsigned Reg;
6455   int64_t Offset;
6456   L = getLoc();
6457   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
6458       parseComma() || parseImmExpr(Offset))
6459     return true;
6460   if (check(((Reg - 19) % 2 != 0), L,
6461             "expected register with even offset from x19"))
6462     return true;
6463   getTargetStreamer().emitARM64WinCFISaveLRPair(Reg, Offset);
6464   return false;
6465 }
6466 
6467 /// parseDirectiveSEHSaveFReg
6468 /// ::= .seh_save_freg
6469 bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
6470   unsigned Reg;
6471   int64_t Offset;
6472   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
6473       parseComma() || parseImmExpr(Offset))
6474     return true;
6475   getTargetStreamer().emitARM64WinCFISaveFReg(Reg, Offset);
6476   return false;
6477 }
6478 
6479 /// parseDirectiveSEHSaveFRegX
6480 /// ::= .seh_save_freg_x
6481 bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
6482   unsigned Reg;
6483   int64_t Offset;
6484   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
6485       parseComma() || parseImmExpr(Offset))
6486     return true;
6487   getTargetStreamer().emitARM64WinCFISaveFRegX(Reg, Offset);
6488   return false;
6489 }
6490 
6491 /// parseDirectiveSEHSaveFRegP
6492 /// ::= .seh_save_fregp
6493 bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
6494   unsigned Reg;
6495   int64_t Offset;
6496   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
6497       parseComma() || parseImmExpr(Offset))
6498     return true;
6499   getTargetStreamer().emitARM64WinCFISaveFRegP(Reg, Offset);
6500   return false;
6501 }
6502 
6503 /// parseDirectiveSEHSaveFRegPX
6504 /// ::= .seh_save_fregp_x
6505 bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
6506   unsigned Reg;
6507   int64_t Offset;
6508   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
6509       parseComma() || parseImmExpr(Offset))
6510     return true;
6511   getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg, Offset);
6512   return false;
6513 }
6514 
6515 /// parseDirectiveSEHSetFP
6516 /// ::= .seh_set_fp
6517 bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
6518   getTargetStreamer().emitARM64WinCFISetFP();
6519   return false;
6520 }
6521 
6522 /// parseDirectiveSEHAddFP
6523 /// ::= .seh_add_fp
6524 bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
6525   int64_t Size;
6526   if (parseImmExpr(Size))
6527     return true;
6528   getTargetStreamer().emitARM64WinCFIAddFP(Size);
6529   return false;
6530 }
6531 
6532 /// parseDirectiveSEHNop
6533 /// ::= .seh_nop
6534 bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
6535   getTargetStreamer().emitARM64WinCFINop();
6536   return false;
6537 }
6538 
6539 /// parseDirectiveSEHSaveNext
6540 /// ::= .seh_save_next
6541 bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
6542   getTargetStreamer().emitARM64WinCFISaveNext();
6543   return false;
6544 }
6545 
6546 /// parseDirectiveSEHEpilogStart
6547 /// ::= .seh_startepilogue
6548 bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
6549   getTargetStreamer().emitARM64WinCFIEpilogStart();
6550   return false;
6551 }
6552 
6553 /// parseDirectiveSEHEpilogEnd
6554 /// ::= .seh_endepilogue
6555 bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
6556   getTargetStreamer().emitARM64WinCFIEpilogEnd();
6557   return false;
6558 }
6559 
6560 /// parseDirectiveSEHTrapFrame
6561 /// ::= .seh_trap_frame
6562 bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
6563   getTargetStreamer().emitARM64WinCFITrapFrame();
6564   return false;
6565 }
6566 
6567 /// parseDirectiveSEHMachineFrame
6568 /// ::= .seh_pushframe
6569 bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
6570   getTargetStreamer().emitARM64WinCFIMachineFrame();
6571   return false;
6572 }
6573 
6574 /// parseDirectiveSEHContext
6575 /// ::= .seh_context
6576 bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
6577   getTargetStreamer().emitARM64WinCFIContext();
6578   return false;
6579 }
6580 
6581 /// parseDirectiveSEHClearUnwoundToCall
6582 /// ::= .seh_clear_unwound_to_call
6583 bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
6584   getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
6585   return false;
6586 }
6587 
6588 bool
6589 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
6590                                     AArch64MCExpr::VariantKind &ELFRefKind,
6591                                     MCSymbolRefExpr::VariantKind &DarwinRefKind,
6592                                     int64_t &Addend) {
6593   ELFRefKind = AArch64MCExpr::VK_INVALID;
6594   DarwinRefKind = MCSymbolRefExpr::VK_None;
6595   Addend = 0;
6596 
6597   if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
6598     ELFRefKind = AE->getKind();
6599     Expr = AE->getSubExpr();
6600   }
6601 
6602   const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
6603   if (SE) {
6604     // It's a simple symbol reference with no addend.
6605     DarwinRefKind = SE->getKind();
6606     return true;
6607   }
6608 
6609   // Check that it looks like a symbol + an addend
6610   MCValue Res;
6611   bool Relocatable = Expr->evaluateAsRelocatable(Res, nullptr, nullptr);
6612   if (!Relocatable || Res.getSymB())
6613     return false;
6614 
6615   // Treat expressions with an ELFRefKind (like ":abs_g1:3", or
6616   // ":abs_g1:x" where x is constant) as symbolic even if there is no symbol.
6617   if (!Res.getSymA() && ELFRefKind == AArch64MCExpr::VK_INVALID)
6618     return false;
6619 
6620   if (Res.getSymA())
6621     DarwinRefKind = Res.getSymA()->getKind();
6622   Addend = Res.getConstant();
6623 
6624   // It's some symbol reference + a constant addend, but really
6625   // shouldn't use both Darwin and ELF syntax.
6626   return ELFRefKind == AArch64MCExpr::VK_INVALID ||
6627          DarwinRefKind == MCSymbolRefExpr::VK_None;
6628 }
6629 
6630 /// Force static initialization.
6631 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser() {
6632   RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget());
6633   RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget());
6634   RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target());
6635   RegisterMCAsmParser<AArch64AsmParser> W(getTheARM64_32Target());
6636   RegisterMCAsmParser<AArch64AsmParser> V(getTheAArch64_32Target());
6637 }
6638 
6639 #define GET_REGISTER_MATCHER
6640 #define GET_SUBTARGET_FEATURE_NAME
6641 #define GET_MATCHER_IMPLEMENTATION
6642 #define GET_MNEMONIC_SPELL_CHECKER
6643 #include "AArch64GenAsmMatcher.inc"
6644 
6645 // Define this matcher function after the auto-generated include so we
6646 // have the match class enum definitions.
6647 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
6648                                                       unsigned Kind) {
6649   AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
6650   // If the kind is a token for a literal immediate, check if our asm
6651   // operand matches. This is for InstAliases which have a fixed-value
6652   // immediate in the syntax.
6653   int64_t ExpectedVal;
6654   switch (Kind) {
6655   default:
6656     return Match_InvalidOperand;
6657   case MCK__HASH_0:
6658     ExpectedVal = 0;
6659     break;
6660   case MCK__HASH_1:
6661     ExpectedVal = 1;
6662     break;
6663   case MCK__HASH_12:
6664     ExpectedVal = 12;
6665     break;
6666   case MCK__HASH_16:
6667     ExpectedVal = 16;
6668     break;
6669   case MCK__HASH_2:
6670     ExpectedVal = 2;
6671     break;
6672   case MCK__HASH_24:
6673     ExpectedVal = 24;
6674     break;
6675   case MCK__HASH_3:
6676     ExpectedVal = 3;
6677     break;
6678   case MCK__HASH_32:
6679     ExpectedVal = 32;
6680     break;
6681   case MCK__HASH_4:
6682     ExpectedVal = 4;
6683     break;
6684   case MCK__HASH_48:
6685     ExpectedVal = 48;
6686     break;
6687   case MCK__HASH_6:
6688     ExpectedVal = 6;
6689     break;
6690   case MCK__HASH_64:
6691     ExpectedVal = 64;
6692     break;
6693   case MCK__HASH_8:
6694     ExpectedVal = 8;
6695     break;
6696   case MCK_MPR:
6697     // If the Kind is a token for the MPR register class which has the "za"
6698     // register (SME accumulator array), check if the asm is a literal "za"
6699     // token. This is for the "smstart za" alias that defines the register
6700     // as a literal token.
6701     if (Op.isTokenEqual("za"))
6702       return Match_Success;
6703     break;
6704   }
6705   if (!Op.isImm())
6706     return Match_InvalidOperand;
6707   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
6708   if (!CE)
6709     return Match_InvalidOperand;
6710   if (CE->getValue() == ExpectedVal)
6711     return Match_Success;
6712   return Match_InvalidOperand;
6713 }
6714 
6715 OperandMatchResultTy
6716 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
6717 
6718   SMLoc S = getLoc();
6719 
6720   if (getTok().isNot(AsmToken::Identifier)) {
6721     Error(S, "expected register");
6722     return MatchOperand_ParseFail;
6723   }
6724 
6725   unsigned FirstReg;
6726   OperandMatchResultTy Res = tryParseScalarRegister(FirstReg);
6727   if (Res != MatchOperand_Success)
6728     return MatchOperand_ParseFail;
6729 
6730   const MCRegisterClass &WRegClass =
6731       AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
6732   const MCRegisterClass &XRegClass =
6733       AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
6734 
6735   bool isXReg = XRegClass.contains(FirstReg),
6736        isWReg = WRegClass.contains(FirstReg);
6737   if (!isXReg && !isWReg) {
6738     Error(S, "expected first even register of a "
6739              "consecutive same-size even/odd register pair");
6740     return MatchOperand_ParseFail;
6741   }
6742 
6743   const MCRegisterInfo *RI = getContext().getRegisterInfo();
6744   unsigned FirstEncoding = RI->getEncodingValue(FirstReg);
6745 
6746   if (FirstEncoding & 0x1) {
6747     Error(S, "expected first even register of a "
6748              "consecutive same-size even/odd register pair");
6749     return MatchOperand_ParseFail;
6750   }
6751 
6752   if (getTok().isNot(AsmToken::Comma)) {
6753     Error(getLoc(), "expected comma");
6754     return MatchOperand_ParseFail;
6755   }
6756   // Eat the comma
6757   Lex();
6758 
6759   SMLoc E = getLoc();
6760   unsigned SecondReg;
6761   Res = tryParseScalarRegister(SecondReg);
6762   if (Res != MatchOperand_Success)
6763     return MatchOperand_ParseFail;
6764 
6765   if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 ||
6766       (isXReg && !XRegClass.contains(SecondReg)) ||
6767       (isWReg && !WRegClass.contains(SecondReg))) {
6768     Error(E,"expected second odd register of a "
6769              "consecutive same-size even/odd register pair");
6770     return MatchOperand_ParseFail;
6771   }
6772 
6773   unsigned Pair = 0;
6774   if (isXReg) {
6775     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64,
6776            &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
6777   } else {
6778     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32,
6779            &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
6780   }
6781 
6782   Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
6783       getLoc(), getContext()));
6784 
6785   return MatchOperand_Success;
6786 }
6787 
6788 template <bool ParseShiftExtend, bool ParseSuffix>
6789 OperandMatchResultTy
6790 AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) {
6791   const SMLoc S = getLoc();
6792   // Check for a SVE vector register specifier first.
6793   unsigned RegNum;
6794   StringRef Kind;
6795 
6796   OperandMatchResultTy Res =
6797       tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
6798 
6799   if (Res != MatchOperand_Success)
6800     return Res;
6801 
6802   if (ParseSuffix && Kind.empty())
6803     return MatchOperand_NoMatch;
6804 
6805   const auto &KindRes = parseVectorKind(Kind, RegKind::SVEDataVector);
6806   if (!KindRes)
6807     return MatchOperand_NoMatch;
6808 
6809   unsigned ElementWidth = KindRes->second;
6810 
6811   // No shift/extend is the default.
6812   if (!ParseShiftExtend || getTok().isNot(AsmToken::Comma)) {
6813     Operands.push_back(AArch64Operand::CreateVectorReg(
6814         RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
6815 
6816     OperandMatchResultTy Res = tryParseVectorIndex(Operands);
6817     if (Res == MatchOperand_ParseFail)
6818       return MatchOperand_ParseFail;
6819     return MatchOperand_Success;
6820   }
6821 
6822   // Eat the comma
6823   Lex();
6824 
6825   // Match the shift
6826   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd;
6827   Res = tryParseOptionalShiftExtend(ExtOpnd);
6828   if (Res != MatchOperand_Success)
6829     return Res;
6830 
6831   auto Ext = static_cast<AArch64Operand *>(ExtOpnd.back().get());
6832   Operands.push_back(AArch64Operand::CreateVectorReg(
6833       RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
6834       getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
6835       Ext->hasShiftExtendAmount()));
6836 
6837   return MatchOperand_Success;
6838 }
6839 
6840 OperandMatchResultTy
6841 AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) {
6842   MCAsmParser &Parser = getParser();
6843 
6844   SMLoc SS = getLoc();
6845   const AsmToken &TokE = getTok();
6846   bool IsHash = TokE.is(AsmToken::Hash);
6847 
6848   if (!IsHash && TokE.isNot(AsmToken::Identifier))
6849     return MatchOperand_NoMatch;
6850 
6851   int64_t Pattern;
6852   if (IsHash) {
6853     Lex(); // Eat hash
6854 
6855     // Parse the immediate operand.
6856     const MCExpr *ImmVal;
6857     SS = getLoc();
6858     if (Parser.parseExpression(ImmVal))
6859       return MatchOperand_ParseFail;
6860 
6861     auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
6862     if (!MCE)
6863       return MatchOperand_ParseFail;
6864 
6865     Pattern = MCE->getValue();
6866   } else {
6867     // Parse the pattern
6868     auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.getString());
6869     if (!Pat)
6870       return MatchOperand_NoMatch;
6871 
6872     Lex();
6873     Pattern = Pat->Encoding;
6874     assert(Pattern >= 0 && Pattern < 32);
6875   }
6876 
6877   Operands.push_back(
6878       AArch64Operand::CreateImm(MCConstantExpr::create(Pattern, getContext()),
6879                                 SS, getLoc(), getContext()));
6880 
6881   return MatchOperand_Success;
6882 }
6883 
6884 OperandMatchResultTy
6885 AArch64AsmParser::tryParseGPR64x8(OperandVector &Operands) {
6886   SMLoc SS = getLoc();
6887 
6888   unsigned XReg;
6889   if (tryParseScalarRegister(XReg) != MatchOperand_Success)
6890     return MatchOperand_NoMatch;
6891 
6892   MCContext &ctx = getContext();
6893   const MCRegisterInfo *RI = ctx.getRegisterInfo();
6894   int X8Reg = RI->getMatchingSuperReg(
6895       XReg, AArch64::x8sub_0,
6896       &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
6897   if (!X8Reg) {
6898     Error(SS, "expected an even-numbered x-register in the range [x0,x22]");
6899     return MatchOperand_ParseFail;
6900   }
6901 
6902   Operands.push_back(
6903       AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
6904   return MatchOperand_Success;
6905 }
6906