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