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