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