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