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