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