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