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 "MCTargetDesc/AArch64AddressingModes.h"
10 #include "MCTargetDesc/AArch64InstPrinter.h"
11 #include "MCTargetDesc/AArch64MCExpr.h"
12 #include "MCTargetDesc/AArch64MCTargetDesc.h"
13 #include "MCTargetDesc/AArch64TargetStreamer.h"
14 #include "TargetInfo/AArch64TargetInfo.h"
15 #include "AArch64InstrInfo.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/SubtargetFeature.h"
44 #include "llvm/MC/MCValue.h"
45 #include "llvm/Support/Casting.h"
46 #include "llvm/Support/Compiler.h"
47 #include "llvm/Support/ErrorHandling.h"
48 #include "llvm/Support/MathExtras.h"
49 #include "llvm/Support/SMLoc.h"
50 #include "llvm/Support/TargetParser.h"
51 #include "llvm/Support/TargetRegistry.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   MCAsmParser &Parser = getParser();
2676   const AsmToken &Tok = getTok();
2677   if (Tok.isNot(AsmToken::Identifier))
2678     return MatchOperand_NoMatch;
2679 
2680   std::string lowerCase = Tok.getString().lower();
2681   unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
2682   if (Reg == 0)
2683     return MatchOperand_NoMatch;
2684 
2685   RegNum = Reg;
2686   Parser.Lex(); // Eat identifier token.
2687   return MatchOperand_Success;
2688 }
2689 
2690 /// tryParseSysCROperand - Try to parse a system instruction CR operand name.
2691 OperandMatchResultTy
2692 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
2693   MCAsmParser &Parser = getParser();
2694   SMLoc S = getLoc();
2695 
2696   if (getTok().isNot(AsmToken::Identifier)) {
2697     Error(S, "Expected cN operand where 0 <= N <= 15");
2698     return MatchOperand_ParseFail;
2699   }
2700 
2701   StringRef Tok = getTok().getIdentifier();
2702   if (Tok[0] != 'c' && Tok[0] != 'C') {
2703     Error(S, "Expected cN operand where 0 <= N <= 15");
2704     return MatchOperand_ParseFail;
2705   }
2706 
2707   uint32_t CRNum;
2708   bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
2709   if (BadNum || CRNum > 15) {
2710     Error(S, "Expected cN operand where 0 <= N <= 15");
2711     return MatchOperand_ParseFail;
2712   }
2713 
2714   Parser.Lex(); // Eat identifier token.
2715   Operands.push_back(
2716       AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
2717   return MatchOperand_Success;
2718 }
2719 
2720 /// tryParsePrefetch - Try to parse a prefetch operand.
2721 template <bool IsSVEPrefetch>
2722 OperandMatchResultTy
2723 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
2724   MCAsmParser &Parser = getParser();
2725   SMLoc S = getLoc();
2726   const AsmToken &Tok = getTok();
2727 
2728   auto LookupByName = [](StringRef N) {
2729     if (IsSVEPrefetch) {
2730       if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(N))
2731         return Optional<unsigned>(Res->Encoding);
2732     } else if (auto Res = AArch64PRFM::lookupPRFMByName(N))
2733       return Optional<unsigned>(Res->Encoding);
2734     return Optional<unsigned>();
2735   };
2736 
2737   auto LookupByEncoding = [](unsigned E) {
2738     if (IsSVEPrefetch) {
2739       if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(E))
2740         return Optional<StringRef>(Res->Name);
2741     } else if (auto Res = AArch64PRFM::lookupPRFMByEncoding(E))
2742       return Optional<StringRef>(Res->Name);
2743     return Optional<StringRef>();
2744   };
2745   unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
2746 
2747   // Either an identifier for named values or a 5-bit immediate.
2748   // Eat optional hash.
2749   if (parseOptionalToken(AsmToken::Hash) ||
2750       Tok.is(AsmToken::Integer)) {
2751     const MCExpr *ImmVal;
2752     if (getParser().parseExpression(ImmVal))
2753       return MatchOperand_ParseFail;
2754 
2755     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2756     if (!MCE) {
2757       TokError("immediate value expected for prefetch operand");
2758       return MatchOperand_ParseFail;
2759     }
2760     unsigned prfop = MCE->getValue();
2761     if (prfop > MaxVal) {
2762       TokError("prefetch operand out of range, [0," + utostr(MaxVal) +
2763                "] expected");
2764       return MatchOperand_ParseFail;
2765     }
2766 
2767     auto PRFM = LookupByEncoding(MCE->getValue());
2768     Operands.push_back(AArch64Operand::CreatePrefetch(
2769         prfop, PRFM.getValueOr(""), S, getContext()));
2770     return MatchOperand_Success;
2771   }
2772 
2773   if (Tok.isNot(AsmToken::Identifier)) {
2774     TokError("prefetch hint expected");
2775     return MatchOperand_ParseFail;
2776   }
2777 
2778   auto PRFM = LookupByName(Tok.getString());
2779   if (!PRFM) {
2780     TokError("prefetch hint expected");
2781     return MatchOperand_ParseFail;
2782   }
2783 
2784   Operands.push_back(AArch64Operand::CreatePrefetch(
2785       *PRFM, Tok.getString(), S, getContext()));
2786   Parser.Lex(); // Eat identifier token.
2787   return MatchOperand_Success;
2788 }
2789 
2790 /// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command
2791 OperandMatchResultTy
2792 AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) {
2793   MCAsmParser &Parser = getParser();
2794   SMLoc S = getLoc();
2795   const AsmToken &Tok = getTok();
2796   if (Tok.isNot(AsmToken::Identifier)) {
2797     TokError("invalid operand for instruction");
2798     return MatchOperand_ParseFail;
2799   }
2800 
2801   auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString());
2802   if (!PSB) {
2803     TokError("invalid operand for instruction");
2804     return MatchOperand_ParseFail;
2805   }
2806 
2807   Operands.push_back(AArch64Operand::CreatePSBHint(
2808       PSB->Encoding, Tok.getString(), S, getContext()));
2809   Parser.Lex(); // Eat identifier token.
2810   return MatchOperand_Success;
2811 }
2812 
2813 /// tryParseBTIHint - Try to parse a BTI operand, mapped to Hint command
2814 OperandMatchResultTy
2815 AArch64AsmParser::tryParseBTIHint(OperandVector &Operands) {
2816   MCAsmParser &Parser = getParser();
2817   SMLoc S = getLoc();
2818   const AsmToken &Tok = getTok();
2819   if (Tok.isNot(AsmToken::Identifier)) {
2820     TokError("invalid operand for instruction");
2821     return MatchOperand_ParseFail;
2822   }
2823 
2824   auto BTI = AArch64BTIHint::lookupBTIByName(Tok.getString());
2825   if (!BTI) {
2826     TokError("invalid operand for instruction");
2827     return MatchOperand_ParseFail;
2828   }
2829 
2830   Operands.push_back(AArch64Operand::CreateBTIHint(
2831       BTI->Encoding, Tok.getString(), S, getContext()));
2832   Parser.Lex(); // Eat identifier token.
2833   return MatchOperand_Success;
2834 }
2835 
2836 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2837 /// instruction.
2838 OperandMatchResultTy
2839 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2840   MCAsmParser &Parser = getParser();
2841   SMLoc S = getLoc();
2842   const MCExpr *Expr = nullptr;
2843 
2844   if (getTok().is(AsmToken::Hash)) {
2845     Parser.Lex(); // Eat hash token.
2846   }
2847 
2848   if (parseSymbolicImmVal(Expr))
2849     return MatchOperand_ParseFail;
2850 
2851   AArch64MCExpr::VariantKind ELFRefKind;
2852   MCSymbolRefExpr::VariantKind DarwinRefKind;
2853   int64_t Addend;
2854   if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2855     if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2856         ELFRefKind == AArch64MCExpr::VK_INVALID) {
2857       // No modifier was specified at all; this is the syntax for an ELF basic
2858       // ADRP relocation (unfortunately).
2859       Expr =
2860           AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
2861     } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2862                 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2863                Addend != 0) {
2864       Error(S, "gotpage label reference not allowed an addend");
2865       return MatchOperand_ParseFail;
2866     } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2867                DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2868                DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2869                ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
2870                ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
2871                ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
2872                ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
2873                ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
2874       // The operand must be an @page or @gotpage qualified symbolref.
2875       Error(S, "page or gotpage label reference expected");
2876       return MatchOperand_ParseFail;
2877     }
2878   }
2879 
2880   // We have either a label reference possibly with addend or an immediate. The
2881   // addend is a raw value here. The linker will adjust it to only reference the
2882   // page.
2883   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2884   Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2885 
2886   return MatchOperand_Success;
2887 }
2888 
2889 /// tryParseAdrLabel - Parse and validate a source label for the ADR
2890 /// instruction.
2891 OperandMatchResultTy
2892 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2893   SMLoc S = getLoc();
2894   const MCExpr *Expr = nullptr;
2895 
2896   // Leave anything with a bracket to the default for SVE
2897   if (getTok().is(AsmToken::LBrac))
2898     return MatchOperand_NoMatch;
2899 
2900   if (getTok().is(AsmToken::Hash))
2901     getParser().Lex(); // Eat hash token.
2902 
2903   if (parseSymbolicImmVal(Expr))
2904     return MatchOperand_ParseFail;
2905 
2906   AArch64MCExpr::VariantKind ELFRefKind;
2907   MCSymbolRefExpr::VariantKind DarwinRefKind;
2908   int64_t Addend;
2909   if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2910     if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2911         ELFRefKind == AArch64MCExpr::VK_INVALID) {
2912       // No modifier was specified at all; this is the syntax for an ELF basic
2913       // ADR relocation (unfortunately).
2914       Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext());
2915     } else {
2916       Error(S, "unexpected adr label");
2917       return MatchOperand_ParseFail;
2918     }
2919   }
2920 
2921   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2922   Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2923   return MatchOperand_Success;
2924 }
2925 
2926 /// tryParseFPImm - A floating point immediate expression operand.
2927 template<bool AddFPZeroAsLiteral>
2928 OperandMatchResultTy
2929 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
2930   MCAsmParser &Parser = getParser();
2931   SMLoc S = getLoc();
2932 
2933   bool Hash = parseOptionalToken(AsmToken::Hash);
2934 
2935   // Handle negation, as that still comes through as a separate token.
2936   bool isNegative = parseOptionalToken(AsmToken::Minus);
2937 
2938   const AsmToken &Tok = getTok();
2939   if (!Tok.is(AsmToken::Real) && !Tok.is(AsmToken::Integer)) {
2940     if (!Hash)
2941       return MatchOperand_NoMatch;
2942     TokError("invalid floating point immediate");
2943     return MatchOperand_ParseFail;
2944   }
2945 
2946   // Parse hexadecimal representation.
2947   if (Tok.is(AsmToken::Integer) && Tok.getString().startswith("0x")) {
2948     if (Tok.getIntVal() > 255 || isNegative) {
2949       TokError("encoded floating point value out of range");
2950       return MatchOperand_ParseFail;
2951     }
2952 
2953     APFloat F((double)AArch64_AM::getFPImmFloat(Tok.getIntVal()));
2954     Operands.push_back(
2955         AArch64Operand::CreateFPImm(F, true, S, getContext()));
2956   } else {
2957     // Parse FP representation.
2958     APFloat RealVal(APFloat::IEEEdouble());
2959     auto StatusOrErr =
2960         RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero);
2961     if (errorToBool(StatusOrErr.takeError())) {
2962       TokError("invalid floating point representation");
2963       return MatchOperand_ParseFail;
2964     }
2965 
2966     if (isNegative)
2967       RealVal.changeSign();
2968 
2969     if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
2970       Operands.push_back(AArch64Operand::CreateToken("#0", S, getContext()));
2971       Operands.push_back(AArch64Operand::CreateToken(".0", S, getContext()));
2972     } else
2973       Operands.push_back(AArch64Operand::CreateFPImm(
2974           RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
2975   }
2976 
2977   Parser.Lex(); // Eat the token.
2978 
2979   return MatchOperand_Success;
2980 }
2981 
2982 /// tryParseImmWithOptionalShift - Parse immediate operand, optionally with
2983 /// a shift suffix, for example '#1, lsl #12'.
2984 OperandMatchResultTy
2985 AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) {
2986   MCAsmParser &Parser = getParser();
2987   SMLoc S = getLoc();
2988 
2989   if (getTok().is(AsmToken::Hash))
2990     Parser.Lex(); // Eat '#'
2991   else if (getTok().isNot(AsmToken::Integer))
2992     // Operand should start from # or should be integer, emit error otherwise.
2993     return MatchOperand_NoMatch;
2994 
2995   const MCExpr *Imm = nullptr;
2996   if (parseSymbolicImmVal(Imm))
2997     return MatchOperand_ParseFail;
2998   else if (getTok().isNot(AsmToken::Comma)) {
2999     Operands.push_back(
3000         AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3001     return MatchOperand_Success;
3002   }
3003 
3004   // Eat ','
3005   Parser.Lex();
3006 
3007   // The optional operand must be "lsl #N" where N is non-negative.
3008   if (!getTok().is(AsmToken::Identifier) ||
3009       !getTok().getIdentifier().equals_insensitive("lsl")) {
3010     Error(getLoc(), "only 'lsl #+N' valid after immediate");
3011     return MatchOperand_ParseFail;
3012   }
3013 
3014   // Eat 'lsl'
3015   Parser.Lex();
3016 
3017   parseOptionalToken(AsmToken::Hash);
3018 
3019   if (getTok().isNot(AsmToken::Integer)) {
3020     Error(getLoc(), "only 'lsl #+N' valid after immediate");
3021     return MatchOperand_ParseFail;
3022   }
3023 
3024   int64_t ShiftAmount = getTok().getIntVal();
3025 
3026   if (ShiftAmount < 0) {
3027     Error(getLoc(), "positive shift amount required");
3028     return MatchOperand_ParseFail;
3029   }
3030   Parser.Lex(); // Eat the number
3031 
3032   // Just in case the optional lsl #0 is used for immediates other than zero.
3033   if (ShiftAmount == 0 && Imm != nullptr) {
3034     Operands.push_back(
3035         AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3036     return MatchOperand_Success;
3037   }
3038 
3039   Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3040                                                       getLoc(), getContext()));
3041   return MatchOperand_Success;
3042 }
3043 
3044 /// parseCondCodeString - Parse a Condition Code string.
3045 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
3046   AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
3047                     .Case("eq", AArch64CC::EQ)
3048                     .Case("ne", AArch64CC::NE)
3049                     .Case("cs", AArch64CC::HS)
3050                     .Case("hs", AArch64CC::HS)
3051                     .Case("cc", AArch64CC::LO)
3052                     .Case("lo", AArch64CC::LO)
3053                     .Case("mi", AArch64CC::MI)
3054                     .Case("pl", AArch64CC::PL)
3055                     .Case("vs", AArch64CC::VS)
3056                     .Case("vc", AArch64CC::VC)
3057                     .Case("hi", AArch64CC::HI)
3058                     .Case("ls", AArch64CC::LS)
3059                     .Case("ge", AArch64CC::GE)
3060                     .Case("lt", AArch64CC::LT)
3061                     .Case("gt", AArch64CC::GT)
3062                     .Case("le", AArch64CC::LE)
3063                     .Case("al", AArch64CC::AL)
3064                     .Case("nv", AArch64CC::NV)
3065                     .Default(AArch64CC::Invalid);
3066 
3067   if (CC == AArch64CC::Invalid &&
3068       getSTI().getFeatureBits()[AArch64::FeatureSVE])
3069     CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
3070                     .Case("none",  AArch64CC::EQ)
3071                     .Case("any",   AArch64CC::NE)
3072                     .Case("nlast", AArch64CC::HS)
3073                     .Case("last",  AArch64CC::LO)
3074                     .Case("first", AArch64CC::MI)
3075                     .Case("nfrst", AArch64CC::PL)
3076                     .Case("pmore", AArch64CC::HI)
3077                     .Case("plast", AArch64CC::LS)
3078                     .Case("tcont", AArch64CC::GE)
3079                     .Case("tstop", AArch64CC::LT)
3080                     .Default(AArch64CC::Invalid);
3081 
3082   return CC;
3083 }
3084 
3085 /// parseCondCode - Parse a Condition Code operand.
3086 bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
3087                                      bool invertCondCode) {
3088   MCAsmParser &Parser = getParser();
3089   SMLoc S = getLoc();
3090   const AsmToken &Tok = getTok();
3091   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3092 
3093   StringRef Cond = Tok.getString();
3094   AArch64CC::CondCode CC = parseCondCodeString(Cond);
3095   if (CC == AArch64CC::Invalid)
3096     return TokError("invalid condition code");
3097   Parser.Lex(); // Eat identifier token.
3098 
3099   if (invertCondCode) {
3100     if (CC == AArch64CC::AL || CC == AArch64CC::NV)
3101       return TokError("condition codes AL and NV are invalid for this instruction");
3102     CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
3103   }
3104 
3105   Operands.push_back(
3106       AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
3107   return false;
3108 }
3109 
3110 OperandMatchResultTy
3111 AArch64AsmParser::tryParseSVCR(OperandVector &Operands) {
3112   MCAsmParser &Parser = getParser();
3113   const AsmToken &Tok = getTok();
3114   SMLoc S = getLoc();
3115 
3116   if (Tok.isNot(AsmToken::Identifier)) {
3117     TokError("invalid operand for instruction");
3118     return MatchOperand_ParseFail;
3119   }
3120 
3121   unsigned PStateImm = -1;
3122   const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.getString());
3123   if (SVCR && SVCR->haveFeatures(getSTI().getFeatureBits()))
3124     PStateImm = SVCR->Encoding;
3125 
3126   Operands.push_back(
3127       AArch64Operand::CreateSVCR(PStateImm, Tok.getString(), S, getContext()));
3128   Parser.Lex(); // Eat identifier token.
3129   return MatchOperand_Success;
3130 }
3131 
3132 OperandMatchResultTy
3133 AArch64AsmParser::tryParseMatrixRegister(OperandVector &Operands) {
3134   MCAsmParser &Parser = getParser();
3135   const AsmToken &Tok = getTok();
3136   SMLoc S = getLoc();
3137 
3138   StringRef Name = Tok.getString();
3139 
3140   if (Name.equals_insensitive("za")) {
3141     Parser.Lex(); // eat "za"
3142     Operands.push_back(AArch64Operand::CreateMatrixRegister(
3143         AArch64::ZA, /*ElementWidth=*/0, MatrixKind::Array, S, getLoc(),
3144         getContext()));
3145     if (getLexer().is(AsmToken::LBrac)) {
3146       // There's no comma after matrix operand, so we can parse the next operand
3147       // immediately.
3148       if (parseOperand(Operands, false, false))
3149         return MatchOperand_NoMatch;
3150     }
3151     return MatchOperand_Success;
3152   }
3153 
3154   // Try to parse matrix register.
3155   unsigned Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3156   if (!Reg)
3157     return MatchOperand_NoMatch;
3158 
3159   size_t DotPosition = Name.find('.');
3160   assert(DotPosition != StringRef::npos && "Unexpected register");
3161 
3162   StringRef Head = Name.take_front(DotPosition);
3163   StringRef Tail = Name.drop_front(DotPosition);
3164   StringRef RowOrColumn = Head.take_back();
3165 
3166   MatrixKind Kind = StringSwitch<MatrixKind>(RowOrColumn)
3167                         .Case("h", MatrixKind::Row)
3168                         .Case("v", MatrixKind::Col)
3169                         .Default(MatrixKind::Tile);
3170 
3171   // Next up, parsing the suffix
3172   const auto &KindRes = parseVectorKind(Tail, RegKind::Matrix);
3173   if (!KindRes) {
3174     TokError("Expected the register to be followed by element width suffix");
3175     return MatchOperand_ParseFail;
3176   }
3177   unsigned ElementWidth = KindRes->second;
3178 
3179   Parser.Lex();
3180 
3181   Operands.push_back(AArch64Operand::CreateMatrixRegister(
3182       Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3183 
3184   if (getLexer().is(AsmToken::LBrac)) {
3185     // There's no comma after matrix operand, so we can parse the next operand
3186     // immediately.
3187     if (parseOperand(Operands, false, false))
3188       return MatchOperand_NoMatch;
3189   }
3190   return MatchOperand_Success;
3191 }
3192 
3193 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse
3194 /// them if present.
3195 OperandMatchResultTy
3196 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
3197   MCAsmParser &Parser = getParser();
3198   const AsmToken &Tok = getTok();
3199   std::string LowerID = Tok.getString().lower();
3200   AArch64_AM::ShiftExtendType ShOp =
3201       StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3202           .Case("lsl", AArch64_AM::LSL)
3203           .Case("lsr", AArch64_AM::LSR)
3204           .Case("asr", AArch64_AM::ASR)
3205           .Case("ror", AArch64_AM::ROR)
3206           .Case("msl", AArch64_AM::MSL)
3207           .Case("uxtb", AArch64_AM::UXTB)
3208           .Case("uxth", AArch64_AM::UXTH)
3209           .Case("uxtw", AArch64_AM::UXTW)
3210           .Case("uxtx", AArch64_AM::UXTX)
3211           .Case("sxtb", AArch64_AM::SXTB)
3212           .Case("sxth", AArch64_AM::SXTH)
3213           .Case("sxtw", AArch64_AM::SXTW)
3214           .Case("sxtx", AArch64_AM::SXTX)
3215           .Default(AArch64_AM::InvalidShiftExtend);
3216 
3217   if (ShOp == AArch64_AM::InvalidShiftExtend)
3218     return MatchOperand_NoMatch;
3219 
3220   SMLoc S = Tok.getLoc();
3221   Parser.Lex();
3222 
3223   bool Hash = parseOptionalToken(AsmToken::Hash);
3224 
3225   if (!Hash && getLexer().isNot(AsmToken::Integer)) {
3226     if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
3227         ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
3228         ShOp == AArch64_AM::MSL) {
3229       // We expect a number here.
3230       TokError("expected #imm after shift specifier");
3231       return MatchOperand_ParseFail;
3232     }
3233 
3234     // "extend" type operations don't need an immediate, #0 is implicit.
3235     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3236     Operands.push_back(
3237         AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
3238     return MatchOperand_Success;
3239   }
3240 
3241   // Make sure we do actually have a number, identifier or a parenthesized
3242   // expression.
3243   SMLoc E = getLoc();
3244   if (!getTok().is(AsmToken::Integer) && !getTok().is(AsmToken::LParen) &&
3245       !getTok().is(AsmToken::Identifier)) {
3246     Error(E, "expected integer shift amount");
3247     return MatchOperand_ParseFail;
3248   }
3249 
3250   const MCExpr *ImmVal;
3251   if (getParser().parseExpression(ImmVal))
3252     return MatchOperand_ParseFail;
3253 
3254   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3255   if (!MCE) {
3256     Error(E, "expected constant '#imm' after shift specifier");
3257     return MatchOperand_ParseFail;
3258   }
3259 
3260   E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3261   Operands.push_back(AArch64Operand::CreateShiftExtend(
3262       ShOp, MCE->getValue(), true, S, E, getContext()));
3263   return MatchOperand_Success;
3264 }
3265 
3266 static const struct Extension {
3267   const char *Name;
3268   const FeatureBitset Features;
3269 } ExtensionMap[] = {
3270     {"crc", {AArch64::FeatureCRC}},
3271     {"sm4", {AArch64::FeatureSM4}},
3272     {"sha3", {AArch64::FeatureSHA3}},
3273     {"sha2", {AArch64::FeatureSHA2}},
3274     {"aes", {AArch64::FeatureAES}},
3275     {"crypto", {AArch64::FeatureCrypto}},
3276     {"fp", {AArch64::FeatureFPARMv8}},
3277     {"simd", {AArch64::FeatureNEON}},
3278     {"ras", {AArch64::FeatureRAS}},
3279     {"lse", {AArch64::FeatureLSE}},
3280     {"predres", {AArch64::FeaturePredRes}},
3281     {"ccdp", {AArch64::FeatureCacheDeepPersist}},
3282     {"mte", {AArch64::FeatureMTE}},
3283     {"memtag", {AArch64::FeatureMTE}},
3284     {"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3285     {"pan", {AArch64::FeaturePAN}},
3286     {"pan-rwv", {AArch64::FeaturePAN_RWV}},
3287     {"ccpp", {AArch64::FeatureCCPP}},
3288     {"rcpc", {AArch64::FeatureRCPC}},
3289     {"rng", {AArch64::FeatureRandGen}},
3290     {"sve", {AArch64::FeatureSVE}},
3291     {"sve2", {AArch64::FeatureSVE2}},
3292     {"sve2-aes", {AArch64::FeatureSVE2AES}},
3293     {"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3294     {"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3295     {"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
3296     {"ls64", {AArch64::FeatureLS64}},
3297     {"xs", {AArch64::FeatureXS}},
3298     {"pauth", {AArch64::FeaturePAuth}},
3299     {"flagm", {AArch64::FeatureFlagM}},
3300     {"rme", {AArch64::FeatureRME}},
3301     {"sme", {AArch64::FeatureSME}},
3302     {"sme-f64", {AArch64::FeatureSMEF64}},
3303     {"sme-i64", {AArch64::FeatureSMEI64}},
3304     // FIXME: Unsupported extensions
3305     {"lor", {}},
3306     {"rdma", {}},
3307     {"profile", {}},
3308 };
3309 
3310 static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
3311   if (FBS[AArch64::HasV8_1aOps])
3312     Str += "ARMv8.1a";
3313   else if (FBS[AArch64::HasV8_2aOps])
3314     Str += "ARMv8.2a";
3315   else if (FBS[AArch64::HasV8_3aOps])
3316     Str += "ARMv8.3a";
3317   else if (FBS[AArch64::HasV8_4aOps])
3318     Str += "ARMv8.4a";
3319   else if (FBS[AArch64::HasV8_5aOps])
3320     Str += "ARMv8.5a";
3321   else if (FBS[AArch64::HasV8_6aOps])
3322     Str += "ARMv8.6a";
3323   else if (FBS[AArch64::HasV8_7aOps])
3324     Str += "ARMv8.7a";
3325   else {
3326     SmallVector<std::string, 2> ExtMatches;
3327     for (const auto& Ext : ExtensionMap) {
3328       // Use & in case multiple features are enabled
3329       if ((FBS & Ext.Features) != FeatureBitset())
3330         ExtMatches.push_back(Ext.Name);
3331     }
3332     Str += !ExtMatches.empty() ? llvm::join(ExtMatches, ", ") : "(unknown)";
3333   }
3334 }
3335 
3336 void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands,
3337                                       SMLoc S) {
3338   const uint16_t Op2 = Encoding & 7;
3339   const uint16_t Cm = (Encoding & 0x78) >> 3;
3340   const uint16_t Cn = (Encoding & 0x780) >> 7;
3341   const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3342 
3343   const MCExpr *Expr = MCConstantExpr::create(Op1, getContext());
3344 
3345   Operands.push_back(
3346       AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3347   Operands.push_back(
3348       AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3349   Operands.push_back(
3350       AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3351   Expr = MCConstantExpr::create(Op2, getContext());
3352   Operands.push_back(
3353       AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3354 }
3355 
3356 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
3357 /// the SYS instruction. Parse them specially so that we create a SYS MCInst.
3358 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3359                                    OperandVector &Operands) {
3360   if (Name.find('.') != StringRef::npos)
3361     return TokError("invalid operand");
3362 
3363   Mnemonic = Name;
3364   Operands.push_back(AArch64Operand::CreateToken("sys", NameLoc, getContext()));
3365 
3366   MCAsmParser &Parser = getParser();
3367   const AsmToken &Tok = getTok();
3368   StringRef Op = Tok.getString();
3369   SMLoc S = Tok.getLoc();
3370 
3371   if (Mnemonic == "ic") {
3372     const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op);
3373     if (!IC)
3374       return TokError("invalid operand for IC instruction");
3375     else if (!IC->haveFeatures(getSTI().getFeatureBits())) {
3376       std::string Str("IC " + std::string(IC->Name) + " requires: ");
3377       setRequiredFeatureString(IC->getRequiredFeatures(), Str);
3378       return TokError(Str.c_str());
3379     }
3380     createSysAlias(IC->Encoding, Operands, S);
3381   } else if (Mnemonic == "dc") {
3382     const AArch64DC::DC *DC = AArch64DC::lookupDCByName(Op);
3383     if (!DC)
3384       return TokError("invalid operand for DC instruction");
3385     else if (!DC->haveFeatures(getSTI().getFeatureBits())) {
3386       std::string Str("DC " + std::string(DC->Name) + " requires: ");
3387       setRequiredFeatureString(DC->getRequiredFeatures(), Str);
3388       return TokError(Str.c_str());
3389     }
3390     createSysAlias(DC->Encoding, Operands, S);
3391   } else if (Mnemonic == "at") {
3392     const AArch64AT::AT *AT = AArch64AT::lookupATByName(Op);
3393     if (!AT)
3394       return TokError("invalid operand for AT instruction");
3395     else if (!AT->haveFeatures(getSTI().getFeatureBits())) {
3396       std::string Str("AT " + std::string(AT->Name) + " requires: ");
3397       setRequiredFeatureString(AT->getRequiredFeatures(), Str);
3398       return TokError(Str.c_str());
3399     }
3400     createSysAlias(AT->Encoding, Operands, S);
3401   } else if (Mnemonic == "tlbi") {
3402     const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(Op);
3403     if (!TLBI)
3404       return TokError("invalid operand for TLBI instruction");
3405     else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) {
3406       std::string Str("TLBI " + std::string(TLBI->Name) + " requires: ");
3407       setRequiredFeatureString(TLBI->getRequiredFeatures(), Str);
3408       return TokError(Str.c_str());
3409     }
3410     createSysAlias(TLBI->Encoding, Operands, S);
3411   } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp") {
3412     const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByName(Op);
3413     if (!PRCTX)
3414       return TokError("invalid operand for prediction restriction instruction");
3415     else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) {
3416       std::string Str(
3417           Mnemonic.upper() + std::string(PRCTX->Name) + " requires: ");
3418       setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str);
3419       return TokError(Str.c_str());
3420     }
3421     uint16_t PRCTX_Op2 =
3422       Mnemonic == "cfp" ? 4 :
3423       Mnemonic == "dvp" ? 5 :
3424       Mnemonic == "cpp" ? 7 :
3425       0;
3426     assert(PRCTX_Op2 && "Invalid mnemonic for prediction restriction instruction");
3427     createSysAlias(PRCTX->Encoding << 3 | PRCTX_Op2 , Operands, S);
3428   }
3429 
3430   Parser.Lex(); // Eat operand.
3431 
3432   bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
3433   bool HasRegister = false;
3434 
3435   // Check for the optional register operand.
3436   if (parseOptionalToken(AsmToken::Comma)) {
3437     if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
3438       return TokError("expected register operand");
3439     HasRegister = true;
3440   }
3441 
3442   if (ExpectRegister && !HasRegister)
3443     return TokError("specified " + Mnemonic + " op requires a register");
3444   else if (!ExpectRegister && HasRegister)
3445     return TokError("specified " + Mnemonic + " op does not use a register");
3446 
3447   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
3448     return true;
3449 
3450   return false;
3451 }
3452 
3453 OperandMatchResultTy
3454 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
3455   MCAsmParser &Parser = getParser();
3456   const AsmToken &Tok = getTok();
3457 
3458   if (Mnemonic == "tsb" && Tok.isNot(AsmToken::Identifier)) {
3459     TokError("'csync' operand expected");
3460     return MatchOperand_ParseFail;
3461   } else if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
3462     // Immediate operand.
3463     const MCExpr *ImmVal;
3464     SMLoc ExprLoc = getLoc();
3465     AsmToken IntTok = Tok;
3466     if (getParser().parseExpression(ImmVal))
3467       return MatchOperand_ParseFail;
3468     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3469     if (!MCE) {
3470       Error(ExprLoc, "immediate value expected for barrier operand");
3471       return MatchOperand_ParseFail;
3472     }
3473     int64_t Value = MCE->getValue();
3474     if (Mnemonic == "dsb" && Value > 15) {
3475       // This case is a no match here, but it might be matched by the nXS
3476       // variant. Deliberately not unlex the optional '#' as it is not necessary
3477       // to characterize an integer immediate.
3478       Parser.getLexer().UnLex(IntTok);
3479       return MatchOperand_NoMatch;
3480     }
3481     if (Value < 0 || Value > 15) {
3482       Error(ExprLoc, "barrier operand out of range");
3483       return MatchOperand_ParseFail;
3484     }
3485     auto DB = AArch64DB::lookupDBByEncoding(Value);
3486     Operands.push_back(AArch64Operand::CreateBarrier(Value, DB ? DB->Name : "",
3487                                                      ExprLoc, getContext(),
3488                                                      false /*hasnXSModifier*/));
3489     return MatchOperand_Success;
3490   }
3491 
3492   if (Tok.isNot(AsmToken::Identifier)) {
3493     TokError("invalid operand for instruction");
3494     return MatchOperand_ParseFail;
3495   }
3496 
3497   StringRef Operand = Tok.getString();
3498   auto TSB = AArch64TSB::lookupTSBByName(Operand);
3499   auto DB = AArch64DB::lookupDBByName(Operand);
3500   // The only valid named option for ISB is 'sy'
3501   if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) {
3502     TokError("'sy' or #imm operand expected");
3503     return MatchOperand_ParseFail;
3504   // The only valid named option for TSB is 'csync'
3505   } else if (Mnemonic == "tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync)) {
3506     TokError("'csync' operand expected");
3507     return MatchOperand_ParseFail;
3508   } else if (!DB && !TSB) {
3509     if (Mnemonic == "dsb") {
3510       // This case is a no match here, but it might be matched by the nXS
3511       // variant.
3512       return MatchOperand_NoMatch;
3513     }
3514     TokError("invalid barrier option name");
3515     return MatchOperand_ParseFail;
3516   }
3517 
3518   Operands.push_back(AArch64Operand::CreateBarrier(
3519       DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(),
3520       getContext(), false /*hasnXSModifier*/));
3521   Parser.Lex(); // Consume the option
3522 
3523   return MatchOperand_Success;
3524 }
3525 
3526 OperandMatchResultTy
3527 AArch64AsmParser::tryParseBarriernXSOperand(OperandVector &Operands) {
3528   MCAsmParser &Parser = getParser();
3529   const AsmToken &Tok = getTok();
3530 
3531   assert(Mnemonic == "dsb" && "Instruction does not accept nXS operands");
3532   if (Mnemonic != "dsb")
3533     return MatchOperand_ParseFail;
3534 
3535   if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
3536     // Immediate operand.
3537     const MCExpr *ImmVal;
3538     SMLoc ExprLoc = getLoc();
3539     if (getParser().parseExpression(ImmVal))
3540       return MatchOperand_ParseFail;
3541     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3542     if (!MCE) {
3543       Error(ExprLoc, "immediate value expected for barrier operand");
3544       return MatchOperand_ParseFail;
3545     }
3546     int64_t Value = MCE->getValue();
3547     // v8.7-A DSB in the nXS variant accepts only the following immediate
3548     // values: 16, 20, 24, 28.
3549     if (Value != 16 && Value != 20 && Value != 24 && Value != 28) {
3550       Error(ExprLoc, "barrier operand out of range");
3551       return MatchOperand_ParseFail;
3552     }
3553     auto DB = AArch64DBnXS::lookupDBnXSByImmValue(Value);
3554     Operands.push_back(AArch64Operand::CreateBarrier(DB->Encoding, DB->Name,
3555                                                      ExprLoc, getContext(),
3556                                                      true /*hasnXSModifier*/));
3557     return MatchOperand_Success;
3558   }
3559 
3560   if (Tok.isNot(AsmToken::Identifier)) {
3561     TokError("invalid operand for instruction");
3562     return MatchOperand_ParseFail;
3563   }
3564 
3565   StringRef Operand = Tok.getString();
3566   auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
3567 
3568   if (!DB) {
3569     TokError("invalid barrier option name");
3570     return MatchOperand_ParseFail;
3571   }
3572 
3573   Operands.push_back(
3574       AArch64Operand::CreateBarrier(DB->Encoding, Tok.getString(), getLoc(),
3575                                     getContext(), true /*hasnXSModifier*/));
3576   Parser.Lex(); // Consume the option
3577 
3578   return MatchOperand_Success;
3579 }
3580 
3581 OperandMatchResultTy
3582 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
3583   MCAsmParser &Parser = getParser();
3584   const AsmToken &Tok = getTok();
3585 
3586   if (Tok.isNot(AsmToken::Identifier))
3587     return MatchOperand_NoMatch;
3588 
3589   if (AArch64SVCR::lookupSVCRByName(Tok.getString()))
3590     return MatchOperand_NoMatch;
3591 
3592   int MRSReg, MSRReg;
3593   auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString());
3594   if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
3595     MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
3596     MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
3597   } else
3598     MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString());
3599 
3600   auto PState = AArch64PState::lookupPStateByName(Tok.getString());
3601   unsigned PStateImm = -1;
3602   if (PState && PState->haveFeatures(getSTI().getFeatureBits()))
3603     PStateImm = PState->Encoding;
3604 
3605   Operands.push_back(
3606       AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg,
3607                                    PStateImm, getContext()));
3608   Parser.Lex(); // Eat identifier
3609 
3610   return MatchOperand_Success;
3611 }
3612 
3613 /// tryParseNeonVectorRegister - Parse a vector register operand.
3614 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) {
3615   if (getTok().isNot(AsmToken::Identifier))
3616     return true;
3617 
3618   SMLoc S = getLoc();
3619   // Check for a vector register specifier first.
3620   StringRef Kind;
3621   unsigned Reg;
3622   OperandMatchResultTy Res =
3623       tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
3624   if (Res != MatchOperand_Success)
3625     return true;
3626 
3627   const auto &KindRes = parseVectorKind(Kind, RegKind::NeonVector);
3628   if (!KindRes)
3629     return true;
3630 
3631   unsigned ElementWidth = KindRes->second;
3632   Operands.push_back(
3633       AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
3634                                       S, getLoc(), getContext()));
3635 
3636   // If there was an explicit qualifier, that goes on as a literal text
3637   // operand.
3638   if (!Kind.empty())
3639     Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
3640 
3641   return tryParseVectorIndex(Operands) == MatchOperand_ParseFail;
3642 }
3643 
3644 OperandMatchResultTy
3645 AArch64AsmParser::tryParseVectorIndex(OperandVector &Operands) {
3646   SMLoc SIdx = getLoc();
3647   if (parseOptionalToken(AsmToken::LBrac)) {
3648     const MCExpr *ImmVal;
3649     if (getParser().parseExpression(ImmVal))
3650       return MatchOperand_NoMatch;
3651     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3652     if (!MCE) {
3653       TokError("immediate value expected for vector index");
3654       return MatchOperand_ParseFail;;
3655     }
3656 
3657     SMLoc E = getLoc();
3658 
3659     if (parseToken(AsmToken::RBrac, "']' expected"))
3660       return MatchOperand_ParseFail;;
3661 
3662     Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
3663                                                          E, getContext()));
3664     return MatchOperand_Success;
3665   }
3666 
3667   return MatchOperand_NoMatch;
3668 }
3669 
3670 // tryParseVectorRegister - Try to parse a vector register name with
3671 // optional kind specifier. If it is a register specifier, eat the token
3672 // and return it.
3673 OperandMatchResultTy
3674 AArch64AsmParser::tryParseVectorRegister(unsigned &Reg, StringRef &Kind,
3675                                          RegKind MatchKind) {
3676   MCAsmParser &Parser = getParser();
3677   const AsmToken &Tok = getTok();
3678 
3679   if (Tok.isNot(AsmToken::Identifier))
3680     return MatchOperand_NoMatch;
3681 
3682   StringRef Name = Tok.getString();
3683   // If there is a kind specifier, it's separated from the register name by
3684   // a '.'.
3685   size_t Start = 0, Next = Name.find('.');
3686   StringRef Head = Name.slice(Start, Next);
3687   unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
3688 
3689   if (RegNum) {
3690     if (Next != StringRef::npos) {
3691       Kind = Name.slice(Next, StringRef::npos);
3692       if (!isValidVectorKind(Kind, MatchKind)) {
3693         TokError("invalid vector kind qualifier");
3694         return MatchOperand_ParseFail;
3695       }
3696     }
3697     Parser.Lex(); // Eat the register token.
3698 
3699     Reg = RegNum;
3700     return MatchOperand_Success;
3701   }
3702 
3703   return MatchOperand_NoMatch;
3704 }
3705 
3706 /// tryParseSVEPredicateVector - Parse a SVE predicate register operand.
3707 OperandMatchResultTy
3708 AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) {
3709   // Check for a SVE predicate register specifier first.
3710   const SMLoc S = getLoc();
3711   StringRef Kind;
3712   unsigned RegNum;
3713   auto Res = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
3714   if (Res != MatchOperand_Success)
3715     return Res;
3716 
3717   const auto &KindRes = parseVectorKind(Kind, RegKind::SVEPredicateVector);
3718   if (!KindRes)
3719     return MatchOperand_NoMatch;
3720 
3721   unsigned ElementWidth = KindRes->second;
3722   Operands.push_back(AArch64Operand::CreateVectorReg(
3723       RegNum, RegKind::SVEPredicateVector, ElementWidth, S,
3724       getLoc(), getContext()));
3725 
3726   if (getLexer().is(AsmToken::LBrac)) {
3727     // Indexed predicate, there's no comma so try parse the next operand
3728     // immediately.
3729     if (parseOperand(Operands, false, false))
3730       return MatchOperand_NoMatch;
3731   }
3732 
3733   // Not all predicates are followed by a '/m' or '/z'.
3734   MCAsmParser &Parser = getParser();
3735   if (getTok().isNot(AsmToken::Slash))
3736     return MatchOperand_Success;
3737 
3738   // But when they do they shouldn't have an element type suffix.
3739   if (!Kind.empty()) {
3740     Error(S, "not expecting size suffix");
3741     return MatchOperand_ParseFail;
3742   }
3743 
3744   // Add a literal slash as operand
3745   Operands.push_back(AArch64Operand::CreateToken("/", getLoc(), getContext()));
3746 
3747   Parser.Lex(); // Eat the slash.
3748 
3749   // Zeroing or merging?
3750   auto Pred = getTok().getString().lower();
3751   if (Pred != "z" && Pred != "m") {
3752     Error(getLoc(), "expecting 'm' or 'z' predication");
3753     return MatchOperand_ParseFail;
3754   }
3755 
3756   // Add zero/merge token.
3757   const char *ZM = Pred == "z" ? "z" : "m";
3758   Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
3759 
3760   Parser.Lex(); // Eat zero/merge token.
3761   return MatchOperand_Success;
3762 }
3763 
3764 /// parseRegister - Parse a register operand.
3765 bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
3766   // Try for a Neon vector register.
3767   if (!tryParseNeonVectorRegister(Operands))
3768     return false;
3769 
3770   // Otherwise try for a scalar register.
3771   if (tryParseGPROperand<false>(Operands) == MatchOperand_Success)
3772     return false;
3773 
3774   return true;
3775 }
3776 
3777 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
3778   MCAsmParser &Parser = getParser();
3779   bool HasELFModifier = false;
3780   AArch64MCExpr::VariantKind RefKind;
3781 
3782   if (parseOptionalToken(AsmToken::Colon)) {
3783     HasELFModifier = true;
3784 
3785     if (getTok().isNot(AsmToken::Identifier))
3786       return TokError("expect relocation specifier in operand after ':'");
3787 
3788     std::string LowerCase = getTok().getIdentifier().lower();
3789     RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
3790                   .Case("lo12", AArch64MCExpr::VK_LO12)
3791                   .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
3792                   .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
3793                   .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
3794                   .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
3795                   .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
3796                   .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
3797                   .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
3798                   .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
3799                   .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
3800                   .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
3801                   .Case("prel_g3", AArch64MCExpr::VK_PREL_G3)
3802                   .Case("prel_g2", AArch64MCExpr::VK_PREL_G2)
3803                   .Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC)
3804                   .Case("prel_g1", AArch64MCExpr::VK_PREL_G1)
3805                   .Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC)
3806                   .Case("prel_g0", AArch64MCExpr::VK_PREL_G0)
3807                   .Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC)
3808                   .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
3809                   .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
3810                   .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
3811                   .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
3812                   .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
3813                   .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
3814                   .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
3815                   .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
3816                   .Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC)
3817                   .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
3818                   .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
3819                   .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
3820                   .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
3821                   .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
3822                   .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
3823                   .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
3824                   .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
3825                   .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
3826                   .Case("got", AArch64MCExpr::VK_GOT_PAGE)
3827                   .Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
3828                   .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
3829                   .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
3830                   .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
3831                   .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
3832                   .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
3833                   .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
3834                   .Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12)
3835                   .Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12)
3836                   .Default(AArch64MCExpr::VK_INVALID);
3837 
3838     if (RefKind == AArch64MCExpr::VK_INVALID)
3839       return TokError("expect relocation specifier in operand after ':'");
3840 
3841     Parser.Lex(); // Eat identifier
3842 
3843     if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier"))
3844       return true;
3845   }
3846 
3847   if (getParser().parseExpression(ImmVal))
3848     return true;
3849 
3850   if (HasELFModifier)
3851     ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext());
3852 
3853   return false;
3854 }
3855 
3856 OperandMatchResultTy
3857 AArch64AsmParser::tryParseMatrixTileList(OperandVector &Operands) {
3858   MCAsmParser &Parser = getParser();
3859 
3860   if (Parser.getTok().isNot(AsmToken::LCurly))
3861     return MatchOperand_NoMatch;
3862 
3863   auto ParseMatrixTile = [this, &Parser](unsigned &Reg,
3864                                          unsigned &ElementWidth) {
3865     StringRef Name = Parser.getTok().getString();
3866     size_t DotPosition = Name.find('.');
3867     if (DotPosition == StringRef::npos)
3868       return MatchOperand_NoMatch;
3869 
3870     unsigned RegNum = matchMatrixTileListRegName(Name);
3871     if (!RegNum)
3872       return MatchOperand_NoMatch;
3873 
3874     StringRef Tail = Name.drop_front(DotPosition);
3875     const Optional<std::pair<int, int>> &KindRes =
3876         parseVectorKind(Tail, RegKind::Matrix);
3877     if (!KindRes) {
3878       TokError("Expected the register to be followed by element width suffix");
3879       return MatchOperand_ParseFail;
3880     }
3881     ElementWidth = KindRes->second;
3882     Reg = RegNum;
3883     Parser.Lex(); // Eat the register.
3884     return MatchOperand_Success;
3885   };
3886 
3887   SMLoc S = getLoc();
3888   auto LCurly = Parser.getTok();
3889   Parser.Lex(); // Eat left bracket token.
3890 
3891   // Empty matrix list
3892   if (parseOptionalToken(AsmToken::RCurly)) {
3893     Operands.push_back(AArch64Operand::CreateMatrixTileList(
3894         /*RegMask=*/0, S, getLoc(), getContext()));
3895     return MatchOperand_Success;
3896   }
3897 
3898   // Try parse {za} alias early
3899   if (Parser.getTok().getString().equals_insensitive("za")) {
3900     Parser.Lex(); // Eat 'za'
3901 
3902     if (parseToken(AsmToken::RCurly, "'}' expected"))
3903       return MatchOperand_ParseFail;
3904 
3905     Operands.push_back(AArch64Operand::CreateMatrixTileList(
3906         /*RegMask=*/0xFF, S, getLoc(), getContext()));
3907     return MatchOperand_Success;
3908   }
3909 
3910   SMLoc TileLoc = getLoc();
3911 
3912   unsigned FirstReg, ElementWidth;
3913   auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
3914   if (ParseRes != MatchOperand_Success) {
3915     Parser.getLexer().UnLex(LCurly);
3916     return ParseRes;
3917   }
3918 
3919   const MCRegisterInfo *RI = getContext().getRegisterInfo();
3920 
3921   unsigned PrevReg = FirstReg;
3922   unsigned Count = 1;
3923 
3924   SmallSet<unsigned, 8> DRegs;
3925   AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
3926 
3927   SmallSet<unsigned, 8> SeenRegs;
3928   SeenRegs.insert(FirstReg);
3929 
3930   while (parseOptionalToken(AsmToken::Comma)) {
3931     TileLoc = getLoc();
3932     unsigned Reg, NextElementWidth;
3933     ParseRes = ParseMatrixTile(Reg, NextElementWidth);
3934     if (ParseRes != MatchOperand_Success)
3935       return ParseRes;
3936 
3937     // Element size must match on all regs in the list.
3938     if (ElementWidth != NextElementWidth) {
3939       Error(TileLoc, "mismatched register size suffix");
3940       return MatchOperand_ParseFail;
3941     }
3942 
3943     if (RI->getEncodingValue(Reg) <= (RI->getEncodingValue(PrevReg)))
3944       Warning(TileLoc, "tile list not in ascending order");
3945 
3946     if (SeenRegs.contains(Reg))
3947       Warning(TileLoc, "duplicate tile in list");
3948     else {
3949       SeenRegs.insert(Reg);
3950       AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
3951     }
3952 
3953     PrevReg = Reg;
3954     ++Count;
3955   }
3956 
3957   if (parseToken(AsmToken::RCurly, "'}' expected"))
3958     return MatchOperand_ParseFail;
3959 
3960   unsigned RegMask = 0;
3961   for (auto Reg : DRegs)
3962     RegMask |= 0x1 << (RI->getEncodingValue(Reg) -
3963                        RI->getEncodingValue(AArch64::ZAD0));
3964   Operands.push_back(
3965       AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
3966 
3967   return MatchOperand_Success;
3968 }
3969 
3970 template <RegKind VectorKind>
3971 OperandMatchResultTy
3972 AArch64AsmParser::tryParseVectorList(OperandVector &Operands,
3973                                      bool ExpectMatch) {
3974   MCAsmParser &Parser = getParser();
3975   if (!getTok().is(AsmToken::LCurly))
3976     return MatchOperand_NoMatch;
3977 
3978   // Wrapper around parse function
3979   auto ParseVector = [this](unsigned &Reg, StringRef &Kind, SMLoc Loc,
3980                             bool NoMatchIsError) {
3981     auto RegTok = getTok();
3982     auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
3983     if (ParseRes == MatchOperand_Success) {
3984       if (parseVectorKind(Kind, VectorKind))
3985         return ParseRes;
3986       llvm_unreachable("Expected a valid vector kind");
3987     }
3988 
3989     if (RegTok.isNot(AsmToken::Identifier) ||
3990         ParseRes == MatchOperand_ParseFail ||
3991         (ParseRes == MatchOperand_NoMatch && NoMatchIsError &&
3992          !RegTok.getString().startswith_insensitive("za"))) {
3993       Error(Loc, "vector register expected");
3994       return MatchOperand_ParseFail;
3995     }
3996 
3997     return MatchOperand_NoMatch;
3998   };
3999 
4000   SMLoc S = getLoc();
4001   auto LCurly = getTok();
4002   Parser.Lex(); // Eat left bracket token.
4003 
4004   StringRef Kind;
4005   unsigned FirstReg;
4006   auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4007 
4008   // Put back the original left bracket if there was no match, so that
4009   // different types of list-operands can be matched (e.g. SVE, Neon).
4010   if (ParseRes == MatchOperand_NoMatch)
4011     Parser.getLexer().UnLex(LCurly);
4012 
4013   if (ParseRes != MatchOperand_Success)
4014     return ParseRes;
4015 
4016   int64_t PrevReg = FirstReg;
4017   unsigned Count = 1;
4018 
4019   if (parseOptionalToken(AsmToken::Minus)) {
4020     SMLoc Loc = getLoc();
4021     StringRef NextKind;
4022 
4023     unsigned Reg;
4024     ParseRes = ParseVector(Reg, NextKind, getLoc(), true);
4025     if (ParseRes != MatchOperand_Success)
4026       return ParseRes;
4027 
4028     // Any Kind suffices must match on all regs in the list.
4029     if (Kind != NextKind) {
4030       Error(Loc, "mismatched register size suffix");
4031       return MatchOperand_ParseFail;
4032     }
4033 
4034     unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
4035 
4036     if (Space == 0 || Space > 3) {
4037       Error(Loc, "invalid number of vectors");
4038       return MatchOperand_ParseFail;
4039     }
4040 
4041     Count += Space;
4042   }
4043   else {
4044     while (parseOptionalToken(AsmToken::Comma)) {
4045       SMLoc Loc = getLoc();
4046       StringRef NextKind;
4047       unsigned Reg;
4048       ParseRes = ParseVector(Reg, NextKind, getLoc(), true);
4049       if (ParseRes != MatchOperand_Success)
4050         return ParseRes;
4051 
4052       // Any Kind suffices must match on all regs in the list.
4053       if (Kind != NextKind) {
4054         Error(Loc, "mismatched register size suffix");
4055         return MatchOperand_ParseFail;
4056       }
4057 
4058       // Registers must be incremental (with wraparound at 31)
4059       if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
4060           (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32) {
4061         Error(Loc, "registers must be sequential");
4062         return MatchOperand_ParseFail;
4063       }
4064 
4065       PrevReg = Reg;
4066       ++Count;
4067     }
4068   }
4069 
4070   if (parseToken(AsmToken::RCurly, "'}' expected"))
4071     return MatchOperand_ParseFail;
4072 
4073   if (Count > 4) {
4074     Error(S, "invalid number of vectors");
4075     return MatchOperand_ParseFail;
4076   }
4077 
4078   unsigned NumElements = 0;
4079   unsigned ElementWidth = 0;
4080   if (!Kind.empty()) {
4081     if (const auto &VK = parseVectorKind(Kind, VectorKind))
4082       std::tie(NumElements, ElementWidth) = *VK;
4083   }
4084 
4085   Operands.push_back(AArch64Operand::CreateVectorList(
4086       FirstReg, Count, NumElements, ElementWidth, VectorKind, S, getLoc(),
4087       getContext()));
4088 
4089   return MatchOperand_Success;
4090 }
4091 
4092 /// parseNeonVectorList - Parse a vector list operand for AdvSIMD instructions.
4093 bool AArch64AsmParser::parseNeonVectorList(OperandVector &Operands) {
4094   auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands, true);
4095   if (ParseRes != MatchOperand_Success)
4096     return true;
4097 
4098   return tryParseVectorIndex(Operands) == MatchOperand_ParseFail;
4099 }
4100 
4101 OperandMatchResultTy
4102 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
4103   SMLoc StartLoc = getLoc();
4104 
4105   unsigned RegNum;
4106   OperandMatchResultTy Res = tryParseScalarRegister(RegNum);
4107   if (Res != MatchOperand_Success)
4108     return Res;
4109 
4110   if (!parseOptionalToken(AsmToken::Comma)) {
4111     Operands.push_back(AArch64Operand::CreateReg(
4112         RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4113     return MatchOperand_Success;
4114   }
4115 
4116   parseOptionalToken(AsmToken::Hash);
4117 
4118   if (getTok().isNot(AsmToken::Integer)) {
4119     Error(getLoc(), "index must be absent or #0");
4120     return MatchOperand_ParseFail;
4121   }
4122 
4123   const MCExpr *ImmVal;
4124   if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4125       cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
4126     Error(getLoc(), "index must be absent or #0");
4127     return MatchOperand_ParseFail;
4128   }
4129 
4130   Operands.push_back(AArch64Operand::CreateReg(
4131       RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4132   return MatchOperand_Success;
4133 }
4134 
4135 template <bool ParseShiftExtend, RegConstraintEqualityTy EqTy>
4136 OperandMatchResultTy
4137 AArch64AsmParser::tryParseGPROperand(OperandVector &Operands) {
4138   SMLoc StartLoc = getLoc();
4139 
4140   unsigned RegNum;
4141   OperandMatchResultTy Res = tryParseScalarRegister(RegNum);
4142   if (Res != MatchOperand_Success)
4143     return Res;
4144 
4145   // No shift/extend is the default.
4146   if (!ParseShiftExtend || getTok().isNot(AsmToken::Comma)) {
4147     Operands.push_back(AArch64Operand::CreateReg(
4148         RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4149     return MatchOperand_Success;
4150   }
4151 
4152   // Eat the comma
4153   getParser().Lex();
4154 
4155   // Match the shift
4156   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd;
4157   Res = tryParseOptionalShiftExtend(ExtOpnd);
4158   if (Res != MatchOperand_Success)
4159     return Res;
4160 
4161   auto Ext = static_cast<AArch64Operand*>(ExtOpnd.back().get());
4162   Operands.push_back(AArch64Operand::CreateReg(
4163       RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(), getContext(), EqTy,
4164       Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4165       Ext->hasShiftExtendAmount()));
4166 
4167   return MatchOperand_Success;
4168 }
4169 
4170 bool AArch64AsmParser::parseOptionalMulOperand(OperandVector &Operands) {
4171   MCAsmParser &Parser = getParser();
4172 
4173   // Some SVE instructions have a decoration after the immediate, i.e.
4174   // "mul vl". We parse them here and add tokens, which must be present in the
4175   // asm string in the tablegen instruction.
4176   bool NextIsVL =
4177       Parser.getLexer().peekTok().getString().equals_insensitive("vl");
4178   bool NextIsHash = Parser.getLexer().peekTok().is(AsmToken::Hash);
4179   if (!getTok().getString().equals_insensitive("mul") ||
4180       !(NextIsVL || NextIsHash))
4181     return true;
4182 
4183   Operands.push_back(
4184       AArch64Operand::CreateToken("mul", getLoc(), getContext()));
4185   Parser.Lex(); // Eat the "mul"
4186 
4187   if (NextIsVL) {
4188     Operands.push_back(
4189         AArch64Operand::CreateToken("vl", getLoc(), getContext()));
4190     Parser.Lex(); // Eat the "vl"
4191     return false;
4192   }
4193 
4194   if (NextIsHash) {
4195     Parser.Lex(); // Eat the #
4196     SMLoc S = getLoc();
4197 
4198     // Parse immediate operand.
4199     const MCExpr *ImmVal;
4200     if (!Parser.parseExpression(ImmVal))
4201       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4202         Operands.push_back(AArch64Operand::CreateImm(
4203             MCConstantExpr::create(MCE->getValue(), getContext()), S, getLoc(),
4204             getContext()));
4205         return MatchOperand_Success;
4206       }
4207   }
4208 
4209   return Error(getLoc(), "expected 'vl' or '#<imm>'");
4210 }
4211 
4212 bool AArch64AsmParser::parseKeywordOperand(OperandVector &Operands) {
4213   MCAsmParser &Parser = getParser();
4214   auto Tok = getTok();
4215   if (Tok.isNot(AsmToken::Identifier))
4216     return true;
4217 
4218   auto Keyword = Tok.getString();
4219   Keyword = StringSwitch<StringRef>(Keyword.lower())
4220                 .Case("sm", "sm")
4221                 .Case("za", "za")
4222                 .Default(Keyword);
4223   Operands.push_back(
4224       AArch64Operand::CreateToken(Keyword, Tok.getLoc(), getContext()));
4225 
4226   Parser.Lex();
4227   return false;
4228 }
4229 
4230 /// parseOperand - Parse a arm instruction operand.  For now this parses the
4231 /// operand regardless of the mnemonic.
4232 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
4233                                   bool invertCondCode) {
4234   MCAsmParser &Parser = getParser();
4235 
4236   OperandMatchResultTy ResTy =
4237       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/ true);
4238 
4239   // Check if the current operand has a custom associated parser, if so, try to
4240   // custom parse the operand, or fallback to the general approach.
4241   if (ResTy == MatchOperand_Success)
4242     return false;
4243   // If there wasn't a custom match, try the generic matcher below. Otherwise,
4244   // there was a match, but an error occurred, in which case, just return that
4245   // the operand parsing failed.
4246   if (ResTy == MatchOperand_ParseFail)
4247     return true;
4248 
4249   // Nothing custom, so do general case parsing.
4250   SMLoc S, E;
4251   switch (getLexer().getKind()) {
4252   default: {
4253     SMLoc S = getLoc();
4254     const MCExpr *Expr;
4255     if (parseSymbolicImmVal(Expr))
4256       return Error(S, "invalid operand");
4257 
4258     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
4259     Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4260     return false;
4261   }
4262   case AsmToken::LBrac: {
4263     Operands.push_back(
4264         AArch64Operand::CreateToken("[", getLoc(), getContext()));
4265     Parser.Lex(); // Eat '['
4266 
4267     // There's no comma after a '[', so we can parse the next operand
4268     // immediately.
4269     return parseOperand(Operands, false, false);
4270   }
4271   case AsmToken::LCurly: {
4272     if (!parseNeonVectorList(Operands))
4273       return false;
4274 
4275     Operands.push_back(
4276         AArch64Operand::CreateToken("{", getLoc(), getContext()));
4277     Parser.Lex(); // Eat '{'
4278 
4279     // There's no comma after a '{', so we can parse the next operand
4280     // immediately.
4281     return parseOperand(Operands, false, false);
4282   }
4283   case AsmToken::Identifier: {
4284     // If we're expecting a Condition Code operand, then just parse that.
4285     if (isCondCode)
4286       return parseCondCode(Operands, invertCondCode);
4287 
4288     // If it's a register name, parse it.
4289     if (!parseRegister(Operands))
4290       return false;
4291 
4292     // See if this is a "mul vl" decoration or "mul #<int>" operand used
4293     // by SVE instructions.
4294     if (!parseOptionalMulOperand(Operands))
4295       return false;
4296 
4297     // If this is an "smstart" or "smstop" instruction, parse its special
4298     // keyword operand as an identifier.
4299     if (Mnemonic == "smstart" || Mnemonic == "smstop")
4300       return parseKeywordOperand(Operands);
4301 
4302     // This could be an optional "shift" or "extend" operand.
4303     OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
4304     // We can only continue if no tokens were eaten.
4305     if (GotShift != MatchOperand_NoMatch)
4306       return GotShift;
4307 
4308     // If this is a two-word mnemonic, parse its special keyword
4309     // operand as an identifier.
4310     if (Mnemonic == "brb")
4311       return parseKeywordOperand(Operands);
4312 
4313     // This was not a register so parse other operands that start with an
4314     // identifier (like labels) as expressions and create them as immediates.
4315     const MCExpr *IdVal;
4316     S = getLoc();
4317     if (getParser().parseExpression(IdVal))
4318       return true;
4319     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
4320     Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
4321     return false;
4322   }
4323   case AsmToken::Integer:
4324   case AsmToken::Real:
4325   case AsmToken::Hash: {
4326     // #42 -> immediate.
4327     S = getLoc();
4328 
4329     parseOptionalToken(AsmToken::Hash);
4330 
4331     // Parse a negative sign
4332     bool isNegative = false;
4333     if (getTok().is(AsmToken::Minus)) {
4334       isNegative = true;
4335       // We need to consume this token only when we have a Real, otherwise
4336       // we let parseSymbolicImmVal take care of it
4337       if (Parser.getLexer().peekTok().is(AsmToken::Real))
4338         Parser.Lex();
4339     }
4340 
4341     // The only Real that should come through here is a literal #0.0 for
4342     // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
4343     // so convert the value.
4344     const AsmToken &Tok = getTok();
4345     if (Tok.is(AsmToken::Real)) {
4346       APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
4347       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
4348       if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
4349           Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
4350           Mnemonic != "fcmlt" && Mnemonic != "fcmne")
4351         return TokError("unexpected floating point literal");
4352       else if (IntVal != 0 || isNegative)
4353         return TokError("expected floating-point constant #0.0");
4354       Parser.Lex(); // Eat the token.
4355 
4356       Operands.push_back(AArch64Operand::CreateToken("#0", S, getContext()));
4357       Operands.push_back(AArch64Operand::CreateToken(".0", S, getContext()));
4358       return false;
4359     }
4360 
4361     const MCExpr *ImmVal;
4362     if (parseSymbolicImmVal(ImmVal))
4363       return true;
4364 
4365     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
4366     Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
4367     return false;
4368   }
4369   case AsmToken::Equal: {
4370     SMLoc Loc = getLoc();
4371     if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
4372       return TokError("unexpected token in operand");
4373     Parser.Lex(); // Eat '='
4374     const MCExpr *SubExprVal;
4375     if (getParser().parseExpression(SubExprVal))
4376       return true;
4377 
4378     if (Operands.size() < 2 ||
4379         !static_cast<AArch64Operand &>(*Operands[1]).isScalarReg())
4380       return Error(Loc, "Only valid when first operand is register");
4381 
4382     bool IsXReg =
4383         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4384             Operands[1]->getReg());
4385 
4386     MCContext& Ctx = getContext();
4387     E = SMLoc::getFromPointer(Loc.getPointer() - 1);
4388     // If the op is an imm and can be fit into a mov, then replace ldr with mov.
4389     if (isa<MCConstantExpr>(SubExprVal)) {
4390       uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
4391       uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
4392       while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
4393         ShiftAmt += 16;
4394         Imm >>= 16;
4395       }
4396       if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
4397         Operands[0] = AArch64Operand::CreateToken("movz", Loc, Ctx);
4398         Operands.push_back(AArch64Operand::CreateImm(
4399             MCConstantExpr::create(Imm, Ctx), S, E, Ctx));
4400         if (ShiftAmt)
4401           Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
4402                      ShiftAmt, true, S, E, Ctx));
4403         return false;
4404       }
4405       APInt Simm = APInt(64, Imm << ShiftAmt);
4406       // check if the immediate is an unsigned or signed 32-bit int for W regs
4407       if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
4408         return Error(Loc, "Immediate too large for register");
4409     }
4410     // If it is a label or an imm that cannot fit in a movz, put it into CP.
4411     const MCExpr *CPLoc =
4412         getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
4413     Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
4414     return false;
4415   }
4416   }
4417 }
4418 
4419 bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
4420   const MCExpr *Expr = nullptr;
4421   SMLoc L = getLoc();
4422   if (check(getParser().parseExpression(Expr), L, "expected expression"))
4423     return true;
4424   const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4425   if (check(!Value, L, "expected constant expression"))
4426     return true;
4427   Out = Value->getValue();
4428   return false;
4429 }
4430 
4431 bool AArch64AsmParser::parseComma() {
4432   if (check(getTok().isNot(AsmToken::Comma), getLoc(), "expected comma"))
4433     return true;
4434   // Eat the comma
4435   getParser().Lex();
4436   return false;
4437 }
4438 
4439 bool AArch64AsmParser::parseRegisterInRange(unsigned &Out, unsigned Base,
4440                                             unsigned First, unsigned Last) {
4441   unsigned Reg;
4442   SMLoc Start, End;
4443   if (check(ParseRegister(Reg, Start, End), getLoc(), "expected register"))
4444     return true;
4445 
4446   // Special handling for FP and LR; they aren't linearly after x28 in
4447   // the registers enum.
4448   unsigned RangeEnd = Last;
4449   if (Base == AArch64::X0) {
4450     if (Last == AArch64::FP) {
4451       RangeEnd = AArch64::X28;
4452       if (Reg == AArch64::FP) {
4453         Out = 29;
4454         return false;
4455       }
4456     }
4457     if (Last == AArch64::LR) {
4458       RangeEnd = AArch64::X28;
4459       if (Reg == AArch64::FP) {
4460         Out = 29;
4461         return false;
4462       } else if (Reg == AArch64::LR) {
4463         Out = 30;
4464         return false;
4465       }
4466     }
4467   }
4468 
4469   if (check(Reg < First || Reg > RangeEnd, Start,
4470             Twine("expected register in range ") +
4471                 AArch64InstPrinter::getRegisterName(First) + " to " +
4472                 AArch64InstPrinter::getRegisterName(Last)))
4473     return true;
4474   Out = Reg - Base;
4475   return false;
4476 }
4477 
4478 bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1,
4479                                  const MCParsedAsmOperand &Op2) const {
4480   auto &AOp1 = static_cast<const AArch64Operand&>(Op1);
4481   auto &AOp2 = static_cast<const AArch64Operand&>(Op2);
4482   if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
4483       AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
4484     return MCTargetAsmParser::regsEqual(Op1, Op2);
4485 
4486   assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
4487          "Testing equality of non-scalar registers not supported");
4488 
4489   // Check if a registers match their sub/super register classes.
4490   if (AOp1.getRegEqualityTy() == EqualsSuperReg)
4491     return getXRegFromWReg(Op1.getReg()) == Op2.getReg();
4492   if (AOp1.getRegEqualityTy() == EqualsSubReg)
4493     return getWRegFromXReg(Op1.getReg()) == Op2.getReg();
4494   if (AOp2.getRegEqualityTy() == EqualsSuperReg)
4495     return getXRegFromWReg(Op2.getReg()) == Op1.getReg();
4496   if (AOp2.getRegEqualityTy() == EqualsSubReg)
4497     return getWRegFromXReg(Op2.getReg()) == Op1.getReg();
4498 
4499   return false;
4500 }
4501 
4502 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
4503 /// operands.
4504 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
4505                                         StringRef Name, SMLoc NameLoc,
4506                                         OperandVector &Operands) {
4507   Name = StringSwitch<StringRef>(Name.lower())
4508              .Case("beq", "b.eq")
4509              .Case("bne", "b.ne")
4510              .Case("bhs", "b.hs")
4511              .Case("bcs", "b.cs")
4512              .Case("blo", "b.lo")
4513              .Case("bcc", "b.cc")
4514              .Case("bmi", "b.mi")
4515              .Case("bpl", "b.pl")
4516              .Case("bvs", "b.vs")
4517              .Case("bvc", "b.vc")
4518              .Case("bhi", "b.hi")
4519              .Case("bls", "b.ls")
4520              .Case("bge", "b.ge")
4521              .Case("blt", "b.lt")
4522              .Case("bgt", "b.gt")
4523              .Case("ble", "b.le")
4524              .Case("bal", "b.al")
4525              .Case("bnv", "b.nv")
4526              .Default(Name);
4527 
4528   // First check for the AArch64-specific .req directive.
4529   if (getTok().is(AsmToken::Identifier) &&
4530       getTok().getIdentifier().lower() == ".req") {
4531     parseDirectiveReq(Name, NameLoc);
4532     // We always return 'error' for this, as we're done with this
4533     // statement and don't need to match the 'instruction."
4534     return true;
4535   }
4536 
4537   // Create the leading tokens for the mnemonic, split by '.' characters.
4538   size_t Start = 0, Next = Name.find('.');
4539   StringRef Head = Name.slice(Start, Next);
4540 
4541   // IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for
4542   // the SYS instruction.
4543   if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" ||
4544       Head == "cfp" || Head == "dvp" || Head == "cpp")
4545     return parseSysAlias(Head, NameLoc, Operands);
4546 
4547   Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
4548   Mnemonic = Head;
4549 
4550   // Handle condition codes for a branch mnemonic
4551   if (Head == "b" && Next != StringRef::npos) {
4552     Start = Next;
4553     Next = Name.find('.', Start + 1);
4554     Head = Name.slice(Start + 1, Next);
4555 
4556     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
4557                                             (Head.data() - Name.data()));
4558     AArch64CC::CondCode CC = parseCondCodeString(Head);
4559     if (CC == AArch64CC::Invalid)
4560       return Error(SuffixLoc, "invalid condition code");
4561     Operands.push_back(AArch64Operand::CreateToken(".", SuffixLoc, getContext(),
4562                                                    /*IsSuffix=*/true));
4563     Operands.push_back(
4564         AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
4565   }
4566 
4567   // Add the remaining tokens in the mnemonic.
4568   while (Next != StringRef::npos) {
4569     Start = Next;
4570     Next = Name.find('.', Start + 1);
4571     Head = Name.slice(Start, Next);
4572     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
4573                                             (Head.data() - Name.data()) + 1);
4574     Operands.push_back(AArch64Operand::CreateToken(
4575         Head, SuffixLoc, getContext(), /*IsSuffix=*/true));
4576   }
4577 
4578   // Conditional compare instructions have a Condition Code operand, which needs
4579   // to be parsed and an immediate operand created.
4580   bool condCodeFourthOperand =
4581       (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
4582        Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
4583        Head == "csinc" || Head == "csinv" || Head == "csneg");
4584 
4585   // These instructions are aliases to some of the conditional select
4586   // instructions. However, the condition code is inverted in the aliased
4587   // instruction.
4588   //
4589   // FIXME: Is this the correct way to handle these? Or should the parser
4590   //        generate the aliased instructions directly?
4591   bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
4592   bool condCodeThirdOperand =
4593       (Head == "cinc" || Head == "cinv" || Head == "cneg");
4594 
4595   // Read the remaining operands.
4596   if (getLexer().isNot(AsmToken::EndOfStatement)) {
4597 
4598     unsigned N = 1;
4599     do {
4600       // Parse and remember the operand.
4601       if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
4602                                      (N == 3 && condCodeThirdOperand) ||
4603                                      (N == 2 && condCodeSecondOperand),
4604                        condCodeSecondOperand || condCodeThirdOperand)) {
4605         return true;
4606       }
4607 
4608       // After successfully parsing some operands there are three special cases
4609       // to consider (i.e. notional operands not separated by commas). Two are
4610       // due to memory specifiers:
4611       //  + An RBrac will end an address for load/store/prefetch
4612       //  + An '!' will indicate a pre-indexed operation.
4613       //
4614       // And a further case is '}', which ends a group of tokens specifying the
4615       // SME accumulator array 'ZA' or tile vector, i.e.
4616       //
4617       //   '{ ZA }' or '{ <ZAt><HV>.<BHSDQ>[<Wv>, #<imm>] }'
4618       //
4619       // It's someone else's responsibility to make sure these tokens are sane
4620       // in the given context!
4621 
4622       if (parseOptionalToken(AsmToken::RBrac))
4623         Operands.push_back(
4624             AArch64Operand::CreateToken("]", getLoc(), getContext()));
4625       if (parseOptionalToken(AsmToken::Exclaim))
4626         Operands.push_back(
4627             AArch64Operand::CreateToken("!", getLoc(), getContext()));
4628       if (parseOptionalToken(AsmToken::RCurly))
4629         Operands.push_back(
4630             AArch64Operand::CreateToken("}", getLoc(), getContext()));
4631 
4632       ++N;
4633     } while (parseOptionalToken(AsmToken::Comma));
4634   }
4635 
4636   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
4637     return true;
4638 
4639   return false;
4640 }
4641 
4642 static inline bool isMatchingOrAlias(unsigned ZReg, unsigned Reg) {
4643   assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
4644   return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
4645          (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
4646          (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
4647          (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
4648          (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
4649          (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
4650 }
4651 
4652 // FIXME: This entire function is a giant hack to provide us with decent
4653 // operand range validation/diagnostics until TableGen/MC can be extended
4654 // to support autogeneration of this kind of validation.
4655 bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
4656                                            SmallVectorImpl<SMLoc> &Loc) {
4657   const MCRegisterInfo *RI = getContext().getRegisterInfo();
4658   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
4659 
4660   // A prefix only applies to the instruction following it.  Here we extract
4661   // prefix information for the next instruction before validating the current
4662   // one so that in the case of failure we don't erronously continue using the
4663   // current prefix.
4664   PrefixInfo Prefix = NextPrefix;
4665   NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.TSFlags);
4666 
4667   // Before validating the instruction in isolation we run through the rules
4668   // applicable when it follows a prefix instruction.
4669   // NOTE: brk & hlt can be prefixed but require no additional validation.
4670   if (Prefix.isActive() &&
4671       (Inst.getOpcode() != AArch64::BRK) &&
4672       (Inst.getOpcode() != AArch64::HLT)) {
4673 
4674     // Prefixed intructions must have a destructive operand.
4675     if ((MCID.TSFlags & AArch64::DestructiveInstTypeMask) ==
4676         AArch64::NotDestructive)
4677       return Error(IDLoc, "instruction is unpredictable when following a"
4678                    " movprfx, suggest replacing movprfx with mov");
4679 
4680     // Destination operands must match.
4681     if (Inst.getOperand(0).getReg() != Prefix.getDstReg())
4682       return Error(Loc[0], "instruction is unpredictable when following a"
4683                    " movprfx writing to a different destination");
4684 
4685     // Destination operand must not be used in any other location.
4686     for (unsigned i = 1; i < Inst.getNumOperands(); ++i) {
4687       if (Inst.getOperand(i).isReg() &&
4688           (MCID.getOperandConstraint(i, MCOI::TIED_TO) == -1) &&
4689           isMatchingOrAlias(Prefix.getDstReg(), Inst.getOperand(i).getReg()))
4690         return Error(Loc[0], "instruction is unpredictable when following a"
4691                      " movprfx and destination also used as non-destructive"
4692                      " source");
4693     }
4694 
4695     auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
4696     if (Prefix.isPredicated()) {
4697       int PgIdx = -1;
4698 
4699       // Find the instructions general predicate.
4700       for (unsigned i = 1; i < Inst.getNumOperands(); ++i)
4701         if (Inst.getOperand(i).isReg() &&
4702             PPRRegClass.contains(Inst.getOperand(i).getReg())) {
4703           PgIdx = i;
4704           break;
4705         }
4706 
4707       // Instruction must be predicated if the movprfx is predicated.
4708       if (PgIdx == -1 ||
4709           (MCID.TSFlags & AArch64::ElementSizeMask) == AArch64::ElementSizeNone)
4710         return Error(IDLoc, "instruction is unpredictable when following a"
4711                      " predicated movprfx, suggest using unpredicated movprfx");
4712 
4713       // Instruction must use same general predicate as the movprfx.
4714       if (Inst.getOperand(PgIdx).getReg() != Prefix.getPgReg())
4715         return Error(IDLoc, "instruction is unpredictable when following a"
4716                      " predicated movprfx using a different general predicate");
4717 
4718       // Instruction element type must match the movprfx.
4719       if ((MCID.TSFlags & AArch64::ElementSizeMask) != Prefix.getElementSize())
4720         return Error(IDLoc, "instruction is unpredictable when following a"
4721                      " predicated movprfx with a different element size");
4722     }
4723   }
4724 
4725   // Check for indexed addressing modes w/ the base register being the
4726   // same as a destination/source register or pair load where
4727   // the Rt == Rt2. All of those are undefined behaviour.
4728   switch (Inst.getOpcode()) {
4729   case AArch64::LDPSWpre:
4730   case AArch64::LDPWpost:
4731   case AArch64::LDPWpre:
4732   case AArch64::LDPXpost:
4733   case AArch64::LDPXpre: {
4734     unsigned Rt = Inst.getOperand(1).getReg();
4735     unsigned Rt2 = Inst.getOperand(2).getReg();
4736     unsigned Rn = Inst.getOperand(3).getReg();
4737     if (RI->isSubRegisterEq(Rn, Rt))
4738       return Error(Loc[0], "unpredictable LDP instruction, writeback base "
4739                            "is also a destination");
4740     if (RI->isSubRegisterEq(Rn, Rt2))
4741       return Error(Loc[1], "unpredictable LDP instruction, writeback base "
4742                            "is also a destination");
4743     LLVM_FALLTHROUGH;
4744   }
4745   case AArch64::LDPDi:
4746   case AArch64::LDPQi:
4747   case AArch64::LDPSi:
4748   case AArch64::LDPSWi:
4749   case AArch64::LDPWi:
4750   case AArch64::LDPXi: {
4751     unsigned Rt = Inst.getOperand(0).getReg();
4752     unsigned Rt2 = Inst.getOperand(1).getReg();
4753     if (Rt == Rt2)
4754       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
4755     break;
4756   }
4757   case AArch64::LDPDpost:
4758   case AArch64::LDPDpre:
4759   case AArch64::LDPQpost:
4760   case AArch64::LDPQpre:
4761   case AArch64::LDPSpost:
4762   case AArch64::LDPSpre:
4763   case AArch64::LDPSWpost: {
4764     unsigned Rt = Inst.getOperand(1).getReg();
4765     unsigned Rt2 = Inst.getOperand(2).getReg();
4766     if (Rt == Rt2)
4767       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
4768     break;
4769   }
4770   case AArch64::STPDpost:
4771   case AArch64::STPDpre:
4772   case AArch64::STPQpost:
4773   case AArch64::STPQpre:
4774   case AArch64::STPSpost:
4775   case AArch64::STPSpre:
4776   case AArch64::STPWpost:
4777   case AArch64::STPWpre:
4778   case AArch64::STPXpost:
4779   case AArch64::STPXpre: {
4780     unsigned Rt = Inst.getOperand(1).getReg();
4781     unsigned Rt2 = Inst.getOperand(2).getReg();
4782     unsigned Rn = Inst.getOperand(3).getReg();
4783     if (RI->isSubRegisterEq(Rn, Rt))
4784       return Error(Loc[0], "unpredictable STP instruction, writeback base "
4785                            "is also a source");
4786     if (RI->isSubRegisterEq(Rn, Rt2))
4787       return Error(Loc[1], "unpredictable STP instruction, writeback base "
4788                            "is also a source");
4789     break;
4790   }
4791   case AArch64::LDRBBpre:
4792   case AArch64::LDRBpre:
4793   case AArch64::LDRHHpre:
4794   case AArch64::LDRHpre:
4795   case AArch64::LDRSBWpre:
4796   case AArch64::LDRSBXpre:
4797   case AArch64::LDRSHWpre:
4798   case AArch64::LDRSHXpre:
4799   case AArch64::LDRSWpre:
4800   case AArch64::LDRWpre:
4801   case AArch64::LDRXpre:
4802   case AArch64::LDRBBpost:
4803   case AArch64::LDRBpost:
4804   case AArch64::LDRHHpost:
4805   case AArch64::LDRHpost:
4806   case AArch64::LDRSBWpost:
4807   case AArch64::LDRSBXpost:
4808   case AArch64::LDRSHWpost:
4809   case AArch64::LDRSHXpost:
4810   case AArch64::LDRSWpost:
4811   case AArch64::LDRWpost:
4812   case AArch64::LDRXpost: {
4813     unsigned Rt = Inst.getOperand(1).getReg();
4814     unsigned Rn = Inst.getOperand(2).getReg();
4815     if (RI->isSubRegisterEq(Rn, Rt))
4816       return Error(Loc[0], "unpredictable LDR instruction, writeback base "
4817                            "is also a source");
4818     break;
4819   }
4820   case AArch64::STRBBpost:
4821   case AArch64::STRBpost:
4822   case AArch64::STRHHpost:
4823   case AArch64::STRHpost:
4824   case AArch64::STRWpost:
4825   case AArch64::STRXpost:
4826   case AArch64::STRBBpre:
4827   case AArch64::STRBpre:
4828   case AArch64::STRHHpre:
4829   case AArch64::STRHpre:
4830   case AArch64::STRWpre:
4831   case AArch64::STRXpre: {
4832     unsigned Rt = Inst.getOperand(1).getReg();
4833     unsigned Rn = Inst.getOperand(2).getReg();
4834     if (RI->isSubRegisterEq(Rn, Rt))
4835       return Error(Loc[0], "unpredictable STR instruction, writeback base "
4836                            "is also a source");
4837     break;
4838   }
4839   case AArch64::STXRB:
4840   case AArch64::STXRH:
4841   case AArch64::STXRW:
4842   case AArch64::STXRX:
4843   case AArch64::STLXRB:
4844   case AArch64::STLXRH:
4845   case AArch64::STLXRW:
4846   case AArch64::STLXRX: {
4847     unsigned Rs = Inst.getOperand(0).getReg();
4848     unsigned Rt = Inst.getOperand(1).getReg();
4849     unsigned Rn = Inst.getOperand(2).getReg();
4850     if (RI->isSubRegisterEq(Rt, Rs) ||
4851         (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP))
4852       return Error(Loc[0],
4853                    "unpredictable STXR instruction, status is also a source");
4854     break;
4855   }
4856   case AArch64::STXPW:
4857   case AArch64::STXPX:
4858   case AArch64::STLXPW:
4859   case AArch64::STLXPX: {
4860     unsigned Rs = Inst.getOperand(0).getReg();
4861     unsigned Rt1 = Inst.getOperand(1).getReg();
4862     unsigned Rt2 = Inst.getOperand(2).getReg();
4863     unsigned Rn = Inst.getOperand(3).getReg();
4864     if (RI->isSubRegisterEq(Rt1, Rs) || RI->isSubRegisterEq(Rt2, Rs) ||
4865         (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP))
4866       return Error(Loc[0],
4867                    "unpredictable STXP instruction, status is also a source");
4868     break;
4869   }
4870   case AArch64::LDRABwriteback:
4871   case AArch64::LDRAAwriteback: {
4872     unsigned Xt = Inst.getOperand(0).getReg();
4873     unsigned Xn = Inst.getOperand(1).getReg();
4874     if (Xt == Xn)
4875       return Error(Loc[0],
4876           "unpredictable LDRA instruction, writeback base"
4877           " is also a destination");
4878     break;
4879   }
4880   }
4881 
4882 
4883   // Now check immediate ranges. Separate from the above as there is overlap
4884   // in the instructions being checked and this keeps the nested conditionals
4885   // to a minimum.
4886   switch (Inst.getOpcode()) {
4887   case AArch64::ADDSWri:
4888   case AArch64::ADDSXri:
4889   case AArch64::ADDWri:
4890   case AArch64::ADDXri:
4891   case AArch64::SUBSWri:
4892   case AArch64::SUBSXri:
4893   case AArch64::SUBWri:
4894   case AArch64::SUBXri: {
4895     // Annoyingly we can't do this in the isAddSubImm predicate, so there is
4896     // some slight duplication here.
4897     if (Inst.getOperand(2).isExpr()) {
4898       const MCExpr *Expr = Inst.getOperand(2).getExpr();
4899       AArch64MCExpr::VariantKind ELFRefKind;
4900       MCSymbolRefExpr::VariantKind DarwinRefKind;
4901       int64_t Addend;
4902       if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
4903 
4904         // Only allow these with ADDXri.
4905         if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
4906              DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
4907             Inst.getOpcode() == AArch64::ADDXri)
4908           return false;
4909 
4910         // Only allow these with ADDXri/ADDWri
4911         if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
4912              ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
4913              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
4914              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
4915              ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
4916              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
4917              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
4918              ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
4919              ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
4920              ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) &&
4921             (Inst.getOpcode() == AArch64::ADDXri ||
4922              Inst.getOpcode() == AArch64::ADDWri))
4923           return false;
4924 
4925         // Don't allow symbol refs in the immediate field otherwise
4926         // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of
4927         // operands of the original instruction (i.e. 'add w0, w1, borked' vs
4928         // 'cmp w0, 'borked')
4929         return Error(Loc.back(), "invalid immediate expression");
4930       }
4931       // We don't validate more complex expressions here
4932     }
4933     return false;
4934   }
4935   default:
4936     return false;
4937   }
4938 }
4939 
4940 static std::string AArch64MnemonicSpellCheck(StringRef S,
4941                                              const FeatureBitset &FBS,
4942                                              unsigned VariantID = 0);
4943 
4944 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
4945                                       uint64_t ErrorInfo,
4946                                       OperandVector &Operands) {
4947   switch (ErrCode) {
4948   case Match_InvalidTiedOperand: {
4949     RegConstraintEqualityTy EqTy =
4950         static_cast<const AArch64Operand &>(*Operands[ErrorInfo])
4951             .getRegEqualityTy();
4952     switch (EqTy) {
4953     case RegConstraintEqualityTy::EqualsSubReg:
4954       return Error(Loc, "operand must be 64-bit form of destination register");
4955     case RegConstraintEqualityTy::EqualsSuperReg:
4956       return Error(Loc, "operand must be 32-bit form of destination register");
4957     case RegConstraintEqualityTy::EqualsReg:
4958       return Error(Loc, "operand must match destination register");
4959     }
4960     llvm_unreachable("Unknown RegConstraintEqualityTy");
4961   }
4962   case Match_MissingFeature:
4963     return Error(Loc,
4964                  "instruction requires a CPU feature not currently enabled");
4965   case Match_InvalidOperand:
4966     return Error(Loc, "invalid operand for instruction");
4967   case Match_InvalidSuffix:
4968     return Error(Loc, "invalid type suffix for instruction");
4969   case Match_InvalidCondCode:
4970     return Error(Loc, "expected AArch64 condition code");
4971   case Match_AddSubRegExtendSmall:
4972     return Error(Loc,
4973       "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
4974   case Match_AddSubRegExtendLarge:
4975     return Error(Loc,
4976       "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
4977   case Match_AddSubSecondSource:
4978     return Error(Loc,
4979       "expected compatible register, symbol or integer in range [0, 4095]");
4980   case Match_LogicalSecondSource:
4981     return Error(Loc, "expected compatible register or logical immediate");
4982   case Match_InvalidMovImm32Shift:
4983     return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
4984   case Match_InvalidMovImm64Shift:
4985     return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
4986   case Match_AddSubRegShift32:
4987     return Error(Loc,
4988        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
4989   case Match_AddSubRegShift64:
4990     return Error(Loc,
4991        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
4992   case Match_InvalidFPImm:
4993     return Error(Loc,
4994                  "expected compatible register or floating-point constant");
4995   case Match_InvalidMemoryIndexedSImm6:
4996     return Error(Loc, "index must be an integer in range [-32, 31].");
4997   case Match_InvalidMemoryIndexedSImm5:
4998     return Error(Loc, "index must be an integer in range [-16, 15].");
4999   case Match_InvalidMemoryIndexed1SImm4:
5000     return Error(Loc, "index must be an integer in range [-8, 7].");
5001   case Match_InvalidMemoryIndexed2SImm4:
5002     return Error(Loc, "index must be a multiple of 2 in range [-16, 14].");
5003   case Match_InvalidMemoryIndexed3SImm4:
5004     return Error(Loc, "index must be a multiple of 3 in range [-24, 21].");
5005   case Match_InvalidMemoryIndexed4SImm4:
5006     return Error(Loc, "index must be a multiple of 4 in range [-32, 28].");
5007   case Match_InvalidMemoryIndexed16SImm4:
5008     return Error(Loc, "index must be a multiple of 16 in range [-128, 112].");
5009   case Match_InvalidMemoryIndexed32SImm4:
5010     return Error(Loc, "index must be a multiple of 32 in range [-256, 224].");
5011   case Match_InvalidMemoryIndexed1SImm6:
5012     return Error(Loc, "index must be an integer in range [-32, 31].");
5013   case Match_InvalidMemoryIndexedSImm8:
5014     return Error(Loc, "index must be an integer in range [-128, 127].");
5015   case Match_InvalidMemoryIndexedSImm9:
5016     return Error(Loc, "index must be an integer in range [-256, 255].");
5017   case Match_InvalidMemoryIndexed16SImm9:
5018     return Error(Loc, "index must be a multiple of 16 in range [-4096, 4080].");
5019   case Match_InvalidMemoryIndexed8SImm10:
5020     return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088].");
5021   case Match_InvalidMemoryIndexed4SImm7:
5022     return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
5023   case Match_InvalidMemoryIndexed8SImm7:
5024     return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
5025   case Match_InvalidMemoryIndexed16SImm7:
5026     return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
5027   case Match_InvalidMemoryIndexed8UImm5:
5028     return Error(Loc, "index must be a multiple of 8 in range [0, 248].");
5029   case Match_InvalidMemoryIndexed4UImm5:
5030     return Error(Loc, "index must be a multiple of 4 in range [0, 124].");
5031   case Match_InvalidMemoryIndexed2UImm5:
5032     return Error(Loc, "index must be a multiple of 2 in range [0, 62].");
5033   case Match_InvalidMemoryIndexed8UImm6:
5034     return Error(Loc, "index must be a multiple of 8 in range [0, 504].");
5035   case Match_InvalidMemoryIndexed16UImm6:
5036     return Error(Loc, "index must be a multiple of 16 in range [0, 1008].");
5037   case Match_InvalidMemoryIndexed4UImm6:
5038     return Error(Loc, "index must be a multiple of 4 in range [0, 252].");
5039   case Match_InvalidMemoryIndexed2UImm6:
5040     return Error(Loc, "index must be a multiple of 2 in range [0, 126].");
5041   case Match_InvalidMemoryIndexed1UImm6:
5042     return Error(Loc, "index must be in range [0, 63].");
5043   case Match_InvalidMemoryWExtend8:
5044     return Error(Loc,
5045                  "expected 'uxtw' or 'sxtw' with optional shift of #0");
5046   case Match_InvalidMemoryWExtend16:
5047     return Error(Loc,
5048                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5049   case Match_InvalidMemoryWExtend32:
5050     return Error(Loc,
5051                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5052   case Match_InvalidMemoryWExtend64:
5053     return Error(Loc,
5054                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5055   case Match_InvalidMemoryWExtend128:
5056     return Error(Loc,
5057                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5058   case Match_InvalidMemoryXExtend8:
5059     return Error(Loc,
5060                  "expected 'lsl' or 'sxtx' with optional shift of #0");
5061   case Match_InvalidMemoryXExtend16:
5062     return Error(Loc,
5063                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5064   case Match_InvalidMemoryXExtend32:
5065     return Error(Loc,
5066                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5067   case Match_InvalidMemoryXExtend64:
5068     return Error(Loc,
5069                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5070   case Match_InvalidMemoryXExtend128:
5071     return Error(Loc,
5072                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5073   case Match_InvalidMemoryIndexed1:
5074     return Error(Loc, "index must be an integer in range [0, 4095].");
5075   case Match_InvalidMemoryIndexed2:
5076     return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
5077   case Match_InvalidMemoryIndexed4:
5078     return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
5079   case Match_InvalidMemoryIndexed8:
5080     return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
5081   case Match_InvalidMemoryIndexed16:
5082     return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
5083   case Match_InvalidImm0_1:
5084     return Error(Loc, "immediate must be an integer in range [0, 1].");
5085   case Match_InvalidImm0_3:
5086     return Error(Loc, "immediate must be an integer in range [0, 3].");
5087   case Match_InvalidImm0_7:
5088     return Error(Loc, "immediate must be an integer in range [0, 7].");
5089   case Match_InvalidImm0_15:
5090     return Error(Loc, "immediate must be an integer in range [0, 15].");
5091   case Match_InvalidImm0_31:
5092     return Error(Loc, "immediate must be an integer in range [0, 31].");
5093   case Match_InvalidImm0_63:
5094     return Error(Loc, "immediate must be an integer in range [0, 63].");
5095   case Match_InvalidImm0_127:
5096     return Error(Loc, "immediate must be an integer in range [0, 127].");
5097   case Match_InvalidImm0_255:
5098     return Error(Loc, "immediate must be an integer in range [0, 255].");
5099   case Match_InvalidImm0_65535:
5100     return Error(Loc, "immediate must be an integer in range [0, 65535].");
5101   case Match_InvalidImm1_8:
5102     return Error(Loc, "immediate must be an integer in range [1, 8].");
5103   case Match_InvalidImm1_16:
5104     return Error(Loc, "immediate must be an integer in range [1, 16].");
5105   case Match_InvalidImm1_32:
5106     return Error(Loc, "immediate must be an integer in range [1, 32].");
5107   case Match_InvalidImm1_64:
5108     return Error(Loc, "immediate must be an integer in range [1, 64].");
5109   case Match_InvalidSVEAddSubImm8:
5110     return Error(Loc, "immediate must be an integer in range [0, 255]"
5111                       " with a shift amount of 0");
5112   case Match_InvalidSVEAddSubImm16:
5113   case Match_InvalidSVEAddSubImm32:
5114   case Match_InvalidSVEAddSubImm64:
5115     return Error(Loc, "immediate must be an integer in range [0, 255] or a "
5116                       "multiple of 256 in range [256, 65280]");
5117   case Match_InvalidSVECpyImm8:
5118     return Error(Loc, "immediate must be an integer in range [-128, 255]"
5119                       " with a shift amount of 0");
5120   case Match_InvalidSVECpyImm16:
5121     return Error(Loc, "immediate must be an integer in range [-128, 127] or a "
5122                       "multiple of 256 in range [-32768, 65280]");
5123   case Match_InvalidSVECpyImm32:
5124   case Match_InvalidSVECpyImm64:
5125     return Error(Loc, "immediate must be an integer in range [-128, 127] or a "
5126                       "multiple of 256 in range [-32768, 32512]");
5127   case Match_InvalidIndexRange1_1:
5128     return Error(Loc, "expected lane specifier '[1]'");
5129   case Match_InvalidIndexRange0_15:
5130     return Error(Loc, "vector lane must be an integer in range [0, 15].");
5131   case Match_InvalidIndexRange0_7:
5132     return Error(Loc, "vector lane must be an integer in range [0, 7].");
5133   case Match_InvalidIndexRange0_3:
5134     return Error(Loc, "vector lane must be an integer in range [0, 3].");
5135   case Match_InvalidIndexRange0_1:
5136     return Error(Loc, "vector lane must be an integer in range [0, 1].");
5137   case Match_InvalidSVEIndexRange0_63:
5138     return Error(Loc, "vector lane must be an integer in range [0, 63].");
5139   case Match_InvalidSVEIndexRange0_31:
5140     return Error(Loc, "vector lane must be an integer in range [0, 31].");
5141   case Match_InvalidSVEIndexRange0_15:
5142     return Error(Loc, "vector lane must be an integer in range [0, 15].");
5143   case Match_InvalidSVEIndexRange0_7:
5144     return Error(Loc, "vector lane must be an integer in range [0, 7].");
5145   case Match_InvalidSVEIndexRange0_3:
5146     return Error(Loc, "vector lane must be an integer in range [0, 3].");
5147   case Match_InvalidLabel:
5148     return Error(Loc, "expected label or encodable integer pc offset");
5149   case Match_MRS:
5150     return Error(Loc, "expected readable system register");
5151   case Match_MSR:
5152   case Match_InvalidSVCR:
5153     return Error(Loc, "expected writable system register or pstate");
5154   case Match_InvalidComplexRotationEven:
5155     return Error(Loc, "complex rotation must be 0, 90, 180 or 270.");
5156   case Match_InvalidComplexRotationOdd:
5157     return Error(Loc, "complex rotation must be 90 or 270.");
5158   case Match_MnemonicFail: {
5159     std::string Suggestion = AArch64MnemonicSpellCheck(
5160         ((AArch64Operand &)*Operands[0]).getToken(),
5161         ComputeAvailableFeatures(STI->getFeatureBits()));
5162     return Error(Loc, "unrecognized instruction mnemonic" + Suggestion);
5163   }
5164   case Match_InvalidGPR64shifted8:
5165     return Error(Loc, "register must be x0..x30 or xzr, without shift");
5166   case Match_InvalidGPR64shifted16:
5167     return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #1'");
5168   case Match_InvalidGPR64shifted32:
5169     return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #2'");
5170   case Match_InvalidGPR64shifted64:
5171     return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #3'");
5172   case Match_InvalidGPR64shifted128:
5173     return Error(
5174         Loc, "register must be x0..x30 or xzr, with required shift 'lsl #4'");
5175   case Match_InvalidGPR64NoXZRshifted8:
5176     return Error(Loc, "register must be x0..x30 without shift");
5177   case Match_InvalidGPR64NoXZRshifted16:
5178     return Error(Loc, "register must be x0..x30 with required shift 'lsl #1'");
5179   case Match_InvalidGPR64NoXZRshifted32:
5180     return Error(Loc, "register must be x0..x30 with required shift 'lsl #2'");
5181   case Match_InvalidGPR64NoXZRshifted64:
5182     return Error(Loc, "register must be x0..x30 with required shift 'lsl #3'");
5183   case Match_InvalidGPR64NoXZRshifted128:
5184     return Error(Loc, "register must be x0..x30 with required shift 'lsl #4'");
5185   case Match_InvalidZPR32UXTW8:
5186   case Match_InvalidZPR32SXTW8:
5187     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
5188   case Match_InvalidZPR32UXTW16:
5189   case Match_InvalidZPR32SXTW16:
5190     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
5191   case Match_InvalidZPR32UXTW32:
5192   case Match_InvalidZPR32SXTW32:
5193     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
5194   case Match_InvalidZPR32UXTW64:
5195   case Match_InvalidZPR32SXTW64:
5196     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
5197   case Match_InvalidZPR64UXTW8:
5198   case Match_InvalidZPR64SXTW8:
5199     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
5200   case Match_InvalidZPR64UXTW16:
5201   case Match_InvalidZPR64SXTW16:
5202     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
5203   case Match_InvalidZPR64UXTW32:
5204   case Match_InvalidZPR64SXTW32:
5205     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
5206   case Match_InvalidZPR64UXTW64:
5207   case Match_InvalidZPR64SXTW64:
5208     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
5209   case Match_InvalidZPR32LSL8:
5210     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s'");
5211   case Match_InvalidZPR32LSL16:
5212     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
5213   case Match_InvalidZPR32LSL32:
5214     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
5215   case Match_InvalidZPR32LSL64:
5216     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
5217   case Match_InvalidZPR64LSL8:
5218     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d'");
5219   case Match_InvalidZPR64LSL16:
5220     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
5221   case Match_InvalidZPR64LSL32:
5222     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
5223   case Match_InvalidZPR64LSL64:
5224     return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
5225   case Match_InvalidZPR0:
5226     return Error(Loc, "expected register without element width suffix");
5227   case Match_InvalidZPR8:
5228   case Match_InvalidZPR16:
5229   case Match_InvalidZPR32:
5230   case Match_InvalidZPR64:
5231   case Match_InvalidZPR128:
5232     return Error(Loc, "invalid element width");
5233   case Match_InvalidZPR_3b8:
5234     return Error(Loc, "Invalid restricted vector register, expected z0.b..z7.b");
5235   case Match_InvalidZPR_3b16:
5236     return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h");
5237   case Match_InvalidZPR_3b32:
5238     return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s");
5239   case Match_InvalidZPR_4b16:
5240     return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h");
5241   case Match_InvalidZPR_4b32:
5242     return Error(Loc, "Invalid restricted vector register, expected z0.s..z15.s");
5243   case Match_InvalidZPR_4b64:
5244     return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d");
5245   case Match_InvalidSVEPattern:
5246     return Error(Loc, "invalid predicate pattern");
5247   case Match_InvalidSVEPredicateAnyReg:
5248   case Match_InvalidSVEPredicateBReg:
5249   case Match_InvalidSVEPredicateHReg:
5250   case Match_InvalidSVEPredicateSReg:
5251   case Match_InvalidSVEPredicateDReg:
5252     return Error(Loc, "invalid predicate register.");
5253   case Match_InvalidSVEPredicate3bAnyReg:
5254     return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)");
5255   case Match_InvalidSVEPredicate3bBReg:
5256     return Error(Loc, "invalid restricted predicate register, expected p0.b..p7.b");
5257   case Match_InvalidSVEPredicate3bHReg:
5258     return Error(Loc, "invalid restricted predicate register, expected p0.h..p7.h");
5259   case Match_InvalidSVEPredicate3bSReg:
5260     return Error(Loc, "invalid restricted predicate register, expected p0.s..p7.s");
5261   case Match_InvalidSVEPredicate3bDReg:
5262     return Error(Loc, "invalid restricted predicate register, expected p0.d..p7.d");
5263   case Match_InvalidSVEExactFPImmOperandHalfOne:
5264     return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0.");
5265   case Match_InvalidSVEExactFPImmOperandHalfTwo:
5266     return Error(Loc, "Invalid floating point constant, expected 0.5 or 2.0.");
5267   case Match_InvalidSVEExactFPImmOperandZeroOne:
5268     return Error(Loc, "Invalid floating point constant, expected 0.0 or 1.0.");
5269   case Match_InvalidMatrixTileVectorH8:
5270   case Match_InvalidMatrixTileVectorV8:
5271     return Error(Loc, "invalid matrix operand, expected za0h.b or za0v.b");
5272   case Match_InvalidMatrixTileVectorH16:
5273   case Match_InvalidMatrixTileVectorV16:
5274     return Error(Loc,
5275                  "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
5276   case Match_InvalidMatrixTileVectorH32:
5277   case Match_InvalidMatrixTileVectorV32:
5278     return Error(Loc,
5279                  "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
5280   case Match_InvalidMatrixTileVectorH64:
5281   case Match_InvalidMatrixTileVectorV64:
5282     return Error(Loc,
5283                  "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
5284   case Match_InvalidMatrixTileVectorH128:
5285   case Match_InvalidMatrixTileVectorV128:
5286     return Error(Loc,
5287                  "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
5288   case Match_InvalidMatrixTile32:
5289     return Error(Loc, "invalid matrix operand, expected za[0-3].s");
5290   case Match_InvalidMatrixTile64:
5291     return Error(Loc, "invalid matrix operand, expected za[0-7].d");
5292   case Match_InvalidMatrix:
5293     return Error(Loc, "invalid matrix operand, expected za");
5294   case Match_InvalidMatrixIndexGPR32_12_15:
5295     return Error(Loc, "operand must be a register in range [w12, w15]");
5296   default:
5297     llvm_unreachable("unexpected error code!");
5298   }
5299 }
5300 
5301 static const char *getSubtargetFeatureName(uint64_t Val);
5302 
5303 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5304                                                OperandVector &Operands,
5305                                                MCStreamer &Out,
5306                                                uint64_t &ErrorInfo,
5307                                                bool MatchingInlineAsm) {
5308   assert(!Operands.empty() && "Unexpect empty operand list!");
5309   AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
5310   assert(Op.isToken() && "Leading operand should always be a mnemonic!");
5311 
5312   StringRef Tok = Op.getToken();
5313   unsigned NumOperands = Operands.size();
5314 
5315   if (NumOperands == 4 && Tok == "lsl") {
5316     AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
5317     AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5318     if (Op2.isScalarReg() && Op3.isImm()) {
5319       const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
5320       if (Op3CE) {
5321         uint64_t Op3Val = Op3CE->getValue();
5322         uint64_t NewOp3Val = 0;
5323         uint64_t NewOp4Val = 0;
5324         if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
5325                 Op2.getReg())) {
5326           NewOp3Val = (32 - Op3Val) & 0x1f;
5327           NewOp4Val = 31 - Op3Val;
5328         } else {
5329           NewOp3Val = (64 - Op3Val) & 0x3f;
5330           NewOp4Val = 63 - Op3Val;
5331         }
5332 
5333         const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext());
5334         const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext());
5335 
5336         Operands[0] =
5337             AArch64Operand::CreateToken("ubfm", Op.getStartLoc(), getContext());
5338         Operands.push_back(AArch64Operand::CreateImm(
5339             NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
5340         Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
5341                                                 Op3.getEndLoc(), getContext());
5342       }
5343     }
5344   } else if (NumOperands == 4 && Tok == "bfc") {
5345     // FIXME: Horrible hack to handle BFC->BFM alias.
5346     AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5347     AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]);
5348     AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]);
5349 
5350     if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
5351       const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
5352       const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
5353 
5354       if (LSBCE && WidthCE) {
5355         uint64_t LSB = LSBCE->getValue();
5356         uint64_t Width = WidthCE->getValue();
5357 
5358         uint64_t RegWidth = 0;
5359         if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5360                 Op1.getReg()))
5361           RegWidth = 64;
5362         else
5363           RegWidth = 32;
5364 
5365         if (LSB >= RegWidth)
5366           return Error(LSBOp.getStartLoc(),
5367                        "expected integer in range [0, 31]");
5368         if (Width < 1 || Width > RegWidth)
5369           return Error(WidthOp.getStartLoc(),
5370                        "expected integer in range [1, 32]");
5371 
5372         uint64_t ImmR = 0;
5373         if (RegWidth == 32)
5374           ImmR = (32 - LSB) & 0x1f;
5375         else
5376           ImmR = (64 - LSB) & 0x3f;
5377 
5378         uint64_t ImmS = Width - 1;
5379 
5380         if (ImmR != 0 && ImmS >= ImmR)
5381           return Error(WidthOp.getStartLoc(),
5382                        "requested insert overflows register");
5383 
5384         const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext());
5385         const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext());
5386         Operands[0] =
5387             AArch64Operand::CreateToken("bfm", Op.getStartLoc(), getContext());
5388         Operands[2] = AArch64Operand::CreateReg(
5389             RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
5390             SMLoc(), SMLoc(), getContext());
5391         Operands[3] = AArch64Operand::CreateImm(
5392             ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
5393         Operands.emplace_back(
5394             AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
5395                                       WidthOp.getEndLoc(), getContext()));
5396       }
5397     }
5398   } else if (NumOperands == 5) {
5399     // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
5400     // UBFIZ -> UBFM aliases.
5401     if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
5402       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5403       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5404       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
5405 
5406       if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
5407         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
5408         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
5409 
5410         if (Op3CE && Op4CE) {
5411           uint64_t Op3Val = Op3CE->getValue();
5412           uint64_t Op4Val = Op4CE->getValue();
5413 
5414           uint64_t RegWidth = 0;
5415           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5416                   Op1.getReg()))
5417             RegWidth = 64;
5418           else
5419             RegWidth = 32;
5420 
5421           if (Op3Val >= RegWidth)
5422             return Error(Op3.getStartLoc(),
5423                          "expected integer in range [0, 31]");
5424           if (Op4Val < 1 || Op4Val > RegWidth)
5425             return Error(Op4.getStartLoc(),
5426                          "expected integer in range [1, 32]");
5427 
5428           uint64_t NewOp3Val = 0;
5429           if (RegWidth == 32)
5430             NewOp3Val = (32 - Op3Val) & 0x1f;
5431           else
5432             NewOp3Val = (64 - Op3Val) & 0x3f;
5433 
5434           uint64_t NewOp4Val = Op4Val - 1;
5435 
5436           if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
5437             return Error(Op4.getStartLoc(),
5438                          "requested insert overflows register");
5439 
5440           const MCExpr *NewOp3 =
5441               MCConstantExpr::create(NewOp3Val, getContext());
5442           const MCExpr *NewOp4 =
5443               MCConstantExpr::create(NewOp4Val, getContext());
5444           Operands[3] = AArch64Operand::CreateImm(
5445               NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
5446           Operands[4] = AArch64Operand::CreateImm(
5447               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
5448           if (Tok == "bfi")
5449             Operands[0] = AArch64Operand::CreateToken("bfm", Op.getStartLoc(),
5450                                                       getContext());
5451           else if (Tok == "sbfiz")
5452             Operands[0] = AArch64Operand::CreateToken("sbfm", Op.getStartLoc(),
5453                                                       getContext());
5454           else if (Tok == "ubfiz")
5455             Operands[0] = AArch64Operand::CreateToken("ubfm", Op.getStartLoc(),
5456                                                       getContext());
5457           else
5458             llvm_unreachable("No valid mnemonic for alias?");
5459         }
5460       }
5461 
5462       // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
5463       // UBFX -> UBFM aliases.
5464     } else if (NumOperands == 5 &&
5465                (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
5466       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5467       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5468       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
5469 
5470       if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
5471         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
5472         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
5473 
5474         if (Op3CE && Op4CE) {
5475           uint64_t Op3Val = Op3CE->getValue();
5476           uint64_t Op4Val = Op4CE->getValue();
5477 
5478           uint64_t RegWidth = 0;
5479           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5480                   Op1.getReg()))
5481             RegWidth = 64;
5482           else
5483             RegWidth = 32;
5484 
5485           if (Op3Val >= RegWidth)
5486             return Error(Op3.getStartLoc(),
5487                          "expected integer in range [0, 31]");
5488           if (Op4Val < 1 || Op4Val > RegWidth)
5489             return Error(Op4.getStartLoc(),
5490                          "expected integer in range [1, 32]");
5491 
5492           uint64_t NewOp4Val = Op3Val + Op4Val - 1;
5493 
5494           if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
5495             return Error(Op4.getStartLoc(),
5496                          "requested extract overflows register");
5497 
5498           const MCExpr *NewOp4 =
5499               MCConstantExpr::create(NewOp4Val, getContext());
5500           Operands[4] = AArch64Operand::CreateImm(
5501               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
5502           if (Tok == "bfxil")
5503             Operands[0] = AArch64Operand::CreateToken("bfm", Op.getStartLoc(),
5504                                                       getContext());
5505           else if (Tok == "sbfx")
5506             Operands[0] = AArch64Operand::CreateToken("sbfm", Op.getStartLoc(),
5507                                                       getContext());
5508           else if (Tok == "ubfx")
5509             Operands[0] = AArch64Operand::CreateToken("ubfm", Op.getStartLoc(),
5510                                                       getContext());
5511           else
5512             llvm_unreachable("No valid mnemonic for alias?");
5513         }
5514       }
5515     }
5516   }
5517 
5518   // The Cyclone CPU and early successors didn't execute the zero-cycle zeroing
5519   // instruction for FP registers correctly in some rare circumstances. Convert
5520   // it to a safe instruction and warn (because silently changing someone's
5521   // assembly is rude).
5522   if (getSTI().getFeatureBits()[AArch64::FeatureZCZeroingFPWorkaround] &&
5523       NumOperands == 4 && Tok == "movi") {
5524     AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
5525     AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
5526     AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
5527     if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
5528         (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
5529       StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
5530       if (Suffix.lower() == ".2d" &&
5531           cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
5532         Warning(IDLoc, "instruction movi.2d with immediate #0 may not function"
5533                 " correctly on this CPU, converting to equivalent movi.16b");
5534         // Switch the suffix to .16b.
5535         unsigned Idx = Op1.isToken() ? 1 : 2;
5536         Operands[Idx] =
5537             AArch64Operand::CreateToken(".16b", IDLoc, getContext());
5538       }
5539     }
5540   }
5541 
5542   // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
5543   //        InstAlias can't quite handle this since the reg classes aren't
5544   //        subclasses.
5545   if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
5546     // The source register can be Wn here, but the matcher expects a
5547     // GPR64. Twiddle it here if necessary.
5548     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
5549     if (Op.isScalarReg()) {
5550       unsigned Reg = getXRegFromWReg(Op.getReg());
5551       Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
5552                                               Op.getStartLoc(), Op.getEndLoc(),
5553                                               getContext());
5554     }
5555   }
5556   // FIXME: Likewise for sxt[bh] with a Xd dst operand
5557   else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
5558     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
5559     if (Op.isScalarReg() &&
5560         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5561             Op.getReg())) {
5562       // The source register can be Wn here, but the matcher expects a
5563       // GPR64. Twiddle it here if necessary.
5564       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
5565       if (Op.isScalarReg()) {
5566         unsigned Reg = getXRegFromWReg(Op.getReg());
5567         Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
5568                                                 Op.getStartLoc(),
5569                                                 Op.getEndLoc(), getContext());
5570       }
5571     }
5572   }
5573   // FIXME: Likewise for uxt[bh] with a Xd dst operand
5574   else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
5575     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
5576     if (Op.isScalarReg() &&
5577         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5578             Op.getReg())) {
5579       // The source register can be Wn here, but the matcher expects a
5580       // GPR32. Twiddle it here if necessary.
5581       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
5582       if (Op.isScalarReg()) {
5583         unsigned Reg = getWRegFromXReg(Op.getReg());
5584         Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
5585                                                 Op.getStartLoc(),
5586                                                 Op.getEndLoc(), getContext());
5587       }
5588     }
5589   }
5590 
5591   MCInst Inst;
5592   FeatureBitset MissingFeatures;
5593   // First try to match against the secondary set of tables containing the
5594   // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
5595   unsigned MatchResult =
5596       MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
5597                            MatchingInlineAsm, 1);
5598 
5599   // If that fails, try against the alternate table containing long-form NEON:
5600   // "fadd v0.2s, v1.2s, v2.2s"
5601   if (MatchResult != Match_Success) {
5602     // But first, save the short-form match result: we can use it in case the
5603     // long-form match also fails.
5604     auto ShortFormNEONErrorInfo = ErrorInfo;
5605     auto ShortFormNEONMatchResult = MatchResult;
5606     auto ShortFormNEONMissingFeatures = MissingFeatures;
5607 
5608     MatchResult =
5609         MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
5610                              MatchingInlineAsm, 0);
5611 
5612     // Now, both matches failed, and the long-form match failed on the mnemonic
5613     // suffix token operand.  The short-form match failure is probably more
5614     // relevant: use it instead.
5615     if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
5616         Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
5617         ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
5618       MatchResult = ShortFormNEONMatchResult;
5619       ErrorInfo = ShortFormNEONErrorInfo;
5620       MissingFeatures = ShortFormNEONMissingFeatures;
5621     }
5622   }
5623 
5624   switch (MatchResult) {
5625   case Match_Success: {
5626     // Perform range checking and other semantic validations
5627     SmallVector<SMLoc, 8> OperandLocs;
5628     NumOperands = Operands.size();
5629     for (unsigned i = 1; i < NumOperands; ++i)
5630       OperandLocs.push_back(Operands[i]->getStartLoc());
5631     if (validateInstruction(Inst, IDLoc, OperandLocs))
5632       return true;
5633 
5634     Inst.setLoc(IDLoc);
5635     Out.emitInstruction(Inst, getSTI());
5636     return false;
5637   }
5638   case Match_MissingFeature: {
5639     assert(MissingFeatures.any() && "Unknown missing feature!");
5640     // Special case the error message for the very common case where only
5641     // a single subtarget feature is missing (neon, e.g.).
5642     std::string Msg = "instruction requires:";
5643     for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
5644       if (MissingFeatures[i]) {
5645         Msg += " ";
5646         Msg += getSubtargetFeatureName(i);
5647       }
5648     }
5649     return Error(IDLoc, Msg);
5650   }
5651   case Match_MnemonicFail:
5652     return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
5653   case Match_InvalidOperand: {
5654     SMLoc ErrorLoc = IDLoc;
5655 
5656     if (ErrorInfo != ~0ULL) {
5657       if (ErrorInfo >= Operands.size())
5658         return Error(IDLoc, "too few operands for instruction",
5659                      SMRange(IDLoc, getTok().getLoc()));
5660 
5661       ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
5662       if (ErrorLoc == SMLoc())
5663         ErrorLoc = IDLoc;
5664     }
5665     // If the match failed on a suffix token operand, tweak the diagnostic
5666     // accordingly.
5667     if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
5668         ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
5669       MatchResult = Match_InvalidSuffix;
5670 
5671     return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
5672   }
5673   case Match_InvalidTiedOperand:
5674   case Match_InvalidMemoryIndexed1:
5675   case Match_InvalidMemoryIndexed2:
5676   case Match_InvalidMemoryIndexed4:
5677   case Match_InvalidMemoryIndexed8:
5678   case Match_InvalidMemoryIndexed16:
5679   case Match_InvalidCondCode:
5680   case Match_AddSubRegExtendSmall:
5681   case Match_AddSubRegExtendLarge:
5682   case Match_AddSubSecondSource:
5683   case Match_LogicalSecondSource:
5684   case Match_AddSubRegShift32:
5685   case Match_AddSubRegShift64:
5686   case Match_InvalidMovImm32Shift:
5687   case Match_InvalidMovImm64Shift:
5688   case Match_InvalidFPImm:
5689   case Match_InvalidMemoryWExtend8:
5690   case Match_InvalidMemoryWExtend16:
5691   case Match_InvalidMemoryWExtend32:
5692   case Match_InvalidMemoryWExtend64:
5693   case Match_InvalidMemoryWExtend128:
5694   case Match_InvalidMemoryXExtend8:
5695   case Match_InvalidMemoryXExtend16:
5696   case Match_InvalidMemoryXExtend32:
5697   case Match_InvalidMemoryXExtend64:
5698   case Match_InvalidMemoryXExtend128:
5699   case Match_InvalidMemoryIndexed1SImm4:
5700   case Match_InvalidMemoryIndexed2SImm4:
5701   case Match_InvalidMemoryIndexed3SImm4:
5702   case Match_InvalidMemoryIndexed4SImm4:
5703   case Match_InvalidMemoryIndexed1SImm6:
5704   case Match_InvalidMemoryIndexed16SImm4:
5705   case Match_InvalidMemoryIndexed32SImm4:
5706   case Match_InvalidMemoryIndexed4SImm7:
5707   case Match_InvalidMemoryIndexed8SImm7:
5708   case Match_InvalidMemoryIndexed16SImm7:
5709   case Match_InvalidMemoryIndexed8UImm5:
5710   case Match_InvalidMemoryIndexed4UImm5:
5711   case Match_InvalidMemoryIndexed2UImm5:
5712   case Match_InvalidMemoryIndexed1UImm6:
5713   case Match_InvalidMemoryIndexed2UImm6:
5714   case Match_InvalidMemoryIndexed4UImm6:
5715   case Match_InvalidMemoryIndexed8UImm6:
5716   case Match_InvalidMemoryIndexed16UImm6:
5717   case Match_InvalidMemoryIndexedSImm6:
5718   case Match_InvalidMemoryIndexedSImm5:
5719   case Match_InvalidMemoryIndexedSImm8:
5720   case Match_InvalidMemoryIndexedSImm9:
5721   case Match_InvalidMemoryIndexed16SImm9:
5722   case Match_InvalidMemoryIndexed8SImm10:
5723   case Match_InvalidImm0_1:
5724   case Match_InvalidImm0_3:
5725   case Match_InvalidImm0_7:
5726   case Match_InvalidImm0_15:
5727   case Match_InvalidImm0_31:
5728   case Match_InvalidImm0_63:
5729   case Match_InvalidImm0_127:
5730   case Match_InvalidImm0_255:
5731   case Match_InvalidImm0_65535:
5732   case Match_InvalidImm1_8:
5733   case Match_InvalidImm1_16:
5734   case Match_InvalidImm1_32:
5735   case Match_InvalidImm1_64:
5736   case Match_InvalidSVEAddSubImm8:
5737   case Match_InvalidSVEAddSubImm16:
5738   case Match_InvalidSVEAddSubImm32:
5739   case Match_InvalidSVEAddSubImm64:
5740   case Match_InvalidSVECpyImm8:
5741   case Match_InvalidSVECpyImm16:
5742   case Match_InvalidSVECpyImm32:
5743   case Match_InvalidSVECpyImm64:
5744   case Match_InvalidIndexRange1_1:
5745   case Match_InvalidIndexRange0_15:
5746   case Match_InvalidIndexRange0_7:
5747   case Match_InvalidIndexRange0_3:
5748   case Match_InvalidIndexRange0_1:
5749   case Match_InvalidSVEIndexRange0_63:
5750   case Match_InvalidSVEIndexRange0_31:
5751   case Match_InvalidSVEIndexRange0_15:
5752   case Match_InvalidSVEIndexRange0_7:
5753   case Match_InvalidSVEIndexRange0_3:
5754   case Match_InvalidLabel:
5755   case Match_InvalidComplexRotationEven:
5756   case Match_InvalidComplexRotationOdd:
5757   case Match_InvalidGPR64shifted8:
5758   case Match_InvalidGPR64shifted16:
5759   case Match_InvalidGPR64shifted32:
5760   case Match_InvalidGPR64shifted64:
5761   case Match_InvalidGPR64shifted128:
5762   case Match_InvalidGPR64NoXZRshifted8:
5763   case Match_InvalidGPR64NoXZRshifted16:
5764   case Match_InvalidGPR64NoXZRshifted32:
5765   case Match_InvalidGPR64NoXZRshifted64:
5766   case Match_InvalidGPR64NoXZRshifted128:
5767   case Match_InvalidZPR32UXTW8:
5768   case Match_InvalidZPR32UXTW16:
5769   case Match_InvalidZPR32UXTW32:
5770   case Match_InvalidZPR32UXTW64:
5771   case Match_InvalidZPR32SXTW8:
5772   case Match_InvalidZPR32SXTW16:
5773   case Match_InvalidZPR32SXTW32:
5774   case Match_InvalidZPR32SXTW64:
5775   case Match_InvalidZPR64UXTW8:
5776   case Match_InvalidZPR64SXTW8:
5777   case Match_InvalidZPR64UXTW16:
5778   case Match_InvalidZPR64SXTW16:
5779   case Match_InvalidZPR64UXTW32:
5780   case Match_InvalidZPR64SXTW32:
5781   case Match_InvalidZPR64UXTW64:
5782   case Match_InvalidZPR64SXTW64:
5783   case Match_InvalidZPR32LSL8:
5784   case Match_InvalidZPR32LSL16:
5785   case Match_InvalidZPR32LSL32:
5786   case Match_InvalidZPR32LSL64:
5787   case Match_InvalidZPR64LSL8:
5788   case Match_InvalidZPR64LSL16:
5789   case Match_InvalidZPR64LSL32:
5790   case Match_InvalidZPR64LSL64:
5791   case Match_InvalidZPR0:
5792   case Match_InvalidZPR8:
5793   case Match_InvalidZPR16:
5794   case Match_InvalidZPR32:
5795   case Match_InvalidZPR64:
5796   case Match_InvalidZPR128:
5797   case Match_InvalidZPR_3b8:
5798   case Match_InvalidZPR_3b16:
5799   case Match_InvalidZPR_3b32:
5800   case Match_InvalidZPR_4b16:
5801   case Match_InvalidZPR_4b32:
5802   case Match_InvalidZPR_4b64:
5803   case Match_InvalidSVEPredicateAnyReg:
5804   case Match_InvalidSVEPattern:
5805   case Match_InvalidSVEPredicateBReg:
5806   case Match_InvalidSVEPredicateHReg:
5807   case Match_InvalidSVEPredicateSReg:
5808   case Match_InvalidSVEPredicateDReg:
5809   case Match_InvalidSVEPredicate3bAnyReg:
5810   case Match_InvalidSVEPredicate3bBReg:
5811   case Match_InvalidSVEPredicate3bHReg:
5812   case Match_InvalidSVEPredicate3bSReg:
5813   case Match_InvalidSVEPredicate3bDReg:
5814   case Match_InvalidSVEExactFPImmOperandHalfOne:
5815   case Match_InvalidSVEExactFPImmOperandHalfTwo:
5816   case Match_InvalidSVEExactFPImmOperandZeroOne:
5817   case Match_InvalidMatrixTile32:
5818   case Match_InvalidMatrixTile64:
5819   case Match_InvalidMatrix:
5820   case Match_InvalidMatrixTileVectorH8:
5821   case Match_InvalidMatrixTileVectorH16:
5822   case Match_InvalidMatrixTileVectorH32:
5823   case Match_InvalidMatrixTileVectorH64:
5824   case Match_InvalidMatrixTileVectorH128:
5825   case Match_InvalidMatrixTileVectorV8:
5826   case Match_InvalidMatrixTileVectorV16:
5827   case Match_InvalidMatrixTileVectorV32:
5828   case Match_InvalidMatrixTileVectorV64:
5829   case Match_InvalidMatrixTileVectorV128:
5830   case Match_InvalidSVCR:
5831   case Match_InvalidMatrixIndexGPR32_12_15:
5832   case Match_MSR:
5833   case Match_MRS: {
5834     if (ErrorInfo >= Operands.size())
5835       return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc()));
5836     // Any time we get here, there's nothing fancy to do. Just get the
5837     // operand SMLoc and display the diagnostic.
5838     SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
5839     if (ErrorLoc == SMLoc())
5840       ErrorLoc = IDLoc;
5841     return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
5842   }
5843   }
5844 
5845   llvm_unreachable("Implement any new match types added!");
5846 }
5847 
5848 /// ParseDirective parses the arm specific directives
5849 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
5850   const MCContext::Environment Format = getContext().getObjectFileType();
5851   bool IsMachO = Format == MCContext::IsMachO;
5852   bool IsCOFF = Format == MCContext::IsCOFF;
5853 
5854   auto IDVal = DirectiveID.getIdentifier().lower();
5855   SMLoc Loc = DirectiveID.getLoc();
5856   if (IDVal == ".arch")
5857     parseDirectiveArch(Loc);
5858   else if (IDVal == ".cpu")
5859     parseDirectiveCPU(Loc);
5860   else if (IDVal == ".tlsdesccall")
5861     parseDirectiveTLSDescCall(Loc);
5862   else if (IDVal == ".ltorg" || IDVal == ".pool")
5863     parseDirectiveLtorg(Loc);
5864   else if (IDVal == ".unreq")
5865     parseDirectiveUnreq(Loc);
5866   else if (IDVal == ".inst")
5867     parseDirectiveInst(Loc);
5868   else if (IDVal == ".cfi_negate_ra_state")
5869     parseDirectiveCFINegateRAState();
5870   else if (IDVal == ".cfi_b_key_frame")
5871     parseDirectiveCFIBKeyFrame();
5872   else if (IDVal == ".arch_extension")
5873     parseDirectiveArchExtension(Loc);
5874   else if (IDVal == ".variant_pcs")
5875     parseDirectiveVariantPCS(Loc);
5876   else if (IsMachO) {
5877     if (IDVal == MCLOHDirectiveName())
5878       parseDirectiveLOH(IDVal, Loc);
5879     else
5880       return true;
5881   } else if (IsCOFF) {
5882     if (IDVal == ".seh_stackalloc")
5883       parseDirectiveSEHAllocStack(Loc);
5884     else if (IDVal == ".seh_endprologue")
5885       parseDirectiveSEHPrologEnd(Loc);
5886     else if (IDVal == ".seh_save_r19r20_x")
5887       parseDirectiveSEHSaveR19R20X(Loc);
5888     else if (IDVal == ".seh_save_fplr")
5889       parseDirectiveSEHSaveFPLR(Loc);
5890     else if (IDVal == ".seh_save_fplr_x")
5891       parseDirectiveSEHSaveFPLRX(Loc);
5892     else if (IDVal == ".seh_save_reg")
5893       parseDirectiveSEHSaveReg(Loc);
5894     else if (IDVal == ".seh_save_reg_x")
5895       parseDirectiveSEHSaveRegX(Loc);
5896     else if (IDVal == ".seh_save_regp")
5897       parseDirectiveSEHSaveRegP(Loc);
5898     else if (IDVal == ".seh_save_regp_x")
5899       parseDirectiveSEHSaveRegPX(Loc);
5900     else if (IDVal == ".seh_save_lrpair")
5901       parseDirectiveSEHSaveLRPair(Loc);
5902     else if (IDVal == ".seh_save_freg")
5903       parseDirectiveSEHSaveFReg(Loc);
5904     else if (IDVal == ".seh_save_freg_x")
5905       parseDirectiveSEHSaveFRegX(Loc);
5906     else if (IDVal == ".seh_save_fregp")
5907       parseDirectiveSEHSaveFRegP(Loc);
5908     else if (IDVal == ".seh_save_fregp_x")
5909       parseDirectiveSEHSaveFRegPX(Loc);
5910     else if (IDVal == ".seh_set_fp")
5911       parseDirectiveSEHSetFP(Loc);
5912     else if (IDVal == ".seh_add_fp")
5913       parseDirectiveSEHAddFP(Loc);
5914     else if (IDVal == ".seh_nop")
5915       parseDirectiveSEHNop(Loc);
5916     else if (IDVal == ".seh_save_next")
5917       parseDirectiveSEHSaveNext(Loc);
5918     else if (IDVal == ".seh_startepilogue")
5919       parseDirectiveSEHEpilogStart(Loc);
5920     else if (IDVal == ".seh_endepilogue")
5921       parseDirectiveSEHEpilogEnd(Loc);
5922     else if (IDVal == ".seh_trap_frame")
5923       parseDirectiveSEHTrapFrame(Loc);
5924     else if (IDVal == ".seh_pushframe")
5925       parseDirectiveSEHMachineFrame(Loc);
5926     else if (IDVal == ".seh_context")
5927       parseDirectiveSEHContext(Loc);
5928     else if (IDVal == ".seh_clear_unwound_to_call")
5929       parseDirectiveSEHClearUnwoundToCall(Loc);
5930     else
5931       return true;
5932   } else
5933     return true;
5934   return false;
5935 }
5936 
5937 static void ExpandCryptoAEK(AArch64::ArchKind ArchKind,
5938                             SmallVector<StringRef, 4> &RequestedExtensions) {
5939   const bool NoCrypto = llvm::is_contained(RequestedExtensions, "nocrypto");
5940   const bool Crypto = llvm::is_contained(RequestedExtensions, "crypto");
5941 
5942   if (!NoCrypto && Crypto) {
5943     switch (ArchKind) {
5944     default:
5945       // Map 'generic' (and others) to sha2 and aes, because
5946       // that was the traditional meaning of crypto.
5947     case AArch64::ArchKind::ARMV8_1A:
5948     case AArch64::ArchKind::ARMV8_2A:
5949     case AArch64::ArchKind::ARMV8_3A:
5950       RequestedExtensions.push_back("sha2");
5951       RequestedExtensions.push_back("aes");
5952       break;
5953     case AArch64::ArchKind::ARMV8_4A:
5954     case AArch64::ArchKind::ARMV8_5A:
5955     case AArch64::ArchKind::ARMV8_6A:
5956     case AArch64::ArchKind::ARMV8_7A:
5957     case AArch64::ArchKind::ARMV8R:
5958       RequestedExtensions.push_back("sm4");
5959       RequestedExtensions.push_back("sha3");
5960       RequestedExtensions.push_back("sha2");
5961       RequestedExtensions.push_back("aes");
5962       break;
5963     }
5964   } else if (NoCrypto) {
5965     switch (ArchKind) {
5966     default:
5967       // Map 'generic' (and others) to sha2 and aes, because
5968       // that was the traditional meaning of crypto.
5969     case AArch64::ArchKind::ARMV8_1A:
5970     case AArch64::ArchKind::ARMV8_2A:
5971     case AArch64::ArchKind::ARMV8_3A:
5972       RequestedExtensions.push_back("nosha2");
5973       RequestedExtensions.push_back("noaes");
5974       break;
5975     case AArch64::ArchKind::ARMV8_4A:
5976     case AArch64::ArchKind::ARMV8_5A:
5977     case AArch64::ArchKind::ARMV8_6A:
5978     case AArch64::ArchKind::ARMV8_7A:
5979       RequestedExtensions.push_back("nosm4");
5980       RequestedExtensions.push_back("nosha3");
5981       RequestedExtensions.push_back("nosha2");
5982       RequestedExtensions.push_back("noaes");
5983       break;
5984     }
5985   }
5986 }
5987 
5988 /// parseDirectiveArch
5989 ///   ::= .arch token
5990 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
5991   SMLoc ArchLoc = getLoc();
5992 
5993   StringRef Arch, ExtensionString;
5994   std::tie(Arch, ExtensionString) =
5995       getParser().parseStringToEndOfStatement().trim().split('+');
5996 
5997   AArch64::ArchKind ID = AArch64::parseArch(Arch);
5998   if (ID == AArch64::ArchKind::INVALID)
5999     return Error(ArchLoc, "unknown arch name");
6000 
6001   if (parseToken(AsmToken::EndOfStatement))
6002     return true;
6003 
6004   // Get the architecture and extension features.
6005   std::vector<StringRef> AArch64Features;
6006   AArch64::getArchFeatures(ID, AArch64Features);
6007   AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID),
6008                                 AArch64Features);
6009 
6010   MCSubtargetInfo &STI = copySTI();
6011   std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
6012   STI.setDefaultFeatures("generic", /*TuneCPU*/ "generic",
6013                          join(ArchFeatures.begin(), ArchFeatures.end(), ","));
6014 
6015   SmallVector<StringRef, 4> RequestedExtensions;
6016   if (!ExtensionString.empty())
6017     ExtensionString.split(RequestedExtensions, '+');
6018 
6019   ExpandCryptoAEK(ID, RequestedExtensions);
6020 
6021   FeatureBitset Features = STI.getFeatureBits();
6022   for (auto Name : RequestedExtensions) {
6023     bool EnableFeature = true;
6024 
6025     if (Name.startswith_insensitive("no")) {
6026       EnableFeature = false;
6027       Name = Name.substr(2);
6028     }
6029 
6030     for (const auto &Extension : ExtensionMap) {
6031       if (Extension.Name != Name)
6032         continue;
6033 
6034       if (Extension.Features.none())
6035         report_fatal_error("unsupported architectural extension: " + Name);
6036 
6037       FeatureBitset ToggleFeatures = EnableFeature
6038                                          ? (~Features & Extension.Features)
6039                                          : ( Features & Extension.Features);
6040       FeatureBitset Features =
6041           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
6042       setAvailableFeatures(Features);
6043       break;
6044     }
6045   }
6046   return false;
6047 }
6048 
6049 /// parseDirectiveArchExtension
6050 ///   ::= .arch_extension [no]feature
6051 bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
6052   SMLoc ExtLoc = getLoc();
6053 
6054   StringRef Name = getParser().parseStringToEndOfStatement().trim();
6055 
6056   if (parseToken(AsmToken::EndOfStatement,
6057                  "unexpected token in '.arch_extension' directive"))
6058     return true;
6059 
6060   bool EnableFeature = true;
6061   if (Name.startswith_insensitive("no")) {
6062     EnableFeature = false;
6063     Name = Name.substr(2);
6064   }
6065 
6066   MCSubtargetInfo &STI = copySTI();
6067   FeatureBitset Features = STI.getFeatureBits();
6068   for (const auto &Extension : ExtensionMap) {
6069     if (Extension.Name != Name)
6070       continue;
6071 
6072     if (Extension.Features.none())
6073       return Error(ExtLoc, "unsupported architectural extension: " + Name);
6074 
6075     FeatureBitset ToggleFeatures = EnableFeature
6076                                        ? (~Features & Extension.Features)
6077                                        : (Features & Extension.Features);
6078     FeatureBitset Features =
6079         ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
6080     setAvailableFeatures(Features);
6081     return false;
6082   }
6083 
6084   return Error(ExtLoc, "unknown architectural extension: " + Name);
6085 }
6086 
6087 static SMLoc incrementLoc(SMLoc L, int Offset) {
6088   return SMLoc::getFromPointer(L.getPointer() + Offset);
6089 }
6090 
6091 /// parseDirectiveCPU
6092 ///   ::= .cpu id
6093 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
6094   SMLoc CurLoc = getLoc();
6095 
6096   StringRef CPU, ExtensionString;
6097   std::tie(CPU, ExtensionString) =
6098       getParser().parseStringToEndOfStatement().trim().split('+');
6099 
6100   if (parseToken(AsmToken::EndOfStatement))
6101     return true;
6102 
6103   SmallVector<StringRef, 4> RequestedExtensions;
6104   if (!ExtensionString.empty())
6105     ExtensionString.split(RequestedExtensions, '+');
6106 
6107   // FIXME This is using tablegen data, but should be moved to ARMTargetParser
6108   // once that is tablegen'ed
6109   if (!getSTI().isCPUStringValid(CPU)) {
6110     Error(CurLoc, "unknown CPU name");
6111     return false;
6112   }
6113 
6114   MCSubtargetInfo &STI = copySTI();
6115   STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
6116   CurLoc = incrementLoc(CurLoc, CPU.size());
6117 
6118   ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions);
6119 
6120   FeatureBitset Features = STI.getFeatureBits();
6121   for (auto Name : RequestedExtensions) {
6122     // Advance source location past '+'.
6123     CurLoc = incrementLoc(CurLoc, 1);
6124 
6125     bool EnableFeature = true;
6126 
6127     if (Name.startswith_insensitive("no")) {
6128       EnableFeature = false;
6129       Name = Name.substr(2);
6130     }
6131 
6132     bool FoundExtension = false;
6133     for (const auto &Extension : ExtensionMap) {
6134       if (Extension.Name != Name)
6135         continue;
6136 
6137       if (Extension.Features.none())
6138         report_fatal_error("unsupported architectural extension: " + Name);
6139 
6140       FeatureBitset ToggleFeatures = EnableFeature
6141                                          ? (~Features & Extension.Features)
6142                                          : ( Features & Extension.Features);
6143       FeatureBitset Features =
6144           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
6145       setAvailableFeatures(Features);
6146       FoundExtension = true;
6147 
6148       break;
6149     }
6150 
6151     if (!FoundExtension)
6152       Error(CurLoc, "unsupported architectural extension");
6153 
6154     CurLoc = incrementLoc(CurLoc, Name.size());
6155   }
6156   return false;
6157 }
6158 
6159 /// parseDirectiveInst
6160 ///  ::= .inst opcode [, ...]
6161 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
6162   if (getLexer().is(AsmToken::EndOfStatement))
6163     return Error(Loc, "expected expression following '.inst' directive");
6164 
6165   auto parseOp = [&]() -> bool {
6166     SMLoc L = getLoc();
6167     const MCExpr *Expr = nullptr;
6168     if (check(getParser().parseExpression(Expr), L, "expected expression"))
6169       return true;
6170     const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
6171     if (check(!Value, L, "expected constant expression"))
6172       return true;
6173     getTargetStreamer().emitInst(Value->getValue());
6174     return false;
6175   };
6176 
6177   return parseMany(parseOp);
6178 }
6179 
6180 // parseDirectiveTLSDescCall:
6181 //   ::= .tlsdesccall symbol
6182 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
6183   StringRef Name;
6184   if (check(getParser().parseIdentifier(Name), L,
6185             "expected symbol after directive") ||
6186       parseToken(AsmToken::EndOfStatement))
6187     return true;
6188 
6189   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6190   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
6191   Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
6192 
6193   MCInst Inst;
6194   Inst.setOpcode(AArch64::TLSDESCCALL);
6195   Inst.addOperand(MCOperand::createExpr(Expr));
6196 
6197   getParser().getStreamer().emitInstruction(Inst, getSTI());
6198   return false;
6199 }
6200 
6201 /// ::= .loh <lohName | lohId> label1, ..., labelN
6202 /// The number of arguments depends on the loh identifier.
6203 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
6204   MCLOHType Kind;
6205   if (getTok().isNot(AsmToken::Identifier)) {
6206     if (getTok().isNot(AsmToken::Integer))
6207       return TokError("expected an identifier or a number in directive");
6208     // We successfully get a numeric value for the identifier.
6209     // Check if it is valid.
6210     int64_t Id = getTok().getIntVal();
6211     if (Id <= -1U && !isValidMCLOHType(Id))
6212       return TokError("invalid numeric identifier in directive");
6213     Kind = (MCLOHType)Id;
6214   } else {
6215     StringRef Name = getTok().getIdentifier();
6216     // We successfully parse an identifier.
6217     // Check if it is a recognized one.
6218     int Id = MCLOHNameToId(Name);
6219 
6220     if (Id == -1)
6221       return TokError("invalid identifier in directive");
6222     Kind = (MCLOHType)Id;
6223   }
6224   // Consume the identifier.
6225   Lex();
6226   // Get the number of arguments of this LOH.
6227   int NbArgs = MCLOHIdToNbArgs(Kind);
6228 
6229   assert(NbArgs != -1 && "Invalid number of arguments");
6230 
6231   SmallVector<MCSymbol *, 3> Args;
6232   for (int Idx = 0; Idx < NbArgs; ++Idx) {
6233     StringRef Name;
6234     if (getParser().parseIdentifier(Name))
6235       return TokError("expected identifier in directive");
6236     Args.push_back(getContext().getOrCreateSymbol(Name));
6237 
6238     if (Idx + 1 == NbArgs)
6239       break;
6240     if (parseToken(AsmToken::Comma,
6241                    "unexpected token in '" + Twine(IDVal) + "' directive"))
6242       return true;
6243   }
6244   if (parseToken(AsmToken::EndOfStatement,
6245                  "unexpected token in '" + Twine(IDVal) + "' directive"))
6246     return true;
6247 
6248   getStreamer().emitLOHDirective((MCLOHType)Kind, Args);
6249   return false;
6250 }
6251 
6252 /// parseDirectiveLtorg
6253 ///  ::= .ltorg | .pool
6254 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
6255   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
6256     return true;
6257   getTargetStreamer().emitCurrentConstantPool();
6258   return false;
6259 }
6260 
6261 /// parseDirectiveReq
6262 ///  ::= name .req registername
6263 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
6264   MCAsmParser &Parser = getParser();
6265   Parser.Lex(); // Eat the '.req' token.
6266   SMLoc SRegLoc = getLoc();
6267   RegKind RegisterKind = RegKind::Scalar;
6268   unsigned RegNum;
6269   OperandMatchResultTy ParseRes = tryParseScalarRegister(RegNum);
6270 
6271   if (ParseRes != MatchOperand_Success) {
6272     StringRef Kind;
6273     RegisterKind = RegKind::NeonVector;
6274     ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
6275 
6276     if (ParseRes == MatchOperand_ParseFail)
6277       return true;
6278 
6279     if (ParseRes == MatchOperand_Success && !Kind.empty())
6280       return Error(SRegLoc, "vector register without type specifier expected");
6281   }
6282 
6283   if (ParseRes != MatchOperand_Success) {
6284     StringRef Kind;
6285     RegisterKind = RegKind::SVEDataVector;
6286     ParseRes =
6287         tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
6288 
6289     if (ParseRes == MatchOperand_ParseFail)
6290       return true;
6291 
6292     if (ParseRes == MatchOperand_Success && !Kind.empty())
6293       return Error(SRegLoc,
6294                    "sve vector register without type specifier expected");
6295   }
6296 
6297   if (ParseRes != MatchOperand_Success) {
6298     StringRef Kind;
6299     RegisterKind = RegKind::SVEPredicateVector;
6300     ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
6301 
6302     if (ParseRes == MatchOperand_ParseFail)
6303       return true;
6304 
6305     if (ParseRes == MatchOperand_Success && !Kind.empty())
6306       return Error(SRegLoc,
6307                    "sve predicate register without type specifier expected");
6308   }
6309 
6310   if (ParseRes != MatchOperand_Success)
6311     return Error(SRegLoc, "register name or alias expected");
6312 
6313   // Shouldn't be anything else.
6314   if (parseToken(AsmToken::EndOfStatement,
6315                  "unexpected input in .req directive"))
6316     return true;
6317 
6318   auto pair = std::make_pair(RegisterKind, (unsigned) RegNum);
6319   if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
6320     Warning(L, "ignoring redefinition of register alias '" + Name + "'");
6321 
6322   return false;
6323 }
6324 
6325 /// parseDirectiveUneq
6326 ///  ::= .unreq registername
6327 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
6328   MCAsmParser &Parser = getParser();
6329   if (getTok().isNot(AsmToken::Identifier))
6330     return TokError("unexpected input in .unreq directive.");
6331   RegisterReqs.erase(getTok().getIdentifier().lower());
6332   Parser.Lex(); // Eat the identifier.
6333   return parseToken(AsmToken::EndOfStatement);
6334 }
6335 
6336 bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
6337   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
6338     return true;
6339   getStreamer().emitCFINegateRAState();
6340   return false;
6341 }
6342 
6343 /// parseDirectiveCFIBKeyFrame
6344 /// ::= .cfi_b_key
6345 bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
6346   if (parseToken(AsmToken::EndOfStatement,
6347                  "unexpected token in '.cfi_b_key_frame'"))
6348     return true;
6349   getStreamer().emitCFIBKeyFrame();
6350   return false;
6351 }
6352 
6353 /// parseDirectiveVariantPCS
6354 /// ::= .variant_pcs symbolname
6355 bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
6356   MCAsmParser &Parser = getParser();
6357 
6358   const AsmToken &Tok = getTok();
6359   if (Tok.isNot(AsmToken::Identifier))
6360     return TokError("expected symbol name");
6361 
6362   StringRef SymbolName = Tok.getIdentifier();
6363 
6364   MCSymbol *Sym = getContext().lookupSymbol(SymbolName);
6365   if (!Sym)
6366     return TokError("unknown symbol");
6367 
6368   Parser.Lex(); // Eat the symbol
6369 
6370   if (parseEOL())
6371     return true;
6372   getTargetStreamer().emitDirectiveVariantPCS(Sym);
6373   return false;
6374 }
6375 
6376 /// parseDirectiveSEHAllocStack
6377 /// ::= .seh_stackalloc
6378 bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
6379   int64_t Size;
6380   if (parseImmExpr(Size))
6381     return true;
6382   getTargetStreamer().emitARM64WinCFIAllocStack(Size);
6383   return false;
6384 }
6385 
6386 /// parseDirectiveSEHPrologEnd
6387 /// ::= .seh_endprologue
6388 bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
6389   getTargetStreamer().emitARM64WinCFIPrologEnd();
6390   return false;
6391 }
6392 
6393 /// parseDirectiveSEHSaveR19R20X
6394 /// ::= .seh_save_r19r20_x
6395 bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
6396   int64_t Offset;
6397   if (parseImmExpr(Offset))
6398     return true;
6399   getTargetStreamer().emitARM64WinCFISaveR19R20X(Offset);
6400   return false;
6401 }
6402 
6403 /// parseDirectiveSEHSaveFPLR
6404 /// ::= .seh_save_fplr
6405 bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
6406   int64_t Offset;
6407   if (parseImmExpr(Offset))
6408     return true;
6409   getTargetStreamer().emitARM64WinCFISaveFPLR(Offset);
6410   return false;
6411 }
6412 
6413 /// parseDirectiveSEHSaveFPLRX
6414 /// ::= .seh_save_fplr_x
6415 bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
6416   int64_t Offset;
6417   if (parseImmExpr(Offset))
6418     return true;
6419   getTargetStreamer().emitARM64WinCFISaveFPLRX(Offset);
6420   return false;
6421 }
6422 
6423 /// parseDirectiveSEHSaveReg
6424 /// ::= .seh_save_reg
6425 bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
6426   unsigned Reg;
6427   int64_t Offset;
6428   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
6429       parseComma() || parseImmExpr(Offset))
6430     return true;
6431   getTargetStreamer().emitARM64WinCFISaveReg(Reg, Offset);
6432   return false;
6433 }
6434 
6435 /// parseDirectiveSEHSaveRegX
6436 /// ::= .seh_save_reg_x
6437 bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
6438   unsigned Reg;
6439   int64_t Offset;
6440   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
6441       parseComma() || parseImmExpr(Offset))
6442     return true;
6443   getTargetStreamer().emitARM64WinCFISaveRegX(Reg, Offset);
6444   return false;
6445 }
6446 
6447 /// parseDirectiveSEHSaveRegP
6448 /// ::= .seh_save_regp
6449 bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
6450   unsigned Reg;
6451   int64_t Offset;
6452   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
6453       parseComma() || parseImmExpr(Offset))
6454     return true;
6455   getTargetStreamer().emitARM64WinCFISaveRegP(Reg, Offset);
6456   return false;
6457 }
6458 
6459 /// parseDirectiveSEHSaveRegPX
6460 /// ::= .seh_save_regp_x
6461 bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
6462   unsigned Reg;
6463   int64_t Offset;
6464   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
6465       parseComma() || parseImmExpr(Offset))
6466     return true;
6467   getTargetStreamer().emitARM64WinCFISaveRegPX(Reg, Offset);
6468   return false;
6469 }
6470 
6471 /// parseDirectiveSEHSaveLRPair
6472 /// ::= .seh_save_lrpair
6473 bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
6474   unsigned Reg;
6475   int64_t Offset;
6476   L = getLoc();
6477   if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
6478       parseComma() || parseImmExpr(Offset))
6479     return true;
6480   if (check(((Reg - 19) % 2 != 0), L,
6481             "expected register with even offset from x19"))
6482     return true;
6483   getTargetStreamer().emitARM64WinCFISaveLRPair(Reg, Offset);
6484   return false;
6485 }
6486 
6487 /// parseDirectiveSEHSaveFReg
6488 /// ::= .seh_save_freg
6489 bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
6490   unsigned Reg;
6491   int64_t Offset;
6492   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
6493       parseComma() || parseImmExpr(Offset))
6494     return true;
6495   getTargetStreamer().emitARM64WinCFISaveFReg(Reg, Offset);
6496   return false;
6497 }
6498 
6499 /// parseDirectiveSEHSaveFRegX
6500 /// ::= .seh_save_freg_x
6501 bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
6502   unsigned Reg;
6503   int64_t Offset;
6504   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
6505       parseComma() || parseImmExpr(Offset))
6506     return true;
6507   getTargetStreamer().emitARM64WinCFISaveFRegX(Reg, Offset);
6508   return false;
6509 }
6510 
6511 /// parseDirectiveSEHSaveFRegP
6512 /// ::= .seh_save_fregp
6513 bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
6514   unsigned Reg;
6515   int64_t Offset;
6516   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
6517       parseComma() || parseImmExpr(Offset))
6518     return true;
6519   getTargetStreamer().emitARM64WinCFISaveFRegP(Reg, Offset);
6520   return false;
6521 }
6522 
6523 /// parseDirectiveSEHSaveFRegPX
6524 /// ::= .seh_save_fregp_x
6525 bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
6526   unsigned Reg;
6527   int64_t Offset;
6528   if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
6529       parseComma() || parseImmExpr(Offset))
6530     return true;
6531   getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg, Offset);
6532   return false;
6533 }
6534 
6535 /// parseDirectiveSEHSetFP
6536 /// ::= .seh_set_fp
6537 bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
6538   getTargetStreamer().emitARM64WinCFISetFP();
6539   return false;
6540 }
6541 
6542 /// parseDirectiveSEHAddFP
6543 /// ::= .seh_add_fp
6544 bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
6545   int64_t Size;
6546   if (parseImmExpr(Size))
6547     return true;
6548   getTargetStreamer().emitARM64WinCFIAddFP(Size);
6549   return false;
6550 }
6551 
6552 /// parseDirectiveSEHNop
6553 /// ::= .seh_nop
6554 bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
6555   getTargetStreamer().emitARM64WinCFINop();
6556   return false;
6557 }
6558 
6559 /// parseDirectiveSEHSaveNext
6560 /// ::= .seh_save_next
6561 bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
6562   getTargetStreamer().emitARM64WinCFISaveNext();
6563   return false;
6564 }
6565 
6566 /// parseDirectiveSEHEpilogStart
6567 /// ::= .seh_startepilogue
6568 bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
6569   getTargetStreamer().emitARM64WinCFIEpilogStart();
6570   return false;
6571 }
6572 
6573 /// parseDirectiveSEHEpilogEnd
6574 /// ::= .seh_endepilogue
6575 bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
6576   getTargetStreamer().emitARM64WinCFIEpilogEnd();
6577   return false;
6578 }
6579 
6580 /// parseDirectiveSEHTrapFrame
6581 /// ::= .seh_trap_frame
6582 bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
6583   getTargetStreamer().emitARM64WinCFITrapFrame();
6584   return false;
6585 }
6586 
6587 /// parseDirectiveSEHMachineFrame
6588 /// ::= .seh_pushframe
6589 bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
6590   getTargetStreamer().emitARM64WinCFIMachineFrame();
6591   return false;
6592 }
6593 
6594 /// parseDirectiveSEHContext
6595 /// ::= .seh_context
6596 bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
6597   getTargetStreamer().emitARM64WinCFIContext();
6598   return false;
6599 }
6600 
6601 /// parseDirectiveSEHClearUnwoundToCall
6602 /// ::= .seh_clear_unwound_to_call
6603 bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
6604   getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
6605   return false;
6606 }
6607 
6608 bool
6609 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
6610                                     AArch64MCExpr::VariantKind &ELFRefKind,
6611                                     MCSymbolRefExpr::VariantKind &DarwinRefKind,
6612                                     int64_t &Addend) {
6613   ELFRefKind = AArch64MCExpr::VK_INVALID;
6614   DarwinRefKind = MCSymbolRefExpr::VK_None;
6615   Addend = 0;
6616 
6617   if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
6618     ELFRefKind = AE->getKind();
6619     Expr = AE->getSubExpr();
6620   }
6621 
6622   const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
6623   if (SE) {
6624     // It's a simple symbol reference with no addend.
6625     DarwinRefKind = SE->getKind();
6626     return true;
6627   }
6628 
6629   // Check that it looks like a symbol + an addend
6630   MCValue Res;
6631   bool Relocatable = Expr->evaluateAsRelocatable(Res, nullptr, nullptr);
6632   if (!Relocatable || Res.getSymB())
6633     return false;
6634 
6635   // Treat expressions with an ELFRefKind (like ":abs_g1:3", or
6636   // ":abs_g1:x" where x is constant) as symbolic even if there is no symbol.
6637   if (!Res.getSymA() && ELFRefKind == AArch64MCExpr::VK_INVALID)
6638     return false;
6639 
6640   if (Res.getSymA())
6641     DarwinRefKind = Res.getSymA()->getKind();
6642   Addend = Res.getConstant();
6643 
6644   // It's some symbol reference + a constant addend, but really
6645   // shouldn't use both Darwin and ELF syntax.
6646   return ELFRefKind == AArch64MCExpr::VK_INVALID ||
6647          DarwinRefKind == MCSymbolRefExpr::VK_None;
6648 }
6649 
6650 /// Force static initialization.
6651 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser() {
6652   RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget());
6653   RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget());
6654   RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target());
6655   RegisterMCAsmParser<AArch64AsmParser> W(getTheARM64_32Target());
6656   RegisterMCAsmParser<AArch64AsmParser> V(getTheAArch64_32Target());
6657 }
6658 
6659 #define GET_REGISTER_MATCHER
6660 #define GET_SUBTARGET_FEATURE_NAME
6661 #define GET_MATCHER_IMPLEMENTATION
6662 #define GET_MNEMONIC_SPELL_CHECKER
6663 #include "AArch64GenAsmMatcher.inc"
6664 
6665 // Define this matcher function after the auto-generated include so we
6666 // have the match class enum definitions.
6667 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
6668                                                       unsigned Kind) {
6669   AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
6670   // If the kind is a token for a literal immediate, check if our asm
6671   // operand matches. This is for InstAliases which have a fixed-value
6672   // immediate in the syntax.
6673   int64_t ExpectedVal;
6674   switch (Kind) {
6675   default:
6676     return Match_InvalidOperand;
6677   case MCK__HASH_0:
6678     ExpectedVal = 0;
6679     break;
6680   case MCK__HASH_1:
6681     ExpectedVal = 1;
6682     break;
6683   case MCK__HASH_12:
6684     ExpectedVal = 12;
6685     break;
6686   case MCK__HASH_16:
6687     ExpectedVal = 16;
6688     break;
6689   case MCK__HASH_2:
6690     ExpectedVal = 2;
6691     break;
6692   case MCK__HASH_24:
6693     ExpectedVal = 24;
6694     break;
6695   case MCK__HASH_3:
6696     ExpectedVal = 3;
6697     break;
6698   case MCK__HASH_32:
6699     ExpectedVal = 32;
6700     break;
6701   case MCK__HASH_4:
6702     ExpectedVal = 4;
6703     break;
6704   case MCK__HASH_48:
6705     ExpectedVal = 48;
6706     break;
6707   case MCK__HASH_6:
6708     ExpectedVal = 6;
6709     break;
6710   case MCK__HASH_64:
6711     ExpectedVal = 64;
6712     break;
6713   case MCK__HASH_8:
6714     ExpectedVal = 8;
6715     break;
6716   case MCK_MPR:
6717     // If the Kind is a token for the MPR register class which has the "za"
6718     // register (SME accumulator array), check if the asm is a literal "za"
6719     // token. This is for the "smstart za" alias that defines the register
6720     // as a literal token.
6721     if (Op.isTokenEqual("za"))
6722       return Match_Success;
6723     break;
6724   }
6725   if (!Op.isImm())
6726     return Match_InvalidOperand;
6727   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
6728   if (!CE)
6729     return Match_InvalidOperand;
6730   if (CE->getValue() == ExpectedVal)
6731     return Match_Success;
6732   return Match_InvalidOperand;
6733 }
6734 
6735 OperandMatchResultTy
6736 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
6737 
6738   SMLoc S = getLoc();
6739 
6740   if (getTok().isNot(AsmToken::Identifier)) {
6741     Error(S, "expected register");
6742     return MatchOperand_ParseFail;
6743   }
6744 
6745   unsigned FirstReg;
6746   OperandMatchResultTy Res = tryParseScalarRegister(FirstReg);
6747   if (Res != MatchOperand_Success)
6748     return MatchOperand_ParseFail;
6749 
6750   const MCRegisterClass &WRegClass =
6751       AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
6752   const MCRegisterClass &XRegClass =
6753       AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
6754 
6755   bool isXReg = XRegClass.contains(FirstReg),
6756        isWReg = WRegClass.contains(FirstReg);
6757   if (!isXReg && !isWReg) {
6758     Error(S, "expected first even register of a "
6759              "consecutive same-size even/odd register pair");
6760     return MatchOperand_ParseFail;
6761   }
6762 
6763   const MCRegisterInfo *RI = getContext().getRegisterInfo();
6764   unsigned FirstEncoding = RI->getEncodingValue(FirstReg);
6765 
6766   if (FirstEncoding & 0x1) {
6767     Error(S, "expected first even register of a "
6768              "consecutive same-size even/odd register pair");
6769     return MatchOperand_ParseFail;
6770   }
6771 
6772   if (getTok().isNot(AsmToken::Comma)) {
6773     Error(getLoc(), "expected comma");
6774     return MatchOperand_ParseFail;
6775   }
6776   // Eat the comma
6777   getParser().Lex();
6778 
6779   SMLoc E = getLoc();
6780   unsigned SecondReg;
6781   Res = tryParseScalarRegister(SecondReg);
6782   if (Res != MatchOperand_Success)
6783     return MatchOperand_ParseFail;
6784 
6785   if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 ||
6786       (isXReg && !XRegClass.contains(SecondReg)) ||
6787       (isWReg && !WRegClass.contains(SecondReg))) {
6788     Error(E,"expected second odd register of a "
6789              "consecutive same-size even/odd register pair");
6790     return MatchOperand_ParseFail;
6791   }
6792 
6793   unsigned Pair = 0;
6794   if (isXReg) {
6795     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64,
6796            &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
6797   } else {
6798     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32,
6799            &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
6800   }
6801 
6802   Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
6803       getLoc(), getContext()));
6804 
6805   return MatchOperand_Success;
6806 }
6807 
6808 template <bool ParseShiftExtend, bool ParseSuffix>
6809 OperandMatchResultTy
6810 AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) {
6811   const SMLoc S = getLoc();
6812   // Check for a SVE vector register specifier first.
6813   unsigned RegNum;
6814   StringRef Kind;
6815 
6816   OperandMatchResultTy Res =
6817       tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
6818 
6819   if (Res != MatchOperand_Success)
6820     return Res;
6821 
6822   if (ParseSuffix && Kind.empty())
6823     return MatchOperand_NoMatch;
6824 
6825   const auto &KindRes = parseVectorKind(Kind, RegKind::SVEDataVector);
6826   if (!KindRes)
6827     return MatchOperand_NoMatch;
6828 
6829   unsigned ElementWidth = KindRes->second;
6830 
6831   // No shift/extend is the default.
6832   if (!ParseShiftExtend || getTok().isNot(AsmToken::Comma)) {
6833     Operands.push_back(AArch64Operand::CreateVectorReg(
6834         RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
6835 
6836     OperandMatchResultTy Res = tryParseVectorIndex(Operands);
6837     if (Res == MatchOperand_ParseFail)
6838       return MatchOperand_ParseFail;
6839     return MatchOperand_Success;
6840   }
6841 
6842   // Eat the comma
6843   getParser().Lex();
6844 
6845   // Match the shift
6846   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd;
6847   Res = tryParseOptionalShiftExtend(ExtOpnd);
6848   if (Res != MatchOperand_Success)
6849     return Res;
6850 
6851   auto Ext = static_cast<AArch64Operand *>(ExtOpnd.back().get());
6852   Operands.push_back(AArch64Operand::CreateVectorReg(
6853       RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
6854       getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
6855       Ext->hasShiftExtendAmount()));
6856 
6857   return MatchOperand_Success;
6858 }
6859 
6860 OperandMatchResultTy
6861 AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) {
6862   MCAsmParser &Parser = getParser();
6863 
6864   SMLoc SS = getLoc();
6865   const AsmToken &TokE = getTok();
6866   bool IsHash = TokE.is(AsmToken::Hash);
6867 
6868   if (!IsHash && TokE.isNot(AsmToken::Identifier))
6869     return MatchOperand_NoMatch;
6870 
6871   int64_t Pattern;
6872   if (IsHash) {
6873     Parser.Lex(); // Eat hash
6874 
6875     // Parse the immediate operand.
6876     const MCExpr *ImmVal;
6877     SS = getLoc();
6878     if (Parser.parseExpression(ImmVal))
6879       return MatchOperand_ParseFail;
6880 
6881     auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
6882     if (!MCE)
6883       return MatchOperand_ParseFail;
6884 
6885     Pattern = MCE->getValue();
6886   } else {
6887     // Parse the pattern
6888     auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.getString());
6889     if (!Pat)
6890       return MatchOperand_NoMatch;
6891 
6892     Parser.Lex();
6893     Pattern = Pat->Encoding;
6894     assert(Pattern >= 0 && Pattern < 32);
6895   }
6896 
6897   Operands.push_back(
6898       AArch64Operand::CreateImm(MCConstantExpr::create(Pattern, getContext()),
6899                                 SS, getLoc(), getContext()));
6900 
6901   return MatchOperand_Success;
6902 }
6903 
6904 OperandMatchResultTy
6905 AArch64AsmParser::tryParseGPR64x8(OperandVector &Operands) {
6906   SMLoc SS = getLoc();
6907 
6908   unsigned XReg;
6909   if (tryParseScalarRegister(XReg) != MatchOperand_Success)
6910     return MatchOperand_NoMatch;
6911 
6912   MCContext &ctx = getContext();
6913   const MCRegisterInfo *RI = ctx.getRegisterInfo();
6914   int X8Reg = RI->getMatchingSuperReg(
6915       XReg, AArch64::x8sub_0,
6916       &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
6917   if (!X8Reg) {
6918     Error(SS, "expected an even-numbered x-register in the range [x0,x22]");
6919     return MatchOperand_ParseFail;
6920   }
6921 
6922   Operands.push_back(
6923       AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
6924   return MatchOperand_Success;
6925 }
6926