1 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "MCTargetDesc/AArch64AddressingModes.h"
11 #include "MCTargetDesc/AArch64MCExpr.h"
12 #include "MCTargetDesc/AArch64MCTargetDesc.h"
13 #include "MCTargetDesc/AArch64TargetStreamer.h"
14 #include "Utils/AArch64BaseInfo.h"
15 #include "llvm/ADT/APFloat.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/StringSwitch.h"
24 #include "llvm/ADT/Twine.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCExpr.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCLinkerOptimizationHint.h"
29 #include "llvm/MC/MCObjectFileInfo.h"
30 #include "llvm/MC/MCParser/MCAsmLexer.h"
31 #include "llvm/MC/MCParser/MCAsmParser.h"
32 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
33 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
35 #include "llvm/MC/MCRegisterInfo.h"
36 #include "llvm/MC/MCStreamer.h"
37 #include "llvm/MC/MCSubtargetInfo.h"
38 #include "llvm/MC/MCSymbol.h"
39 #include "llvm/MC/MCTargetOptions.h"
40 #include "llvm/MC/SubtargetFeature.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/Compiler.h"
43 #include "llvm/Support/ErrorHandling.h"
44 #include "llvm/Support/MathExtras.h"
45 #include "llvm/Support/SMLoc.h"
46 #include "llvm/Support/TargetParser.h"
47 #include "llvm/Support/TargetRegistry.h"
48 #include "llvm/Support/raw_ostream.h"
49 #include <cassert>
50 #include <cctype>
51 #include <cstdint>
52 #include <cstdio>
53 #include <string>
54 #include <tuple>
55 #include <utility>
56 #include <vector>
57 
58 using namespace llvm;
59 
60 namespace {
61 
62 class AArch64AsmParser : public MCTargetAsmParser {
63 private:
64   StringRef Mnemonic; ///< Instruction mnemonic.
65 
66   // Map of register aliases registers via the .req directive.
67   StringMap<std::pair<bool, unsigned>> RegisterReqs;
68 
69   AArch64TargetStreamer &getTargetStreamer() {
70     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
71     return static_cast<AArch64TargetStreamer &>(TS);
72   }
73 
74   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
75 
76   bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
77   AArch64CC::CondCode parseCondCodeString(StringRef Cond);
78   bool parseCondCode(OperandVector &Operands, bool invertCondCode);
79   unsigned matchRegisterNameAlias(StringRef Name, bool isVector);
80   int tryParseRegister();
81   int tryMatchVectorRegister(StringRef &Kind, bool expected);
82   bool parseRegister(OperandVector &Operands);
83   bool parseSymbolicImmVal(const MCExpr *&ImmVal);
84   bool parseVectorList(OperandVector &Operands);
85   bool parseOperand(OperandVector &Operands, bool isCondCode,
86                     bool invertCondCode);
87 
88   bool showMatchError(SMLoc Loc, unsigned ErrCode);
89 
90   bool parseDirectiveArch(SMLoc L);
91   bool parseDirectiveCPU(SMLoc L);
92   bool parseDirectiveWord(unsigned Size, SMLoc L);
93   bool parseDirectiveInst(SMLoc L);
94 
95   bool parseDirectiveTLSDescCall(SMLoc L);
96 
97   bool parseDirectiveLOH(StringRef LOH, SMLoc L);
98   bool parseDirectiveLtorg(SMLoc L);
99 
100   bool parseDirectiveReq(StringRef Name, SMLoc L);
101   bool parseDirectiveUnreq(SMLoc L);
102 
103   bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc);
104   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
105                                OperandVector &Operands, MCStreamer &Out,
106                                uint64_t &ErrorInfo,
107                                bool MatchingInlineAsm) override;
108 /// @name Auto-generated Match Functions
109 /// {
110 
111 #define GET_ASSEMBLER_HEADER
112 #include "AArch64GenAsmMatcher.inc"
113 
114   /// }
115 
116   OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
117   OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
118   OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
119   OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
120   OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
121   OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
122   OperandMatchResultTy tryParsePSBHint(OperandVector &Operands);
123   OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
124   OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
125   OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
126   OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands);
127   OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
128   bool tryParseVectorRegister(OperandVector &Operands);
129   OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands);
130 
131 public:
132   enum AArch64MatchResultTy {
133     Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
134 #define GET_OPERAND_DIAGNOSTIC_TYPES
135 #include "AArch64GenAsmMatcher.inc"
136   };
137   bool IsILP32;
138 
139   AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
140                    const MCInstrInfo &MII, const MCTargetOptions &Options)
141     : MCTargetAsmParser(Options, STI) {
142     IsILP32 = Options.getABIName() == "ilp32";
143     MCAsmParserExtension::Initialize(Parser);
144     MCStreamer &S = getParser().getStreamer();
145     if (S.getTargetStreamer() == nullptr)
146       new AArch64TargetStreamer(S);
147 
148     // Initialize the set of available features.
149     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
150   }
151 
152   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
153                         SMLoc NameLoc, OperandVector &Operands) override;
154   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
155   bool ParseDirective(AsmToken DirectiveID) override;
156   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
157                                       unsigned Kind) override;
158 
159   static bool classifySymbolRef(const MCExpr *Expr,
160                                 AArch64MCExpr::VariantKind &ELFRefKind,
161                                 MCSymbolRefExpr::VariantKind &DarwinRefKind,
162                                 int64_t &Addend);
163 };
164 
165 /// AArch64Operand - Instances of this class represent a parsed AArch64 machine
166 /// instruction.
167 class AArch64Operand : public MCParsedAsmOperand {
168 private:
169   enum KindTy {
170     k_Immediate,
171     k_ShiftedImm,
172     k_CondCode,
173     k_Register,
174     k_VectorList,
175     k_VectorIndex,
176     k_Token,
177     k_SysReg,
178     k_SysCR,
179     k_Prefetch,
180     k_ShiftExtend,
181     k_FPImm,
182     k_Barrier,
183     k_PSBHint,
184   } Kind;
185 
186   SMLoc StartLoc, EndLoc;
187 
188   struct TokOp {
189     const char *Data;
190     unsigned Length;
191     bool IsSuffix; // Is the operand actually a suffix on the mnemonic.
192   };
193 
194   struct RegOp {
195     unsigned RegNum;
196     bool isVector;
197   };
198 
199   struct VectorListOp {
200     unsigned RegNum;
201     unsigned Count;
202     unsigned NumElements;
203     unsigned ElementKind;
204   };
205 
206   struct VectorIndexOp {
207     unsigned Val;
208   };
209 
210   struct ImmOp {
211     const MCExpr *Val;
212   };
213 
214   struct ShiftedImmOp {
215     const MCExpr *Val;
216     unsigned ShiftAmount;
217   };
218 
219   struct CondCodeOp {
220     AArch64CC::CondCode Code;
221   };
222 
223   struct FPImmOp {
224     unsigned Val; // Encoded 8-bit representation.
225   };
226 
227   struct BarrierOp {
228     const char *Data;
229     unsigned Length;
230     unsigned Val; // Not the enum since not all values have names.
231   };
232 
233   struct SysRegOp {
234     const char *Data;
235     unsigned Length;
236     uint32_t MRSReg;
237     uint32_t MSRReg;
238     uint32_t PStateField;
239   };
240 
241   struct SysCRImmOp {
242     unsigned Val;
243   };
244 
245   struct PrefetchOp {
246     const char *Data;
247     unsigned Length;
248     unsigned Val;
249   };
250 
251   struct PSBHintOp {
252     const char *Data;
253     unsigned Length;
254     unsigned Val;
255   };
256 
257   struct ShiftExtendOp {
258     AArch64_AM::ShiftExtendType Type;
259     unsigned Amount;
260     bool HasExplicitAmount;
261   };
262 
263   struct ExtendOp {
264     unsigned Val;
265   };
266 
267   union {
268     struct TokOp Tok;
269     struct RegOp Reg;
270     struct VectorListOp VectorList;
271     struct VectorIndexOp VectorIndex;
272     struct ImmOp Imm;
273     struct ShiftedImmOp ShiftedImm;
274     struct CondCodeOp CondCode;
275     struct FPImmOp FPImm;
276     struct BarrierOp Barrier;
277     struct SysRegOp SysReg;
278     struct SysCRImmOp SysCRImm;
279     struct PrefetchOp Prefetch;
280     struct PSBHintOp PSBHint;
281     struct ShiftExtendOp ShiftExtend;
282   };
283 
284   // Keep the MCContext around as the MCExprs may need manipulated during
285   // the add<>Operands() calls.
286   MCContext &Ctx;
287 
288 public:
289   AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {}
290 
291   AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
292     Kind = o.Kind;
293     StartLoc = o.StartLoc;
294     EndLoc = o.EndLoc;
295     switch (Kind) {
296     case k_Token:
297       Tok = o.Tok;
298       break;
299     case k_Immediate:
300       Imm = o.Imm;
301       break;
302     case k_ShiftedImm:
303       ShiftedImm = o.ShiftedImm;
304       break;
305     case k_CondCode:
306       CondCode = o.CondCode;
307       break;
308     case k_FPImm:
309       FPImm = o.FPImm;
310       break;
311     case k_Barrier:
312       Barrier = o.Barrier;
313       break;
314     case k_Register:
315       Reg = o.Reg;
316       break;
317     case k_VectorList:
318       VectorList = o.VectorList;
319       break;
320     case k_VectorIndex:
321       VectorIndex = o.VectorIndex;
322       break;
323     case k_SysReg:
324       SysReg = o.SysReg;
325       break;
326     case k_SysCR:
327       SysCRImm = o.SysCRImm;
328       break;
329     case k_Prefetch:
330       Prefetch = o.Prefetch;
331       break;
332     case k_PSBHint:
333       PSBHint = o.PSBHint;
334       break;
335     case k_ShiftExtend:
336       ShiftExtend = o.ShiftExtend;
337       break;
338     }
339   }
340 
341   /// getStartLoc - Get the location of the first token of this operand.
342   SMLoc getStartLoc() const override { return StartLoc; }
343   /// getEndLoc - Get the location of the last token of this operand.
344   SMLoc getEndLoc() const override { return EndLoc; }
345 
346   StringRef getToken() const {
347     assert(Kind == k_Token && "Invalid access!");
348     return StringRef(Tok.Data, Tok.Length);
349   }
350 
351   bool isTokenSuffix() const {
352     assert(Kind == k_Token && "Invalid access!");
353     return Tok.IsSuffix;
354   }
355 
356   const MCExpr *getImm() const {
357     assert(Kind == k_Immediate && "Invalid access!");
358     return Imm.Val;
359   }
360 
361   const MCExpr *getShiftedImmVal() const {
362     assert(Kind == k_ShiftedImm && "Invalid access!");
363     return ShiftedImm.Val;
364   }
365 
366   unsigned getShiftedImmShift() const {
367     assert(Kind == k_ShiftedImm && "Invalid access!");
368     return ShiftedImm.ShiftAmount;
369   }
370 
371   AArch64CC::CondCode getCondCode() const {
372     assert(Kind == k_CondCode && "Invalid access!");
373     return CondCode.Code;
374   }
375 
376   unsigned getFPImm() const {
377     assert(Kind == k_FPImm && "Invalid access!");
378     return FPImm.Val;
379   }
380 
381   unsigned getBarrier() const {
382     assert(Kind == k_Barrier && "Invalid access!");
383     return Barrier.Val;
384   }
385 
386   StringRef getBarrierName() const {
387     assert(Kind == k_Barrier && "Invalid access!");
388     return StringRef(Barrier.Data, Barrier.Length);
389   }
390 
391   unsigned getReg() const override {
392     assert(Kind == k_Register && "Invalid access!");
393     return Reg.RegNum;
394   }
395 
396   unsigned getVectorListStart() const {
397     assert(Kind == k_VectorList && "Invalid access!");
398     return VectorList.RegNum;
399   }
400 
401   unsigned getVectorListCount() const {
402     assert(Kind == k_VectorList && "Invalid access!");
403     return VectorList.Count;
404   }
405 
406   unsigned getVectorIndex() const {
407     assert(Kind == k_VectorIndex && "Invalid access!");
408     return VectorIndex.Val;
409   }
410 
411   StringRef getSysReg() const {
412     assert(Kind == k_SysReg && "Invalid access!");
413     return StringRef(SysReg.Data, SysReg.Length);
414   }
415 
416   unsigned getSysCR() const {
417     assert(Kind == k_SysCR && "Invalid access!");
418     return SysCRImm.Val;
419   }
420 
421   unsigned getPrefetch() const {
422     assert(Kind == k_Prefetch && "Invalid access!");
423     return Prefetch.Val;
424   }
425 
426   unsigned getPSBHint() const {
427     assert(Kind == k_PSBHint && "Invalid access!");
428     return PSBHint.Val;
429   }
430 
431   StringRef getPSBHintName() const {
432     assert(Kind == k_PSBHint && "Invalid access!");
433     return StringRef(PSBHint.Data, PSBHint.Length);
434   }
435 
436   StringRef getPrefetchName() const {
437     assert(Kind == k_Prefetch && "Invalid access!");
438     return StringRef(Prefetch.Data, Prefetch.Length);
439   }
440 
441   AArch64_AM::ShiftExtendType getShiftExtendType() const {
442     assert(Kind == k_ShiftExtend && "Invalid access!");
443     return ShiftExtend.Type;
444   }
445 
446   unsigned getShiftExtendAmount() const {
447     assert(Kind == k_ShiftExtend && "Invalid access!");
448     return ShiftExtend.Amount;
449   }
450 
451   bool hasShiftExtendAmount() const {
452     assert(Kind == k_ShiftExtend && "Invalid access!");
453     return ShiftExtend.HasExplicitAmount;
454   }
455 
456   bool isImm() const override { return Kind == k_Immediate; }
457   bool isMem() const override { return false; }
458   bool isSImm9() const {
459     if (!isImm())
460       return false;
461     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
462     if (!MCE)
463       return false;
464     int64_t Val = MCE->getValue();
465     return (Val >= -256 && Val < 256);
466   }
467   bool isSImm7s4() const {
468     if (!isImm())
469       return false;
470     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
471     if (!MCE)
472       return false;
473     int64_t Val = MCE->getValue();
474     return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
475   }
476   bool isSImm7s8() const {
477     if (!isImm())
478       return false;
479     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
480     if (!MCE)
481       return false;
482     int64_t Val = MCE->getValue();
483     return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
484   }
485   bool isSImm7s16() const {
486     if (!isImm())
487       return false;
488     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
489     if (!MCE)
490       return false;
491     int64_t Val = MCE->getValue();
492     return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
493   }
494 
495   bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
496     AArch64MCExpr::VariantKind ELFRefKind;
497     MCSymbolRefExpr::VariantKind DarwinRefKind;
498     int64_t Addend;
499     if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
500                                            Addend)) {
501       // If we don't understand the expression, assume the best and
502       // let the fixup and relocation code deal with it.
503       return true;
504     }
505 
506     if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
507         ELFRefKind == AArch64MCExpr::VK_LO12 ||
508         ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
509         ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
510         ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
511         ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
512         ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
513         ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
514         ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) {
515       // Note that we don't range-check the addend. It's adjusted modulo page
516       // size when converted, so there is no "out of range" condition when using
517       // @pageoff.
518       return Addend >= 0 && (Addend % Scale) == 0;
519     } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
520                DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
521       // @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
522       return Addend == 0;
523     }
524 
525     return false;
526   }
527 
528   template <int Scale> bool isUImm12Offset() const {
529     if (!isImm())
530       return false;
531 
532     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
533     if (!MCE)
534       return isSymbolicUImm12Offset(getImm(), Scale);
535 
536     int64_t Val = MCE->getValue();
537     return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
538   }
539 
540   template <int N, int M>
541   bool isImmInRange() const {
542     if (!isImm())
543       return false;
544     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
545     if (!MCE)
546       return false;
547     int64_t Val = MCE->getValue();
548     return (Val >= N && Val <= M);
549   }
550 
551   bool isLogicalImm32() const {
552     if (!isImm())
553       return false;
554     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
555     if (!MCE)
556       return false;
557     int64_t Val = MCE->getValue();
558     if (Val >> 32 != 0 && Val >> 32 != ~0LL)
559       return false;
560     Val &= 0xFFFFFFFF;
561     return AArch64_AM::isLogicalImmediate(Val, 32);
562   }
563 
564   bool isLogicalImm64() const {
565     if (!isImm())
566       return false;
567     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
568     if (!MCE)
569       return false;
570     return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64);
571   }
572 
573   bool isLogicalImm32Not() const {
574     if (!isImm())
575       return false;
576     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
577     if (!MCE)
578       return false;
579     int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
580     return AArch64_AM::isLogicalImmediate(Val, 32);
581   }
582 
583   bool isLogicalImm64Not() const {
584     if (!isImm())
585       return false;
586     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
587     if (!MCE)
588       return false;
589     return AArch64_AM::isLogicalImmediate(~MCE->getValue(), 64);
590   }
591 
592   bool isShiftedImm() const { return Kind == k_ShiftedImm; }
593 
594   bool isAddSubImm() const {
595     if (!isShiftedImm() && !isImm())
596       return false;
597 
598     const MCExpr *Expr;
599 
600     // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
601     if (isShiftedImm()) {
602       unsigned Shift = ShiftedImm.ShiftAmount;
603       Expr = ShiftedImm.Val;
604       if (Shift != 0 && Shift != 12)
605         return false;
606     } else {
607       Expr = getImm();
608     }
609 
610     AArch64MCExpr::VariantKind ELFRefKind;
611     MCSymbolRefExpr::VariantKind DarwinRefKind;
612     int64_t Addend;
613     if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
614                                           DarwinRefKind, Addend)) {
615       return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
616           || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
617           || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
618           || ELFRefKind == AArch64MCExpr::VK_LO12
619           || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
620           || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
621           || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
622           || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
623           || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
624           || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
625           || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12;
626     }
627 
628     // If it's a constant, it should be a real immediate in range:
629     if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
630       return CE->getValue() >= 0 && CE->getValue() <= 0xfff;
631 
632     // If it's an expression, we hope for the best and let the fixup/relocation
633     // code deal with it.
634     return true;
635   }
636 
637   bool isAddSubImmNeg() const {
638     if (!isShiftedImm() && !isImm())
639       return false;
640 
641     const MCExpr *Expr;
642 
643     // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
644     if (isShiftedImm()) {
645       unsigned Shift = ShiftedImm.ShiftAmount;
646       Expr = ShiftedImm.Val;
647       if (Shift != 0 && Shift != 12)
648         return false;
649     } else
650       Expr = getImm();
651 
652     // Otherwise it should be a real negative immediate in range:
653     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
654     return CE != nullptr && CE->getValue() < 0 && -CE->getValue() <= 0xfff;
655   }
656 
657   bool isCondCode() const { return Kind == k_CondCode; }
658 
659   bool isSIMDImmType10() const {
660     if (!isImm())
661       return false;
662     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
663     if (!MCE)
664       return false;
665     return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue());
666   }
667 
668   template<int N>
669   bool isBranchTarget() const {
670     if (!isImm())
671       return false;
672     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
673     if (!MCE)
674       return true;
675     int64_t Val = MCE->getValue();
676     if (Val & 0x3)
677       return false;
678     assert(N > 0 && "Branch target immediate cannot be 0 bits!");
679     return (Val >= -((1<<(N-1)) << 2) && Val <= (((1<<(N-1))-1) << 2));
680   }
681 
682   bool
683   isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const {
684     if (!isImm())
685       return false;
686 
687     AArch64MCExpr::VariantKind ELFRefKind;
688     MCSymbolRefExpr::VariantKind DarwinRefKind;
689     int64_t Addend;
690     if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
691                                              DarwinRefKind, Addend)) {
692       return false;
693     }
694     if (DarwinRefKind != MCSymbolRefExpr::VK_None)
695       return false;
696 
697     for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
698       if (ELFRefKind == AllowedModifiers[i])
699         return Addend == 0;
700     }
701 
702     return false;
703   }
704 
705   bool isMovZSymbolG3() const {
706     return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
707   }
708 
709   bool isMovZSymbolG2() const {
710     return isMovWSymbol({AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S,
711                          AArch64MCExpr::VK_TPREL_G2,
712                          AArch64MCExpr::VK_DTPREL_G2});
713   }
714 
715   bool isMovZSymbolG1() const {
716     return isMovWSymbol({
717         AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S,
718         AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1,
719         AArch64MCExpr::VK_DTPREL_G1,
720     });
721   }
722 
723   bool isMovZSymbolG0() const {
724     return isMovWSymbol({AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S,
725                          AArch64MCExpr::VK_TPREL_G0,
726                          AArch64MCExpr::VK_DTPREL_G0});
727   }
728 
729   bool isMovKSymbolG3() const {
730     return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
731   }
732 
733   bool isMovKSymbolG2() const {
734     return isMovWSymbol(AArch64MCExpr::VK_ABS_G2_NC);
735   }
736 
737   bool isMovKSymbolG1() const {
738     return isMovWSymbol({AArch64MCExpr::VK_ABS_G1_NC,
739                          AArch64MCExpr::VK_TPREL_G1_NC,
740                          AArch64MCExpr::VK_DTPREL_G1_NC});
741   }
742 
743   bool isMovKSymbolG0() const {
744     return isMovWSymbol(
745         {AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC,
746          AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC});
747   }
748 
749   template<int RegWidth, int Shift>
750   bool isMOVZMovAlias() const {
751     if (!isImm()) return false;
752 
753     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
754     if (!CE) return false;
755     uint64_t Value = CE->getValue();
756 
757     return AArch64_AM::isMOVZMovAlias(Value, Shift, RegWidth);
758   }
759 
760   template<int RegWidth, int Shift>
761   bool isMOVNMovAlias() const {
762     if (!isImm()) return false;
763 
764     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
765     if (!CE) return false;
766     uint64_t Value = CE->getValue();
767 
768     return AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth);
769   }
770 
771   bool isFPImm() const { return Kind == k_FPImm; }
772   bool isBarrier() const { return Kind == k_Barrier; }
773   bool isSysReg() const { return Kind == k_SysReg; }
774 
775   bool isMRSSystemRegister() const {
776     if (!isSysReg()) return false;
777 
778     return SysReg.MRSReg != -1U;
779   }
780 
781   bool isMSRSystemRegister() const {
782     if (!isSysReg()) return false;
783     return SysReg.MSRReg != -1U;
784   }
785 
786   bool isSystemPStateFieldWithImm0_1() const {
787     if (!isSysReg()) return false;
788     return (SysReg.PStateField == AArch64PState::PAN ||
789             SysReg.PStateField == AArch64PState::UAO);
790   }
791 
792   bool isSystemPStateFieldWithImm0_15() const {
793     if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false;
794     return SysReg.PStateField != -1U;
795   }
796 
797   bool isReg() const override { return Kind == k_Register && !Reg.isVector; }
798   bool isVectorReg() const { return Kind == k_Register && Reg.isVector; }
799 
800   bool isVectorRegLo() const {
801     return Kind == k_Register && Reg.isVector &&
802            AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
803                Reg.RegNum);
804   }
805 
806   bool isGPR32as64() const {
807     return Kind == k_Register && !Reg.isVector &&
808       AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
809   }
810 
811   bool isWSeqPair() const {
812     return Kind == k_Register && !Reg.isVector &&
813            AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
814                Reg.RegNum);
815   }
816 
817   bool isXSeqPair() const {
818     return Kind == k_Register && !Reg.isVector &&
819            AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
820                Reg.RegNum);
821   }
822 
823   bool isGPR64sp0() const {
824     return Kind == k_Register && !Reg.isVector &&
825       AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum);
826   }
827 
828   /// Is this a vector list with the type implicit (presumably attached to the
829   /// instruction itself)?
830   template <unsigned NumRegs> bool isImplicitlyTypedVectorList() const {
831     return Kind == k_VectorList && VectorList.Count == NumRegs &&
832            !VectorList.ElementKind;
833   }
834 
835   template <unsigned NumRegs, unsigned NumElements, char ElementKind>
836   bool isTypedVectorList() const {
837     if (Kind != k_VectorList)
838       return false;
839     if (VectorList.Count != NumRegs)
840       return false;
841     if (VectorList.ElementKind != ElementKind)
842       return false;
843     return VectorList.NumElements == NumElements;
844   }
845 
846   bool isVectorIndex1() const {
847     return Kind == k_VectorIndex && VectorIndex.Val == 1;
848   }
849 
850   bool isVectorIndexB() const {
851     return Kind == k_VectorIndex && VectorIndex.Val < 16;
852   }
853 
854   bool isVectorIndexH() const {
855     return Kind == k_VectorIndex && VectorIndex.Val < 8;
856   }
857 
858   bool isVectorIndexS() const {
859     return Kind == k_VectorIndex && VectorIndex.Val < 4;
860   }
861 
862   bool isVectorIndexD() const {
863     return Kind == k_VectorIndex && VectorIndex.Val < 2;
864   }
865 
866   bool isToken() const override { return Kind == k_Token; }
867 
868   bool isTokenEqual(StringRef Str) const {
869     return Kind == k_Token && getToken() == Str;
870   }
871   bool isSysCR() const { return Kind == k_SysCR; }
872   bool isPrefetch() const { return Kind == k_Prefetch; }
873   bool isPSBHint() const { return Kind == k_PSBHint; }
874   bool isShiftExtend() const { return Kind == k_ShiftExtend; }
875   bool isShifter() const {
876     if (!isShiftExtend())
877       return false;
878 
879     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
880     return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
881             ST == AArch64_AM::ASR || ST == AArch64_AM::ROR ||
882             ST == AArch64_AM::MSL);
883   }
884   bool isExtend() const {
885     if (!isShiftExtend())
886       return false;
887 
888     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
889     return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
890             ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
891             ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW ||
892             ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
893             ET == AArch64_AM::LSL) &&
894            getShiftExtendAmount() <= 4;
895   }
896 
897   bool isExtend64() const {
898     if (!isExtend())
899       return false;
900     // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class).
901     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
902     return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX;
903   }
904 
905   bool isExtendLSL64() const {
906     if (!isExtend())
907       return false;
908     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
909     return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
910             ET == AArch64_AM::LSL) &&
911            getShiftExtendAmount() <= 4;
912   }
913 
914   template<int Width> bool isMemXExtend() const {
915     if (!isExtend())
916       return false;
917     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
918     return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) &&
919            (getShiftExtendAmount() == Log2_32(Width / 8) ||
920             getShiftExtendAmount() == 0);
921   }
922 
923   template<int Width> bool isMemWExtend() const {
924     if (!isExtend())
925       return false;
926     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
927     return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) &&
928            (getShiftExtendAmount() == Log2_32(Width / 8) ||
929             getShiftExtendAmount() == 0);
930   }
931 
932   template <unsigned width>
933   bool isArithmeticShifter() const {
934     if (!isShifter())
935       return false;
936 
937     // An arithmetic shifter is LSL, LSR, or ASR.
938     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
939     return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
940             ST == AArch64_AM::ASR) && getShiftExtendAmount() < width;
941   }
942 
943   template <unsigned width>
944   bool isLogicalShifter() const {
945     if (!isShifter())
946       return false;
947 
948     // A logical shifter is LSL, LSR, ASR or ROR.
949     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
950     return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
951             ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) &&
952            getShiftExtendAmount() < width;
953   }
954 
955   bool isMovImm32Shifter() const {
956     if (!isShifter())
957       return false;
958 
959     // A MOVi shifter is LSL of 0, 16, 32, or 48.
960     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
961     if (ST != AArch64_AM::LSL)
962       return false;
963     uint64_t Val = getShiftExtendAmount();
964     return (Val == 0 || Val == 16);
965   }
966 
967   bool isMovImm64Shifter() const {
968     if (!isShifter())
969       return false;
970 
971     // A MOVi shifter is LSL of 0 or 16.
972     AArch64_AM::ShiftExtendType ST = getShiftExtendType();
973     if (ST != AArch64_AM::LSL)
974       return false;
975     uint64_t Val = getShiftExtendAmount();
976     return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
977   }
978 
979   bool isLogicalVecShifter() const {
980     if (!isShifter())
981       return false;
982 
983     // A logical vector shifter is a left shift by 0, 8, 16, or 24.
984     unsigned Shift = getShiftExtendAmount();
985     return getShiftExtendType() == AArch64_AM::LSL &&
986            (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
987   }
988 
989   bool isLogicalVecHalfWordShifter() const {
990     if (!isLogicalVecShifter())
991       return false;
992 
993     // A logical vector shifter is a left shift by 0 or 8.
994     unsigned Shift = getShiftExtendAmount();
995     return getShiftExtendType() == AArch64_AM::LSL &&
996            (Shift == 0 || Shift == 8);
997   }
998 
999   bool isMoveVecShifter() const {
1000     if (!isShiftExtend())
1001       return false;
1002 
1003     // A logical vector shifter is a left shift by 8 or 16.
1004     unsigned Shift = getShiftExtendAmount();
1005     return getShiftExtendType() == AArch64_AM::MSL &&
1006            (Shift == 8 || Shift == 16);
1007   }
1008 
1009   // Fallback unscaled operands are for aliases of LDR/STR that fall back
1010   // to LDUR/STUR when the offset is not legal for the former but is for
1011   // the latter. As such, in addition to checking for being a legal unscaled
1012   // address, also check that it is not a legal scaled address. This avoids
1013   // ambiguity in the matcher.
1014   template<int Width>
1015   bool isSImm9OffsetFB() const {
1016     return isSImm9() && !isUImm12Offset<Width / 8>();
1017   }
1018 
1019   bool isAdrpLabel() const {
1020     // Validation was handled during parsing, so we just sanity check that
1021     // something didn't go haywire.
1022     if (!isImm())
1023         return false;
1024 
1025     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1026       int64_t Val = CE->getValue();
1027       int64_t Min = - (4096 * (1LL << (21 - 1)));
1028       int64_t Max = 4096 * ((1LL << (21 - 1)) - 1);
1029       return (Val % 4096) == 0 && Val >= Min && Val <= Max;
1030     }
1031 
1032     return true;
1033   }
1034 
1035   bool isAdrLabel() const {
1036     // Validation was handled during parsing, so we just sanity check that
1037     // something didn't go haywire.
1038     if (!isImm())
1039         return false;
1040 
1041     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1042       int64_t Val = CE->getValue();
1043       int64_t Min = - (1LL << (21 - 1));
1044       int64_t Max = ((1LL << (21 - 1)) - 1);
1045       return Val >= Min && Val <= Max;
1046     }
1047 
1048     return true;
1049   }
1050 
1051   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1052     // Add as immediates when possible.  Null MCExpr = 0.
1053     if (!Expr)
1054       Inst.addOperand(MCOperand::createImm(0));
1055     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1056       Inst.addOperand(MCOperand::createImm(CE->getValue()));
1057     else
1058       Inst.addOperand(MCOperand::createExpr(Expr));
1059   }
1060 
1061   void addRegOperands(MCInst &Inst, unsigned N) const {
1062     assert(N == 1 && "Invalid number of operands!");
1063     Inst.addOperand(MCOperand::createReg(getReg()));
1064   }
1065 
1066   void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
1067     assert(N == 1 && "Invalid number of operands!");
1068     assert(
1069         AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg()));
1070 
1071     const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1072     uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister(
1073         RI->getEncodingValue(getReg()));
1074 
1075     Inst.addOperand(MCOperand::createReg(Reg));
1076   }
1077 
1078   void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
1079     assert(N == 1 && "Invalid number of operands!");
1080     assert(
1081         AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1082     Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0));
1083   }
1084 
1085   void addVectorReg128Operands(MCInst &Inst, unsigned N) const {
1086     assert(N == 1 && "Invalid number of operands!");
1087     assert(
1088         AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1089     Inst.addOperand(MCOperand::createReg(getReg()));
1090   }
1091 
1092   void addVectorRegLoOperands(MCInst &Inst, unsigned N) const {
1093     assert(N == 1 && "Invalid number of operands!");
1094     Inst.addOperand(MCOperand::createReg(getReg()));
1095   }
1096 
1097   template <unsigned NumRegs>
1098   void addVectorList64Operands(MCInst &Inst, unsigned N) const {
1099     assert(N == 1 && "Invalid number of operands!");
1100     static const unsigned FirstRegs[] = { AArch64::D0,
1101                                           AArch64::D0_D1,
1102                                           AArch64::D0_D1_D2,
1103                                           AArch64::D0_D1_D2_D3 };
1104     unsigned FirstReg = FirstRegs[NumRegs - 1];
1105 
1106     Inst.addOperand(
1107         MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
1108   }
1109 
1110   template <unsigned NumRegs>
1111   void addVectorList128Operands(MCInst &Inst, unsigned N) const {
1112     assert(N == 1 && "Invalid number of operands!");
1113     static const unsigned FirstRegs[] = { AArch64::Q0,
1114                                           AArch64::Q0_Q1,
1115                                           AArch64::Q0_Q1_Q2,
1116                                           AArch64::Q0_Q1_Q2_Q3 };
1117     unsigned FirstReg = FirstRegs[NumRegs - 1];
1118 
1119     Inst.addOperand(
1120         MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
1121   }
1122 
1123   void addVectorIndex1Operands(MCInst &Inst, unsigned N) const {
1124     assert(N == 1 && "Invalid number of operands!");
1125     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1126   }
1127 
1128   void addVectorIndexBOperands(MCInst &Inst, unsigned N) const {
1129     assert(N == 1 && "Invalid number of operands!");
1130     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1131   }
1132 
1133   void addVectorIndexHOperands(MCInst &Inst, unsigned N) const {
1134     assert(N == 1 && "Invalid number of operands!");
1135     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1136   }
1137 
1138   void addVectorIndexSOperands(MCInst &Inst, unsigned N) const {
1139     assert(N == 1 && "Invalid number of operands!");
1140     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1141   }
1142 
1143   void addVectorIndexDOperands(MCInst &Inst, unsigned N) const {
1144     assert(N == 1 && "Invalid number of operands!");
1145     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1146   }
1147 
1148   void addImmOperands(MCInst &Inst, unsigned N) const {
1149     assert(N == 1 && "Invalid number of operands!");
1150     // If this is a pageoff symrefexpr with an addend, adjust the addend
1151     // to be only the page-offset portion. Otherwise, just add the expr
1152     // as-is.
1153     addExpr(Inst, getImm());
1154   }
1155 
1156   void addAddSubImmOperands(MCInst &Inst, unsigned N) const {
1157     assert(N == 2 && "Invalid number of operands!");
1158     if (isShiftedImm()) {
1159       addExpr(Inst, getShiftedImmVal());
1160       Inst.addOperand(MCOperand::createImm(getShiftedImmShift()));
1161     } else {
1162       addExpr(Inst, getImm());
1163       Inst.addOperand(MCOperand::createImm(0));
1164     }
1165   }
1166 
1167   void addAddSubImmNegOperands(MCInst &Inst, unsigned N) const {
1168     assert(N == 2 && "Invalid number of operands!");
1169 
1170     const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm();
1171     const MCConstantExpr *CE = cast<MCConstantExpr>(MCE);
1172     int64_t Val = -CE->getValue();
1173     unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0;
1174 
1175     Inst.addOperand(MCOperand::createImm(Val));
1176     Inst.addOperand(MCOperand::createImm(ShiftAmt));
1177   }
1178 
1179   void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1180     assert(N == 1 && "Invalid number of operands!");
1181     Inst.addOperand(MCOperand::createImm(getCondCode()));
1182   }
1183 
1184   void addAdrpLabelOperands(MCInst &Inst, unsigned N) const {
1185     assert(N == 1 && "Invalid number of operands!");
1186     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1187     if (!MCE)
1188       addExpr(Inst, getImm());
1189     else
1190       Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12));
1191   }
1192 
1193   void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1194     addImmOperands(Inst, N);
1195   }
1196 
1197   template<int Scale>
1198   void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1199     assert(N == 1 && "Invalid number of operands!");
1200     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1201 
1202     if (!MCE) {
1203       Inst.addOperand(MCOperand::createExpr(getImm()));
1204       return;
1205     }
1206     Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
1207   }
1208 
1209   void addSImm9Operands(MCInst &Inst, unsigned N) const {
1210     assert(N == 1 && "Invalid number of operands!");
1211     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1212     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1213   }
1214 
1215   void addSImm7s4Operands(MCInst &Inst, unsigned N) const {
1216     assert(N == 1 && "Invalid number of operands!");
1217     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1218     Inst.addOperand(MCOperand::createImm(MCE->getValue() / 4));
1219   }
1220 
1221   void addSImm7s8Operands(MCInst &Inst, unsigned N) const {
1222     assert(N == 1 && "Invalid number of operands!");
1223     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1224     Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8));
1225   }
1226 
1227   void addSImm7s16Operands(MCInst &Inst, unsigned N) const {
1228     assert(N == 1 && "Invalid number of operands!");
1229     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1230     Inst.addOperand(MCOperand::createImm(MCE->getValue() / 16));
1231   }
1232 
1233   void addImm0_1Operands(MCInst &Inst, unsigned N) const {
1234     assert(N == 1 && "Invalid number of operands!");
1235     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1236     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1237   }
1238 
1239   void addImm0_7Operands(MCInst &Inst, unsigned N) const {
1240     assert(N == 1 && "Invalid number of operands!");
1241     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1242     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1243   }
1244 
1245   void addImm1_8Operands(MCInst &Inst, unsigned N) const {
1246     assert(N == 1 && "Invalid number of operands!");
1247     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1248     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1249   }
1250 
1251   void addImm0_15Operands(MCInst &Inst, unsigned N) const {
1252     assert(N == 1 && "Invalid number of operands!");
1253     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1254     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1255   }
1256 
1257   void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1258     assert(N == 1 && "Invalid number of operands!");
1259     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1260     assert(MCE && "Invalid constant immediate operand!");
1261     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1262   }
1263 
1264   void addImm0_31Operands(MCInst &Inst, unsigned N) const {
1265     assert(N == 1 && "Invalid number of operands!");
1266     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1267     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1268   }
1269 
1270   void addImm1_31Operands(MCInst &Inst, unsigned N) const {
1271     assert(N == 1 && "Invalid number of operands!");
1272     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1273     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1274   }
1275 
1276   void addImm1_32Operands(MCInst &Inst, unsigned N) const {
1277     assert(N == 1 && "Invalid number of operands!");
1278     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1279     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1280   }
1281 
1282   void addImm0_63Operands(MCInst &Inst, unsigned N) const {
1283     assert(N == 1 && "Invalid number of operands!");
1284     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1285     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1286   }
1287 
1288   void addImm1_63Operands(MCInst &Inst, unsigned N) const {
1289     assert(N == 1 && "Invalid number of operands!");
1290     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1291     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1292   }
1293 
1294   void addImm1_64Operands(MCInst &Inst, unsigned N) const {
1295     assert(N == 1 && "Invalid number of operands!");
1296     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1297     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1298   }
1299 
1300   void addImm0_127Operands(MCInst &Inst, unsigned N) const {
1301     assert(N == 1 && "Invalid number of operands!");
1302     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1303     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1304   }
1305 
1306   void addImm0_255Operands(MCInst &Inst, unsigned N) const {
1307     assert(N == 1 && "Invalid number of operands!");
1308     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1309     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1310   }
1311 
1312   void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1313     assert(N == 1 && "Invalid number of operands!");
1314     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1315     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1316   }
1317 
1318   void addImm32_63Operands(MCInst &Inst, unsigned N) const {
1319     assert(N == 1 && "Invalid number of operands!");
1320     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1321     Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1322   }
1323 
1324   void addLogicalImm32Operands(MCInst &Inst, unsigned N) const {
1325     assert(N == 1 && "Invalid number of operands!");
1326     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1327     uint64_t encoding =
1328         AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32);
1329     Inst.addOperand(MCOperand::createImm(encoding));
1330   }
1331 
1332   void addLogicalImm64Operands(MCInst &Inst, unsigned N) const {
1333     assert(N == 1 && "Invalid number of operands!");
1334     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1335     uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
1336     Inst.addOperand(MCOperand::createImm(encoding));
1337   }
1338 
1339   void addLogicalImm32NotOperands(MCInst &Inst, unsigned N) const {
1340     assert(N == 1 && "Invalid number of operands!");
1341     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1342     int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
1343     uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, 32);
1344     Inst.addOperand(MCOperand::createImm(encoding));
1345   }
1346 
1347   void addLogicalImm64NotOperands(MCInst &Inst, unsigned N) const {
1348     assert(N == 1 && "Invalid number of operands!");
1349     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1350     uint64_t encoding =
1351         AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64);
1352     Inst.addOperand(MCOperand::createImm(encoding));
1353   }
1354 
1355   void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const {
1356     assert(N == 1 && "Invalid number of operands!");
1357     const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1358     uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
1359     Inst.addOperand(MCOperand::createImm(encoding));
1360   }
1361 
1362   void addBranchTarget26Operands(MCInst &Inst, unsigned N) const {
1363     // Branch operands don't encode the low bits, so shift them off
1364     // here. If it's a label, however, just put it on directly as there's
1365     // not enough information now to do anything.
1366     assert(N == 1 && "Invalid number of operands!");
1367     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1368     if (!MCE) {
1369       addExpr(Inst, getImm());
1370       return;
1371     }
1372     assert(MCE && "Invalid constant immediate operand!");
1373     Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1374   }
1375 
1376   void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const {
1377     // Branch operands don't encode the low bits, so shift them off
1378     // here. If it's a label, however, just put it on directly as there's
1379     // not enough information now to do anything.
1380     assert(N == 1 && "Invalid number of operands!");
1381     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1382     if (!MCE) {
1383       addExpr(Inst, getImm());
1384       return;
1385     }
1386     assert(MCE && "Invalid constant immediate operand!");
1387     Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1388   }
1389 
1390   void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
1391     // Branch operands don't encode the low bits, so shift them off
1392     // here. If it's a label, however, just put it on directly as there's
1393     // not enough information now to do anything.
1394     assert(N == 1 && "Invalid number of operands!");
1395     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1396     if (!MCE) {
1397       addExpr(Inst, getImm());
1398       return;
1399     }
1400     assert(MCE && "Invalid constant immediate operand!");
1401     Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1402   }
1403 
1404   void addFPImmOperands(MCInst &Inst, unsigned N) const {
1405     assert(N == 1 && "Invalid number of operands!");
1406     Inst.addOperand(MCOperand::createImm(getFPImm()));
1407   }
1408 
1409   void addBarrierOperands(MCInst &Inst, unsigned N) const {
1410     assert(N == 1 && "Invalid number of operands!");
1411     Inst.addOperand(MCOperand::createImm(getBarrier()));
1412   }
1413 
1414   void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1415     assert(N == 1 && "Invalid number of operands!");
1416 
1417     Inst.addOperand(MCOperand::createImm(SysReg.MRSReg));
1418   }
1419 
1420   void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1421     assert(N == 1 && "Invalid number of operands!");
1422 
1423     Inst.addOperand(MCOperand::createImm(SysReg.MSRReg));
1424   }
1425 
1426   void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst, unsigned N) const {
1427     assert(N == 1 && "Invalid number of operands!");
1428 
1429     Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1430   }
1431 
1432   void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const {
1433     assert(N == 1 && "Invalid number of operands!");
1434 
1435     Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1436   }
1437 
1438   void addSysCROperands(MCInst &Inst, unsigned N) const {
1439     assert(N == 1 && "Invalid number of operands!");
1440     Inst.addOperand(MCOperand::createImm(getSysCR()));
1441   }
1442 
1443   void addPrefetchOperands(MCInst &Inst, unsigned N) const {
1444     assert(N == 1 && "Invalid number of operands!");
1445     Inst.addOperand(MCOperand::createImm(getPrefetch()));
1446   }
1447 
1448   void addPSBHintOperands(MCInst &Inst, unsigned N) const {
1449     assert(N == 1 && "Invalid number of operands!");
1450     Inst.addOperand(MCOperand::createImm(getPSBHint()));
1451   }
1452 
1453   void addShifterOperands(MCInst &Inst, unsigned N) const {
1454     assert(N == 1 && "Invalid number of operands!");
1455     unsigned Imm =
1456         AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
1457     Inst.addOperand(MCOperand::createImm(Imm));
1458   }
1459 
1460   void addExtendOperands(MCInst &Inst, unsigned N) const {
1461     assert(N == 1 && "Invalid number of operands!");
1462     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1463     if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW;
1464     unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1465     Inst.addOperand(MCOperand::createImm(Imm));
1466   }
1467 
1468   void addExtend64Operands(MCInst &Inst, unsigned N) const {
1469     assert(N == 1 && "Invalid number of operands!");
1470     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1471     if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX;
1472     unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1473     Inst.addOperand(MCOperand::createImm(Imm));
1474   }
1475 
1476   void addMemExtendOperands(MCInst &Inst, unsigned N) const {
1477     assert(N == 2 && "Invalid number of operands!");
1478     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1479     bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1480     Inst.addOperand(MCOperand::createImm(IsSigned));
1481     Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0));
1482   }
1483 
1484   // For 8-bit load/store instructions with a register offset, both the
1485   // "DoShift" and "NoShift" variants have a shift of 0. Because of this,
1486   // they're disambiguated by whether the shift was explicit or implicit rather
1487   // than its size.
1488   void addMemExtend8Operands(MCInst &Inst, unsigned N) const {
1489     assert(N == 2 && "Invalid number of operands!");
1490     AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1491     bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1492     Inst.addOperand(MCOperand::createImm(IsSigned));
1493     Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount()));
1494   }
1495 
1496   template<int Shift>
1497   void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const {
1498     assert(N == 1 && "Invalid number of operands!");
1499 
1500     const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1501     uint64_t Value = CE->getValue();
1502     Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff));
1503   }
1504 
1505   template<int Shift>
1506   void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const {
1507     assert(N == 1 && "Invalid number of operands!");
1508 
1509     const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1510     uint64_t Value = CE->getValue();
1511     Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff));
1512   }
1513 
1514   void print(raw_ostream &OS) const override;
1515 
1516   static std::unique_ptr<AArch64Operand>
1517   CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) {
1518     auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
1519     Op->Tok.Data = Str.data();
1520     Op->Tok.Length = Str.size();
1521     Op->Tok.IsSuffix = IsSuffix;
1522     Op->StartLoc = S;
1523     Op->EndLoc = S;
1524     return Op;
1525   }
1526 
1527   static std::unique_ptr<AArch64Operand>
1528   CreateReg(unsigned RegNum, bool isVector, SMLoc S, SMLoc E, MCContext &Ctx) {
1529     auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1530     Op->Reg.RegNum = RegNum;
1531     Op->Reg.isVector = isVector;
1532     Op->StartLoc = S;
1533     Op->EndLoc = E;
1534     return Op;
1535   }
1536 
1537   static std::unique_ptr<AArch64Operand>
1538   CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements,
1539                    char ElementKind, SMLoc S, SMLoc E, MCContext &Ctx) {
1540     auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
1541     Op->VectorList.RegNum = RegNum;
1542     Op->VectorList.Count = Count;
1543     Op->VectorList.NumElements = NumElements;
1544     Op->VectorList.ElementKind = ElementKind;
1545     Op->StartLoc = S;
1546     Op->EndLoc = E;
1547     return Op;
1548   }
1549 
1550   static std::unique_ptr<AArch64Operand>
1551   CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
1552     auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
1553     Op->VectorIndex.Val = Idx;
1554     Op->StartLoc = S;
1555     Op->EndLoc = E;
1556     return Op;
1557   }
1558 
1559   static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S,
1560                                                    SMLoc E, MCContext &Ctx) {
1561     auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
1562     Op->Imm.Val = Val;
1563     Op->StartLoc = S;
1564     Op->EndLoc = E;
1565     return Op;
1566   }
1567 
1568   static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val,
1569                                                           unsigned ShiftAmount,
1570                                                           SMLoc S, SMLoc E,
1571                                                           MCContext &Ctx) {
1572     auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
1573     Op->ShiftedImm .Val = Val;
1574     Op->ShiftedImm.ShiftAmount = ShiftAmount;
1575     Op->StartLoc = S;
1576     Op->EndLoc = E;
1577     return Op;
1578   }
1579 
1580   static std::unique_ptr<AArch64Operand>
1581   CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
1582     auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
1583     Op->CondCode.Code = Code;
1584     Op->StartLoc = S;
1585     Op->EndLoc = E;
1586     return Op;
1587   }
1588 
1589   static std::unique_ptr<AArch64Operand> CreateFPImm(unsigned Val, SMLoc S,
1590                                                      MCContext &Ctx) {
1591     auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
1592     Op->FPImm.Val = Val;
1593     Op->StartLoc = S;
1594     Op->EndLoc = S;
1595     return Op;
1596   }
1597 
1598   static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val,
1599                                                        StringRef Str,
1600                                                        SMLoc S,
1601                                                        MCContext &Ctx) {
1602     auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
1603     Op->Barrier.Val = Val;
1604     Op->Barrier.Data = Str.data();
1605     Op->Barrier.Length = Str.size();
1606     Op->StartLoc = S;
1607     Op->EndLoc = S;
1608     return Op;
1609   }
1610 
1611   static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
1612                                                       uint32_t MRSReg,
1613                                                       uint32_t MSRReg,
1614                                                       uint32_t PStateField,
1615                                                       MCContext &Ctx) {
1616     auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
1617     Op->SysReg.Data = Str.data();
1618     Op->SysReg.Length = Str.size();
1619     Op->SysReg.MRSReg = MRSReg;
1620     Op->SysReg.MSRReg = MSRReg;
1621     Op->SysReg.PStateField = PStateField;
1622     Op->StartLoc = S;
1623     Op->EndLoc = S;
1624     return Op;
1625   }
1626 
1627   static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
1628                                                      SMLoc E, MCContext &Ctx) {
1629     auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
1630     Op->SysCRImm.Val = Val;
1631     Op->StartLoc = S;
1632     Op->EndLoc = E;
1633     return Op;
1634   }
1635 
1636   static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val,
1637                                                         StringRef Str,
1638                                                         SMLoc S,
1639                                                         MCContext &Ctx) {
1640     auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
1641     Op->Prefetch.Val = Val;
1642     Op->Barrier.Data = Str.data();
1643     Op->Barrier.Length = Str.size();
1644     Op->StartLoc = S;
1645     Op->EndLoc = S;
1646     return Op;
1647   }
1648 
1649   static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val,
1650                                                        StringRef Str,
1651                                                        SMLoc S,
1652                                                        MCContext &Ctx) {
1653     auto Op = make_unique<AArch64Operand>(k_PSBHint, Ctx);
1654     Op->PSBHint.Val = Val;
1655     Op->PSBHint.Data = Str.data();
1656     Op->PSBHint.Length = Str.size();
1657     Op->StartLoc = S;
1658     Op->EndLoc = S;
1659     return Op;
1660   }
1661 
1662   static std::unique_ptr<AArch64Operand>
1663   CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
1664                     bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
1665     auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
1666     Op->ShiftExtend.Type = ShOp;
1667     Op->ShiftExtend.Amount = Val;
1668     Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1669     Op->StartLoc = S;
1670     Op->EndLoc = E;
1671     return Op;
1672   }
1673 };
1674 
1675 } // end anonymous namespace.
1676 
1677 void AArch64Operand::print(raw_ostream &OS) const {
1678   switch (Kind) {
1679   case k_FPImm:
1680     OS << "<fpimm " << getFPImm() << "("
1681        << AArch64_AM::getFPImmFloat(getFPImm()) << ") >";
1682     break;
1683   case k_Barrier: {
1684     StringRef Name = getBarrierName();
1685     if (!Name.empty())
1686       OS << "<barrier " << Name << ">";
1687     else
1688       OS << "<barrier invalid #" << getBarrier() << ">";
1689     break;
1690   }
1691   case k_Immediate:
1692     OS << *getImm();
1693     break;
1694   case k_ShiftedImm: {
1695     unsigned Shift = getShiftedImmShift();
1696     OS << "<shiftedimm ";
1697     OS << *getShiftedImmVal();
1698     OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
1699     break;
1700   }
1701   case k_CondCode:
1702     OS << "<condcode " << getCondCode() << ">";
1703     break;
1704   case k_Register:
1705     OS << "<register " << getReg() << ">";
1706     break;
1707   case k_VectorList: {
1708     OS << "<vectorlist ";
1709     unsigned Reg = getVectorListStart();
1710     for (unsigned i = 0, e = getVectorListCount(); i != e; ++i)
1711       OS << Reg + i << " ";
1712     OS << ">";
1713     break;
1714   }
1715   case k_VectorIndex:
1716     OS << "<vectorindex " << getVectorIndex() << ">";
1717     break;
1718   case k_SysReg:
1719     OS << "<sysreg: " << getSysReg() << '>';
1720     break;
1721   case k_Token:
1722     OS << "'" << getToken() << "'";
1723     break;
1724   case k_SysCR:
1725     OS << "c" << getSysCR();
1726     break;
1727   case k_Prefetch: {
1728     StringRef Name = getPrefetchName();
1729     if (!Name.empty())
1730       OS << "<prfop " << Name << ">";
1731     else
1732       OS << "<prfop invalid #" << getPrefetch() << ">";
1733     break;
1734   }
1735   case k_PSBHint:
1736     OS << getPSBHintName();
1737     break;
1738   case k_ShiftExtend:
1739     OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
1740        << getShiftExtendAmount();
1741     if (!hasShiftExtendAmount())
1742       OS << "<imp>";
1743     OS << '>';
1744     break;
1745   }
1746 }
1747 
1748 /// @name Auto-generated Match Functions
1749 /// {
1750 
1751 static unsigned MatchRegisterName(StringRef Name);
1752 
1753 /// }
1754 
1755 static unsigned matchVectorRegName(StringRef Name) {
1756   return StringSwitch<unsigned>(Name.lower())
1757       .Case("v0", AArch64::Q0)
1758       .Case("v1", AArch64::Q1)
1759       .Case("v2", AArch64::Q2)
1760       .Case("v3", AArch64::Q3)
1761       .Case("v4", AArch64::Q4)
1762       .Case("v5", AArch64::Q5)
1763       .Case("v6", AArch64::Q6)
1764       .Case("v7", AArch64::Q7)
1765       .Case("v8", AArch64::Q8)
1766       .Case("v9", AArch64::Q9)
1767       .Case("v10", AArch64::Q10)
1768       .Case("v11", AArch64::Q11)
1769       .Case("v12", AArch64::Q12)
1770       .Case("v13", AArch64::Q13)
1771       .Case("v14", AArch64::Q14)
1772       .Case("v15", AArch64::Q15)
1773       .Case("v16", AArch64::Q16)
1774       .Case("v17", AArch64::Q17)
1775       .Case("v18", AArch64::Q18)
1776       .Case("v19", AArch64::Q19)
1777       .Case("v20", AArch64::Q20)
1778       .Case("v21", AArch64::Q21)
1779       .Case("v22", AArch64::Q22)
1780       .Case("v23", AArch64::Q23)
1781       .Case("v24", AArch64::Q24)
1782       .Case("v25", AArch64::Q25)
1783       .Case("v26", AArch64::Q26)
1784       .Case("v27", AArch64::Q27)
1785       .Case("v28", AArch64::Q28)
1786       .Case("v29", AArch64::Q29)
1787       .Case("v30", AArch64::Q30)
1788       .Case("v31", AArch64::Q31)
1789       .Default(0);
1790 }
1791 
1792 static bool isValidVectorKind(StringRef Name) {
1793   return StringSwitch<bool>(Name.lower())
1794       .Case(".8b", true)
1795       .Case(".16b", true)
1796       .Case(".4h", true)
1797       .Case(".8h", true)
1798       .Case(".2s", true)
1799       .Case(".4s", true)
1800       .Case(".1d", true)
1801       .Case(".2d", true)
1802       .Case(".1q", true)
1803       // Accept the width neutral ones, too, for verbose syntax. If those
1804       // aren't used in the right places, the token operand won't match so
1805       // all will work out.
1806       .Case(".b", true)
1807       .Case(".h", true)
1808       .Case(".s", true)
1809       .Case(".d", true)
1810       // Needed for fp16 scalar pairwise reductions
1811       .Case(".2h", true)
1812       .Default(false);
1813 }
1814 
1815 static void parseValidVectorKind(StringRef Name, unsigned &NumElements,
1816                                  char &ElementKind) {
1817   assert(isValidVectorKind(Name));
1818 
1819   ElementKind = Name.lower()[Name.size() - 1];
1820   NumElements = 0;
1821 
1822   if (Name.size() == 2)
1823     return;
1824 
1825   // Parse the lane count
1826   Name = Name.drop_front();
1827   while (isdigit(Name.front())) {
1828     NumElements = 10 * NumElements + (Name.front() - '0');
1829     Name = Name.drop_front();
1830   }
1831 }
1832 
1833 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1834                                      SMLoc &EndLoc) {
1835   StartLoc = getLoc();
1836   RegNo = tryParseRegister();
1837   EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
1838   return (RegNo == (unsigned)-1);
1839 }
1840 
1841 // Matches a register name or register alias previously defined by '.req'
1842 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
1843                                                   bool isVector) {
1844   unsigned RegNum = isVector ? matchVectorRegName(Name)
1845                              : MatchRegisterName(Name);
1846 
1847   if (RegNum == 0) {
1848     // Check for aliases registered via .req. Canonicalize to lower case.
1849     // That's more consistent since register names are case insensitive, and
1850     // it's how the original entry was passed in from MC/MCParser/AsmParser.
1851     auto Entry = RegisterReqs.find(Name.lower());
1852     if (Entry == RegisterReqs.end())
1853       return 0;
1854     // set RegNum if the match is the right kind of register
1855     if (isVector == Entry->getValue().first)
1856       RegNum = Entry->getValue().second;
1857   }
1858   return RegNum;
1859 }
1860 
1861 /// tryParseRegister - Try to parse a register name. The token must be an
1862 /// Identifier when called, and if it is a register name the token is eaten and
1863 /// the register is added to the operand list.
1864 int AArch64AsmParser::tryParseRegister() {
1865   MCAsmParser &Parser = getParser();
1866   const AsmToken &Tok = Parser.getTok();
1867   if (Tok.isNot(AsmToken::Identifier))
1868     return -1;
1869 
1870   std::string lowerCase = Tok.getString().lower();
1871   unsigned RegNum = matchRegisterNameAlias(lowerCase, false);
1872   // Also handle a few aliases of registers.
1873   if (RegNum == 0)
1874     RegNum = StringSwitch<unsigned>(lowerCase)
1875                  .Case("fp",  AArch64::FP)
1876                  .Case("lr",  AArch64::LR)
1877                  .Case("x31", AArch64::XZR)
1878                  .Case("w31", AArch64::WZR)
1879                  .Default(0);
1880 
1881   if (RegNum == 0)
1882     return -1;
1883 
1884   Parser.Lex(); // Eat identifier token.
1885   return RegNum;
1886 }
1887 
1888 /// tryMatchVectorRegister - Try to parse a vector register name with optional
1889 /// kind specifier. If it is a register specifier, eat the token and return it.
1890 int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) {
1891   MCAsmParser &Parser = getParser();
1892   if (Parser.getTok().isNot(AsmToken::Identifier)) {
1893     TokError("vector register expected");
1894     return -1;
1895   }
1896 
1897   StringRef Name = Parser.getTok().getString();
1898   // If there is a kind specifier, it's separated from the register name by
1899   // a '.'.
1900   size_t Start = 0, Next = Name.find('.');
1901   StringRef Head = Name.slice(Start, Next);
1902   unsigned RegNum = matchRegisterNameAlias(Head, true);
1903 
1904   if (RegNum) {
1905     if (Next != StringRef::npos) {
1906       Kind = Name.slice(Next, StringRef::npos);
1907       if (!isValidVectorKind(Kind)) {
1908         TokError("invalid vector kind qualifier");
1909         return -1;
1910       }
1911     }
1912     Parser.Lex(); // Eat the register token.
1913     return RegNum;
1914   }
1915 
1916   if (expected)
1917     TokError("vector register expected");
1918   return -1;
1919 }
1920 
1921 /// tryParseSysCROperand - Try to parse a system instruction CR operand name.
1922 OperandMatchResultTy
1923 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
1924   MCAsmParser &Parser = getParser();
1925   SMLoc S = getLoc();
1926 
1927   if (Parser.getTok().isNot(AsmToken::Identifier)) {
1928     Error(S, "Expected cN operand where 0 <= N <= 15");
1929     return MatchOperand_ParseFail;
1930   }
1931 
1932   StringRef Tok = Parser.getTok().getIdentifier();
1933   if (Tok[0] != 'c' && Tok[0] != 'C') {
1934     Error(S, "Expected cN operand where 0 <= N <= 15");
1935     return MatchOperand_ParseFail;
1936   }
1937 
1938   uint32_t CRNum;
1939   bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
1940   if (BadNum || CRNum > 15) {
1941     Error(S, "Expected cN operand where 0 <= N <= 15");
1942     return MatchOperand_ParseFail;
1943   }
1944 
1945   Parser.Lex(); // Eat identifier token.
1946   Operands.push_back(
1947       AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
1948   return MatchOperand_Success;
1949 }
1950 
1951 /// tryParsePrefetch - Try to parse a prefetch operand.
1952 OperandMatchResultTy
1953 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
1954   MCAsmParser &Parser = getParser();
1955   SMLoc S = getLoc();
1956   const AsmToken &Tok = Parser.getTok();
1957   // Either an identifier for named values or a 5-bit immediate.
1958   // Eat optional hash.
1959   if (parseOptionalToken(AsmToken::Hash) ||
1960       Tok.is(AsmToken::Integer)) {
1961     const MCExpr *ImmVal;
1962     if (getParser().parseExpression(ImmVal))
1963       return MatchOperand_ParseFail;
1964 
1965     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
1966     if (!MCE) {
1967       TokError("immediate value expected for prefetch operand");
1968       return MatchOperand_ParseFail;
1969     }
1970     unsigned prfop = MCE->getValue();
1971     if (prfop > 31) {
1972       TokError("prefetch operand out of range, [0,31] expected");
1973       return MatchOperand_ParseFail;
1974     }
1975 
1976     auto PRFM = AArch64PRFM::lookupPRFMByEncoding(MCE->getValue());
1977     Operands.push_back(AArch64Operand::CreatePrefetch(
1978         prfop, PRFM ? PRFM->Name : "", S, getContext()));
1979     return MatchOperand_Success;
1980   }
1981 
1982   if (Tok.isNot(AsmToken::Identifier)) {
1983     TokError("pre-fetch hint expected");
1984     return MatchOperand_ParseFail;
1985   }
1986 
1987   auto PRFM = AArch64PRFM::lookupPRFMByName(Tok.getString());
1988   if (!PRFM) {
1989     TokError("pre-fetch hint expected");
1990     return MatchOperand_ParseFail;
1991   }
1992 
1993   Parser.Lex(); // Eat identifier token.
1994   Operands.push_back(AArch64Operand::CreatePrefetch(
1995       PRFM->Encoding, Tok.getString(), S, getContext()));
1996   return MatchOperand_Success;
1997 }
1998 
1999 /// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command
2000 OperandMatchResultTy
2001 AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) {
2002   MCAsmParser &Parser = getParser();
2003   SMLoc S = getLoc();
2004   const AsmToken &Tok = Parser.getTok();
2005   if (Tok.isNot(AsmToken::Identifier)) {
2006     TokError("invalid operand for instruction");
2007     return MatchOperand_ParseFail;
2008   }
2009 
2010   auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString());
2011   if (!PSB) {
2012     TokError("invalid operand for instruction");
2013     return MatchOperand_ParseFail;
2014   }
2015 
2016   Parser.Lex(); // Eat identifier token.
2017   Operands.push_back(AArch64Operand::CreatePSBHint(
2018       PSB->Encoding, Tok.getString(), S, getContext()));
2019   return MatchOperand_Success;
2020 }
2021 
2022 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2023 /// instruction.
2024 OperandMatchResultTy
2025 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2026   MCAsmParser &Parser = getParser();
2027   SMLoc S = getLoc();
2028   const MCExpr *Expr;
2029 
2030   if (Parser.getTok().is(AsmToken::Hash)) {
2031     Parser.Lex(); // Eat hash token.
2032   }
2033 
2034   if (parseSymbolicImmVal(Expr))
2035     return MatchOperand_ParseFail;
2036 
2037   AArch64MCExpr::VariantKind ELFRefKind;
2038   MCSymbolRefExpr::VariantKind DarwinRefKind;
2039   int64_t Addend;
2040   if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2041     if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2042         ELFRefKind == AArch64MCExpr::VK_INVALID) {
2043       // No modifier was specified at all; this is the syntax for an ELF basic
2044       // ADRP relocation (unfortunately).
2045       Expr =
2046           AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
2047     } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2048                 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2049                Addend != 0) {
2050       Error(S, "gotpage label reference not allowed an addend");
2051       return MatchOperand_ParseFail;
2052     } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2053                DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2054                DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2055                ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
2056                ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
2057                ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
2058       // The operand must be an @page or @gotpage qualified symbolref.
2059       Error(S, "page or gotpage label reference expected");
2060       return MatchOperand_ParseFail;
2061     }
2062   }
2063 
2064   // We have either a label reference possibly with addend or an immediate. The
2065   // addend is a raw value here. The linker will adjust it to only reference the
2066   // page.
2067   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2068   Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2069 
2070   return MatchOperand_Success;
2071 }
2072 
2073 /// tryParseAdrLabel - Parse and validate a source label for the ADR
2074 /// instruction.
2075 OperandMatchResultTy
2076 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2077   SMLoc S = getLoc();
2078   const MCExpr *Expr;
2079 
2080   parseOptionalToken(AsmToken::Hash);
2081   if (getParser().parseExpression(Expr))
2082     return MatchOperand_ParseFail;
2083 
2084   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2085   Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2086 
2087   return MatchOperand_Success;
2088 }
2089 
2090 /// tryParseFPImm - A floating point immediate expression operand.
2091 OperandMatchResultTy
2092 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
2093   MCAsmParser &Parser = getParser();
2094   SMLoc S = getLoc();
2095 
2096   bool Hash = parseOptionalToken(AsmToken::Hash);
2097 
2098   // Handle negation, as that still comes through as a separate token.
2099   bool isNegative = parseOptionalToken(AsmToken::Minus);
2100 
2101   const AsmToken &Tok = Parser.getTok();
2102   if (Tok.is(AsmToken::Real)) {
2103     APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
2104     if (isNegative)
2105       RealVal.changeSign();
2106 
2107     uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2108     int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2109     Parser.Lex(); // Eat the token.
2110     // Check for out of range values. As an exception, we let Zero through,
2111     // as we handle that special case in post-processing before matching in
2112     // order to use the zero register for it.
2113     if (Val == -1 && !RealVal.isPosZero()) {
2114       TokError("expected compatible register or floating-point constant");
2115       return MatchOperand_ParseFail;
2116     }
2117     Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2118     return MatchOperand_Success;
2119   }
2120   if (Tok.is(AsmToken::Integer)) {
2121     int64_t Val;
2122     if (!isNegative && Tok.getString().startswith("0x")) {
2123       Val = Tok.getIntVal();
2124       if (Val > 255 || Val < 0) {
2125         TokError("encoded floating point value out of range");
2126         return MatchOperand_ParseFail;
2127       }
2128     } else {
2129       APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
2130       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2131       // If we had a '-' in front, toggle the sign bit.
2132       IntVal ^= (uint64_t)isNegative << 63;
2133       Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2134     }
2135     Parser.Lex(); // Eat the token.
2136     Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2137     return MatchOperand_Success;
2138   }
2139 
2140   if (!Hash)
2141     return MatchOperand_NoMatch;
2142 
2143   TokError("invalid floating point immediate");
2144   return MatchOperand_ParseFail;
2145 }
2146 
2147 /// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand
2148 OperandMatchResultTy
2149 AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
2150   MCAsmParser &Parser = getParser();
2151   SMLoc S = getLoc();
2152 
2153   if (Parser.getTok().is(AsmToken::Hash))
2154     Parser.Lex(); // Eat '#'
2155   else if (Parser.getTok().isNot(AsmToken::Integer))
2156     // Operand should start from # or should be integer, emit error otherwise.
2157     return MatchOperand_NoMatch;
2158 
2159   const MCExpr *Imm;
2160   if (parseSymbolicImmVal(Imm))
2161     return MatchOperand_ParseFail;
2162   else if (Parser.getTok().isNot(AsmToken::Comma)) {
2163     uint64_t ShiftAmount = 0;
2164     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm);
2165     if (MCE) {
2166       int64_t Val = MCE->getValue();
2167       if (Val > 0xfff && (Val & 0xfff) == 0) {
2168         Imm = MCConstantExpr::create(Val >> 12, getContext());
2169         ShiftAmount = 12;
2170       }
2171     }
2172     SMLoc E = Parser.getTok().getLoc();
2173     Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
2174                                                         getContext()));
2175     return MatchOperand_Success;
2176   }
2177 
2178   // Eat ','
2179   Parser.Lex();
2180 
2181   // The optional operand must be "lsl #N" where N is non-negative.
2182   if (!Parser.getTok().is(AsmToken::Identifier) ||
2183       !Parser.getTok().getIdentifier().equals_lower("lsl")) {
2184     Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2185     return MatchOperand_ParseFail;
2186   }
2187 
2188   // Eat 'lsl'
2189   Parser.Lex();
2190 
2191   parseOptionalToken(AsmToken::Hash);
2192 
2193   if (Parser.getTok().isNot(AsmToken::Integer)) {
2194     Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2195     return MatchOperand_ParseFail;
2196   }
2197 
2198   int64_t ShiftAmount = Parser.getTok().getIntVal();
2199 
2200   if (ShiftAmount < 0) {
2201     Error(Parser.getTok().getLoc(), "positive shift amount required");
2202     return MatchOperand_ParseFail;
2203   }
2204   Parser.Lex(); // Eat the number
2205 
2206   SMLoc E = Parser.getTok().getLoc();
2207   Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2208                                                       S, E, getContext()));
2209   return MatchOperand_Success;
2210 }
2211 
2212 /// parseCondCodeString - Parse a Condition Code string.
2213 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
2214   AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
2215                     .Case("eq", AArch64CC::EQ)
2216                     .Case("ne", AArch64CC::NE)
2217                     .Case("cs", AArch64CC::HS)
2218                     .Case("hs", AArch64CC::HS)
2219                     .Case("cc", AArch64CC::LO)
2220                     .Case("lo", AArch64CC::LO)
2221                     .Case("mi", AArch64CC::MI)
2222                     .Case("pl", AArch64CC::PL)
2223                     .Case("vs", AArch64CC::VS)
2224                     .Case("vc", AArch64CC::VC)
2225                     .Case("hi", AArch64CC::HI)
2226                     .Case("ls", AArch64CC::LS)
2227                     .Case("ge", AArch64CC::GE)
2228                     .Case("lt", AArch64CC::LT)
2229                     .Case("gt", AArch64CC::GT)
2230                     .Case("le", AArch64CC::LE)
2231                     .Case("al", AArch64CC::AL)
2232                     .Case("nv", AArch64CC::NV)
2233                     .Default(AArch64CC::Invalid);
2234   return CC;
2235 }
2236 
2237 /// parseCondCode - Parse a Condition Code operand.
2238 bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
2239                                      bool invertCondCode) {
2240   MCAsmParser &Parser = getParser();
2241   SMLoc S = getLoc();
2242   const AsmToken &Tok = Parser.getTok();
2243   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2244 
2245   StringRef Cond = Tok.getString();
2246   AArch64CC::CondCode CC = parseCondCodeString(Cond);
2247   if (CC == AArch64CC::Invalid)
2248     return TokError("invalid condition code");
2249   Parser.Lex(); // Eat identifier token.
2250 
2251   if (invertCondCode) {
2252     if (CC == AArch64CC::AL || CC == AArch64CC::NV)
2253       return TokError("condition codes AL and NV are invalid for this instruction");
2254     CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
2255   }
2256 
2257   Operands.push_back(
2258       AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2259   return false;
2260 }
2261 
2262 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse
2263 /// them if present.
2264 OperandMatchResultTy
2265 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
2266   MCAsmParser &Parser = getParser();
2267   const AsmToken &Tok = Parser.getTok();
2268   std::string LowerID = Tok.getString().lower();
2269   AArch64_AM::ShiftExtendType ShOp =
2270       StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
2271           .Case("lsl", AArch64_AM::LSL)
2272           .Case("lsr", AArch64_AM::LSR)
2273           .Case("asr", AArch64_AM::ASR)
2274           .Case("ror", AArch64_AM::ROR)
2275           .Case("msl", AArch64_AM::MSL)
2276           .Case("uxtb", AArch64_AM::UXTB)
2277           .Case("uxth", AArch64_AM::UXTH)
2278           .Case("uxtw", AArch64_AM::UXTW)
2279           .Case("uxtx", AArch64_AM::UXTX)
2280           .Case("sxtb", AArch64_AM::SXTB)
2281           .Case("sxth", AArch64_AM::SXTH)
2282           .Case("sxtw", AArch64_AM::SXTW)
2283           .Case("sxtx", AArch64_AM::SXTX)
2284           .Default(AArch64_AM::InvalidShiftExtend);
2285 
2286   if (ShOp == AArch64_AM::InvalidShiftExtend)
2287     return MatchOperand_NoMatch;
2288 
2289   SMLoc S = Tok.getLoc();
2290   Parser.Lex();
2291 
2292   bool Hash = parseOptionalToken(AsmToken::Hash);
2293 
2294   if (!Hash && getLexer().isNot(AsmToken::Integer)) {
2295     if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
2296         ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
2297         ShOp == AArch64_AM::MSL) {
2298       // We expect a number here.
2299       TokError("expected #imm after shift specifier");
2300       return MatchOperand_ParseFail;
2301     }
2302 
2303     // "extend" type operations don't need an immediate, #0 is implicit.
2304     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2305     Operands.push_back(
2306         AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
2307     return MatchOperand_Success;
2308   }
2309 
2310   // Make sure we do actually have a number, identifier or a parenthesized
2311   // expression.
2312   SMLoc E = Parser.getTok().getLoc();
2313   if (!Parser.getTok().is(AsmToken::Integer) &&
2314       !Parser.getTok().is(AsmToken::LParen) &&
2315       !Parser.getTok().is(AsmToken::Identifier)) {
2316     Error(E, "expected integer shift amount");
2317     return MatchOperand_ParseFail;
2318   }
2319 
2320   const MCExpr *ImmVal;
2321   if (getParser().parseExpression(ImmVal))
2322     return MatchOperand_ParseFail;
2323 
2324   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2325   if (!MCE) {
2326     Error(E, "expected constant '#imm' after shift specifier");
2327     return MatchOperand_ParseFail;
2328   }
2329 
2330   E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2331   Operands.push_back(AArch64Operand::CreateShiftExtend(
2332       ShOp, MCE->getValue(), true, S, E, getContext()));
2333   return MatchOperand_Success;
2334 }
2335 
2336 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
2337 /// the SYS instruction. Parse them specially so that we create a SYS MCInst.
2338 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
2339                                    OperandVector &Operands) {
2340   if (Name.find('.') != StringRef::npos)
2341     return TokError("invalid operand");
2342 
2343   Mnemonic = Name;
2344   Operands.push_back(
2345       AArch64Operand::CreateToken("sys", false, NameLoc, getContext()));
2346 
2347   MCAsmParser &Parser = getParser();
2348   const AsmToken &Tok = Parser.getTok();
2349   StringRef Op = Tok.getString();
2350   SMLoc S = Tok.getLoc();
2351 
2352   const MCExpr *Expr = nullptr;
2353 
2354 #define SYS_ALIAS(op1, Cn, Cm, op2)                                            \
2355   do {                                                                         \
2356     Expr = MCConstantExpr::create(op1, getContext());                          \
2357     Operands.push_back(                                                        \
2358         AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));           \
2359     Operands.push_back(                                                        \
2360         AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));           \
2361     Operands.push_back(                                                        \
2362         AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));           \
2363     Expr = MCConstantExpr::create(op2, getContext());                          \
2364     Operands.push_back(                                                        \
2365         AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));           \
2366   } while (false)
2367 
2368   if (Mnemonic == "ic") {
2369     if (!Op.compare_lower("ialluis")) {
2370       // SYS #0, C7, C1, #0
2371       SYS_ALIAS(0, 7, 1, 0);
2372     } else if (!Op.compare_lower("iallu")) {
2373       // SYS #0, C7, C5, #0
2374       SYS_ALIAS(0, 7, 5, 0);
2375     } else if (!Op.compare_lower("ivau")) {
2376       // SYS #3, C7, C5, #1
2377       SYS_ALIAS(3, 7, 5, 1);
2378     } else {
2379       return TokError("invalid operand for IC instruction");
2380     }
2381   } else if (Mnemonic == "dc") {
2382     if (!Op.compare_lower("zva")) {
2383       // SYS #3, C7, C4, #1
2384       SYS_ALIAS(3, 7, 4, 1);
2385     } else if (!Op.compare_lower("ivac")) {
2386       // SYS #3, C7, C6, #1
2387       SYS_ALIAS(0, 7, 6, 1);
2388     } else if (!Op.compare_lower("isw")) {
2389       // SYS #0, C7, C6, #2
2390       SYS_ALIAS(0, 7, 6, 2);
2391     } else if (!Op.compare_lower("cvac")) {
2392       // SYS #3, C7, C10, #1
2393       SYS_ALIAS(3, 7, 10, 1);
2394     } else if (!Op.compare_lower("csw")) {
2395       // SYS #0, C7, C10, #2
2396       SYS_ALIAS(0, 7, 10, 2);
2397     } else if (!Op.compare_lower("cvau")) {
2398       // SYS #3, C7, C11, #1
2399       SYS_ALIAS(3, 7, 11, 1);
2400     } else if (!Op.compare_lower("civac")) {
2401       // SYS #3, C7, C14, #1
2402       SYS_ALIAS(3, 7, 14, 1);
2403     } else if (!Op.compare_lower("cisw")) {
2404       // SYS #0, C7, C14, #2
2405       SYS_ALIAS(0, 7, 14, 2);
2406     } else if (!Op.compare_lower("cvap")) {
2407       if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) {
2408         // SYS #3, C7, C12, #1
2409         SYS_ALIAS(3, 7, 12, 1);
2410       } else {
2411         return TokError("DC CVAP requires ARMv8.2a");
2412       }
2413     } else {
2414       return TokError("invalid operand for DC instruction");
2415     }
2416   } else if (Mnemonic == "at") {
2417     if (!Op.compare_lower("s1e1r")) {
2418       // SYS #0, C7, C8, #0
2419       SYS_ALIAS(0, 7, 8, 0);
2420     } else if (!Op.compare_lower("s1e2r")) {
2421       // SYS #4, C7, C8, #0
2422       SYS_ALIAS(4, 7, 8, 0);
2423     } else if (!Op.compare_lower("s1e3r")) {
2424       // SYS #6, C7, C8, #0
2425       SYS_ALIAS(6, 7, 8, 0);
2426     } else if (!Op.compare_lower("s1e1w")) {
2427       // SYS #0, C7, C8, #1
2428       SYS_ALIAS(0, 7, 8, 1);
2429     } else if (!Op.compare_lower("s1e2w")) {
2430       // SYS #4, C7, C8, #1
2431       SYS_ALIAS(4, 7, 8, 1);
2432     } else if (!Op.compare_lower("s1e3w")) {
2433       // SYS #6, C7, C8, #1
2434       SYS_ALIAS(6, 7, 8, 1);
2435     } else if (!Op.compare_lower("s1e0r")) {
2436       // SYS #0, C7, C8, #3
2437       SYS_ALIAS(0, 7, 8, 2);
2438     } else if (!Op.compare_lower("s1e0w")) {
2439       // SYS #0, C7, C8, #3
2440       SYS_ALIAS(0, 7, 8, 3);
2441     } else if (!Op.compare_lower("s12e1r")) {
2442       // SYS #4, C7, C8, #4
2443       SYS_ALIAS(4, 7, 8, 4);
2444     } else if (!Op.compare_lower("s12e1w")) {
2445       // SYS #4, C7, C8, #5
2446       SYS_ALIAS(4, 7, 8, 5);
2447     } else if (!Op.compare_lower("s12e0r")) {
2448       // SYS #4, C7, C8, #6
2449       SYS_ALIAS(4, 7, 8, 6);
2450     } else if (!Op.compare_lower("s12e0w")) {
2451       // SYS #4, C7, C8, #7
2452       SYS_ALIAS(4, 7, 8, 7);
2453     } else if (!Op.compare_lower("s1e1rp")) {
2454       if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) {
2455         // SYS #0, C7, C9, #0
2456         SYS_ALIAS(0, 7, 9, 0);
2457       } else {
2458         return TokError("AT S1E1RP requires ARMv8.2a");
2459       }
2460     } else if (!Op.compare_lower("s1e1wp")) {
2461       if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) {
2462         // SYS #0, C7, C9, #1
2463         SYS_ALIAS(0, 7, 9, 1);
2464       } else {
2465         return TokError("AT S1E1WP requires ARMv8.2a");
2466       }
2467     } else {
2468       return TokError("invalid operand for AT instruction");
2469     }
2470   } else if (Mnemonic == "tlbi") {
2471     if (!Op.compare_lower("vmalle1is")) {
2472       // SYS #0, C8, C3, #0
2473       SYS_ALIAS(0, 8, 3, 0);
2474     } else if (!Op.compare_lower("alle2is")) {
2475       // SYS #4, C8, C3, #0
2476       SYS_ALIAS(4, 8, 3, 0);
2477     } else if (!Op.compare_lower("alle3is")) {
2478       // SYS #6, C8, C3, #0
2479       SYS_ALIAS(6, 8, 3, 0);
2480     } else if (!Op.compare_lower("vae1is")) {
2481       // SYS #0, C8, C3, #1
2482       SYS_ALIAS(0, 8, 3, 1);
2483     } else if (!Op.compare_lower("vae2is")) {
2484       // SYS #4, C8, C3, #1
2485       SYS_ALIAS(4, 8, 3, 1);
2486     } else if (!Op.compare_lower("vae3is")) {
2487       // SYS #6, C8, C3, #1
2488       SYS_ALIAS(6, 8, 3, 1);
2489     } else if (!Op.compare_lower("aside1is")) {
2490       // SYS #0, C8, C3, #2
2491       SYS_ALIAS(0, 8, 3, 2);
2492     } else if (!Op.compare_lower("vaae1is")) {
2493       // SYS #0, C8, C3, #3
2494       SYS_ALIAS(0, 8, 3, 3);
2495     } else if (!Op.compare_lower("alle1is")) {
2496       // SYS #4, C8, C3, #4
2497       SYS_ALIAS(4, 8, 3, 4);
2498     } else if (!Op.compare_lower("vale1is")) {
2499       // SYS #0, C8, C3, #5
2500       SYS_ALIAS(0, 8, 3, 5);
2501     } else if (!Op.compare_lower("vaale1is")) {
2502       // SYS #0, C8, C3, #7
2503       SYS_ALIAS(0, 8, 3, 7);
2504     } else if (!Op.compare_lower("vmalle1")) {
2505       // SYS #0, C8, C7, #0
2506       SYS_ALIAS(0, 8, 7, 0);
2507     } else if (!Op.compare_lower("alle2")) {
2508       // SYS #4, C8, C7, #0
2509       SYS_ALIAS(4, 8, 7, 0);
2510     } else if (!Op.compare_lower("vale2is")) {
2511       // SYS #4, C8, C3, #5
2512       SYS_ALIAS(4, 8, 3, 5);
2513     } else if (!Op.compare_lower("vale3is")) {
2514       // SYS #6, C8, C3, #5
2515       SYS_ALIAS(6, 8, 3, 5);
2516     } else if (!Op.compare_lower("alle3")) {
2517       // SYS #6, C8, C7, #0
2518       SYS_ALIAS(6, 8, 7, 0);
2519     } else if (!Op.compare_lower("vae1")) {
2520       // SYS #0, C8, C7, #1
2521       SYS_ALIAS(0, 8, 7, 1);
2522     } else if (!Op.compare_lower("vae2")) {
2523       // SYS #4, C8, C7, #1
2524       SYS_ALIAS(4, 8, 7, 1);
2525     } else if (!Op.compare_lower("vae3")) {
2526       // SYS #6, C8, C7, #1
2527       SYS_ALIAS(6, 8, 7, 1);
2528     } else if (!Op.compare_lower("aside1")) {
2529       // SYS #0, C8, C7, #2
2530       SYS_ALIAS(0, 8, 7, 2);
2531     } else if (!Op.compare_lower("vaae1")) {
2532       // SYS #0, C8, C7, #3
2533       SYS_ALIAS(0, 8, 7, 3);
2534     } else if (!Op.compare_lower("alle1")) {
2535       // SYS #4, C8, C7, #4
2536       SYS_ALIAS(4, 8, 7, 4);
2537     } else if (!Op.compare_lower("vale1")) {
2538       // SYS #0, C8, C7, #5
2539       SYS_ALIAS(0, 8, 7, 5);
2540     } else if (!Op.compare_lower("vale2")) {
2541       // SYS #4, C8, C7, #5
2542       SYS_ALIAS(4, 8, 7, 5);
2543     } else if (!Op.compare_lower("vale3")) {
2544       // SYS #6, C8, C7, #5
2545       SYS_ALIAS(6, 8, 7, 5);
2546     } else if (!Op.compare_lower("vaale1")) {
2547       // SYS #0, C8, C7, #7
2548       SYS_ALIAS(0, 8, 7, 7);
2549     } else if (!Op.compare_lower("ipas2e1")) {
2550       // SYS #4, C8, C4, #1
2551       SYS_ALIAS(4, 8, 4, 1);
2552     } else if (!Op.compare_lower("ipas2le1")) {
2553       // SYS #4, C8, C4, #5
2554       SYS_ALIAS(4, 8, 4, 5);
2555     } else if (!Op.compare_lower("ipas2e1is")) {
2556       // SYS #4, C8, C4, #1
2557       SYS_ALIAS(4, 8, 0, 1);
2558     } else if (!Op.compare_lower("ipas2le1is")) {
2559       // SYS #4, C8, C4, #5
2560       SYS_ALIAS(4, 8, 0, 5);
2561     } else if (!Op.compare_lower("vmalls12e1")) {
2562       // SYS #4, C8, C7, #6
2563       SYS_ALIAS(4, 8, 7, 6);
2564     } else if (!Op.compare_lower("vmalls12e1is")) {
2565       // SYS #4, C8, C3, #6
2566       SYS_ALIAS(4, 8, 3, 6);
2567     } else {
2568       return TokError("invalid operand for TLBI instruction");
2569     }
2570   }
2571 
2572 #undef SYS_ALIAS
2573 
2574   Parser.Lex(); // Eat operand.
2575 
2576   bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
2577   bool HasRegister = false;
2578 
2579   // Check for the optional register operand.
2580   if (parseOptionalToken(AsmToken::Comma)) {
2581     if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
2582       return TokError("expected register operand");
2583     HasRegister = true;
2584   }
2585 
2586   if (ExpectRegister && !HasRegister) {
2587     return TokError("specified " + Mnemonic + " op requires a register");
2588   }
2589   else if (!ExpectRegister && HasRegister) {
2590     return TokError("specified " + Mnemonic + " op does not use a register");
2591   }
2592 
2593   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
2594     return true;
2595 
2596   return false;
2597 }
2598 
2599 OperandMatchResultTy
2600 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
2601   MCAsmParser &Parser = getParser();
2602   const AsmToken &Tok = Parser.getTok();
2603 
2604   // Can be either a #imm style literal or an option name
2605   if (parseOptionalToken(AsmToken::Hash) ||
2606       Tok.is(AsmToken::Integer)) {
2607     // Immediate operand.
2608     const MCExpr *ImmVal;
2609     SMLoc ExprLoc = getLoc();
2610     if (getParser().parseExpression(ImmVal))
2611       return MatchOperand_ParseFail;
2612     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2613     if (!MCE) {
2614       Error(ExprLoc, "immediate value expected for barrier operand");
2615       return MatchOperand_ParseFail;
2616     }
2617     if (MCE->getValue() < 0 || MCE->getValue() > 15) {
2618       Error(ExprLoc, "barrier operand out of range");
2619       return MatchOperand_ParseFail;
2620     }
2621     auto DB = AArch64DB::lookupDBByEncoding(MCE->getValue());
2622     Operands.push_back(AArch64Operand::CreateBarrier(
2623         MCE->getValue(), DB ? DB->Name : "", ExprLoc, getContext()));
2624     return MatchOperand_Success;
2625   }
2626 
2627   if (Tok.isNot(AsmToken::Identifier)) {
2628     TokError("invalid operand for instruction");
2629     return MatchOperand_ParseFail;
2630   }
2631 
2632   auto DB = AArch64DB::lookupDBByName(Tok.getString());
2633   if (!DB) {
2634     TokError("invalid barrier option name");
2635     return MatchOperand_ParseFail;
2636   }
2637 
2638   // The only valid named option for ISB is 'sy'
2639   if (Mnemonic == "isb" && DB->Encoding != AArch64DB::sy) {
2640     TokError("'sy' or #imm operand expected");
2641     return MatchOperand_ParseFail;
2642   }
2643 
2644   Operands.push_back(AArch64Operand::CreateBarrier(
2645       DB->Encoding, Tok.getString(), getLoc(), getContext()));
2646   Parser.Lex(); // Consume the option
2647 
2648   return MatchOperand_Success;
2649 }
2650 
2651 OperandMatchResultTy
2652 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
2653   MCAsmParser &Parser = getParser();
2654   const AsmToken &Tok = Parser.getTok();
2655 
2656   if (Tok.isNot(AsmToken::Identifier))
2657     return MatchOperand_NoMatch;
2658 
2659   int MRSReg, MSRReg;
2660   auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString());
2661   if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
2662     MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
2663     MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
2664   } else
2665     MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString());
2666 
2667   auto PState = AArch64PState::lookupPStateByName(Tok.getString());
2668   unsigned PStateImm = -1;
2669   if (PState && PState->haveFeatures(getSTI().getFeatureBits()))
2670     PStateImm = PState->Encoding;
2671 
2672   Operands.push_back(
2673       AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg,
2674                                    PStateImm, getContext()));
2675   Parser.Lex(); // Eat identifier
2676 
2677   return MatchOperand_Success;
2678 }
2679 
2680 /// tryParseVectorRegister - Parse a vector register operand.
2681 bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
2682   MCAsmParser &Parser = getParser();
2683   if (Parser.getTok().isNot(AsmToken::Identifier))
2684     return true;
2685 
2686   SMLoc S = getLoc();
2687   // Check for a vector register specifier first.
2688   StringRef Kind;
2689   int64_t Reg = tryMatchVectorRegister(Kind, false);
2690   if (Reg == -1)
2691     return true;
2692   Operands.push_back(
2693       AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
2694   // If there was an explicit qualifier, that goes on as a literal text
2695   // operand.
2696   if (!Kind.empty())
2697     Operands.push_back(
2698         AArch64Operand::CreateToken(Kind, false, S, getContext()));
2699 
2700   // If there is an index specifier following the register, parse that too.
2701   SMLoc SIdx = getLoc();
2702   if (parseOptionalToken(AsmToken::LBrac)) {
2703     const MCExpr *ImmVal;
2704     if (getParser().parseExpression(ImmVal))
2705       return false;
2706     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2707     if (!MCE) {
2708       TokError("immediate value expected for vector index");
2709       return false;
2710     }
2711 
2712     SMLoc E = getLoc();
2713 
2714     if (parseToken(AsmToken::RBrac, "']' expected"))
2715       return false;
2716 
2717     Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2718                                                          E, getContext()));
2719   }
2720 
2721   return false;
2722 }
2723 
2724 /// parseRegister - Parse a non-vector register operand.
2725 bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
2726   SMLoc S = getLoc();
2727   // Try for a vector register.
2728   if (!tryParseVectorRegister(Operands))
2729     return false;
2730 
2731   // Try for a scalar register.
2732   int64_t Reg = tryParseRegister();
2733   if (Reg == -1)
2734     return true;
2735   Operands.push_back(
2736       AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
2737 
2738   return false;
2739 }
2740 
2741 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
2742   MCAsmParser &Parser = getParser();
2743   bool HasELFModifier = false;
2744   AArch64MCExpr::VariantKind RefKind;
2745 
2746   if (parseOptionalToken(AsmToken::Colon)) {
2747     HasELFModifier = true;
2748 
2749     if (Parser.getTok().isNot(AsmToken::Identifier))
2750       return TokError("expect relocation specifier in operand after ':'");
2751 
2752     std::string LowerCase = Parser.getTok().getIdentifier().lower();
2753     RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
2754                   .Case("lo12", AArch64MCExpr::VK_LO12)
2755                   .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
2756                   .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
2757                   .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
2758                   .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
2759                   .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
2760                   .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
2761                   .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
2762                   .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
2763                   .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
2764                   .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
2765                   .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
2766                   .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
2767                   .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
2768                   .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
2769                   .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
2770                   .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
2771                   .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
2772                   .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
2773                   .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
2774                   .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
2775                   .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
2776                   .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
2777                   .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
2778                   .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
2779                   .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
2780                   .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
2781                   .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
2782                   .Case("got", AArch64MCExpr::VK_GOT_PAGE)
2783                   .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
2784                   .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
2785                   .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
2786                   .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
2787                   .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
2788                   .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
2789                   .Default(AArch64MCExpr::VK_INVALID);
2790 
2791     if (RefKind == AArch64MCExpr::VK_INVALID)
2792       return TokError("expect relocation specifier in operand after ':'");
2793 
2794     Parser.Lex(); // Eat identifier
2795 
2796     if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier"))
2797       return true;
2798   }
2799 
2800   if (getParser().parseExpression(ImmVal))
2801     return true;
2802 
2803   if (HasELFModifier)
2804     ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext());
2805 
2806   return false;
2807 }
2808 
2809 /// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
2810 bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
2811   MCAsmParser &Parser = getParser();
2812   assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
2813   SMLoc S = getLoc();
2814   Parser.Lex(); // Eat left bracket token.
2815   StringRef Kind;
2816   int64_t FirstReg = tryMatchVectorRegister(Kind, true);
2817   if (FirstReg == -1)
2818     return true;
2819   int64_t PrevReg = FirstReg;
2820   unsigned Count = 1;
2821 
2822   if (parseOptionalToken(AsmToken::Minus)) {
2823     SMLoc Loc = getLoc();
2824     StringRef NextKind;
2825     int64_t Reg = tryMatchVectorRegister(NextKind, true);
2826     if (Reg == -1)
2827       return true;
2828     // Any Kind suffices must match on all regs in the list.
2829     if (Kind != NextKind)
2830       return Error(Loc, "mismatched register size suffix");
2831 
2832     unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
2833 
2834     if (Space == 0 || Space > 3) {
2835       return Error(Loc, "invalid number of vectors");
2836     }
2837 
2838     Count += Space;
2839   }
2840   else {
2841     while (parseOptionalToken(AsmToken::Comma)) {
2842       SMLoc Loc = getLoc();
2843       StringRef NextKind;
2844       int64_t Reg = tryMatchVectorRegister(NextKind, true);
2845       if (Reg == -1)
2846         return true;
2847       // Any Kind suffices must match on all regs in the list.
2848       if (Kind != NextKind)
2849         return Error(Loc, "mismatched register size suffix");
2850 
2851       // Registers must be incremental (with wraparound at 31)
2852       if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2853           (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2854        return Error(Loc, "registers must be sequential");
2855 
2856       PrevReg = Reg;
2857       ++Count;
2858     }
2859   }
2860 
2861   if (parseToken(AsmToken::RCurly, "'}' expected"))
2862     return true;
2863 
2864   if (Count > 4)
2865     return Error(S, "invalid number of vectors");
2866 
2867   unsigned NumElements = 0;
2868   char ElementKind = 0;
2869   if (!Kind.empty())
2870     parseValidVectorKind(Kind, NumElements, ElementKind);
2871 
2872   Operands.push_back(AArch64Operand::CreateVectorList(
2873       FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2874 
2875   // If there is an index specifier following the list, parse that too.
2876   SMLoc SIdx = getLoc();
2877   if (parseOptionalToken(AsmToken::LBrac)) { // Eat left bracket token.
2878     const MCExpr *ImmVal;
2879     if (getParser().parseExpression(ImmVal))
2880       return false;
2881     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2882     if (!MCE) {
2883       TokError("immediate value expected for vector index");
2884       return false;
2885     }
2886 
2887     SMLoc E = getLoc();
2888     if (parseToken(AsmToken::RBrac, "']' expected"))
2889       return false;
2890 
2891     Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2892                                                          E, getContext()));
2893   }
2894   return false;
2895 }
2896 
2897 OperandMatchResultTy
2898 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
2899   MCAsmParser &Parser = getParser();
2900   const AsmToken &Tok = Parser.getTok();
2901   if (!Tok.is(AsmToken::Identifier))
2902     return MatchOperand_NoMatch;
2903 
2904   unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false);
2905 
2906   MCContext &Ctx = getContext();
2907   const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2908   if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
2909     return MatchOperand_NoMatch;
2910 
2911   SMLoc S = getLoc();
2912   Parser.Lex(); // Eat register
2913 
2914   if (!parseOptionalToken(AsmToken::Comma)) {
2915     Operands.push_back(
2916         AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2917     return MatchOperand_Success;
2918   }
2919 
2920   parseOptionalToken(AsmToken::Hash);
2921 
2922   if (Parser.getTok().isNot(AsmToken::Integer)) {
2923     Error(getLoc(), "index must be absent or #0");
2924     return MatchOperand_ParseFail;
2925   }
2926 
2927   const MCExpr *ImmVal;
2928   if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
2929       cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
2930     Error(getLoc(), "index must be absent or #0");
2931     return MatchOperand_ParseFail;
2932   }
2933 
2934   Operands.push_back(
2935       AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2936   return MatchOperand_Success;
2937 }
2938 
2939 /// parseOperand - Parse a arm instruction operand.  For now this parses the
2940 /// operand regardless of the mnemonic.
2941 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
2942                                   bool invertCondCode) {
2943   MCAsmParser &Parser = getParser();
2944   // Check if the current operand has a custom associated parser, if so, try to
2945   // custom parse the operand, or fallback to the general approach.
2946   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2947   if (ResTy == MatchOperand_Success)
2948     return false;
2949   // If there wasn't a custom match, try the generic matcher below. Otherwise,
2950   // there was a match, but an error occurred, in which case, just return that
2951   // the operand parsing failed.
2952   if (ResTy == MatchOperand_ParseFail)
2953     return true;
2954 
2955   // Nothing custom, so do general case parsing.
2956   SMLoc S, E;
2957   switch (getLexer().getKind()) {
2958   default: {
2959     SMLoc S = getLoc();
2960     const MCExpr *Expr;
2961     if (parseSymbolicImmVal(Expr))
2962       return Error(S, "invalid operand");
2963 
2964     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2965     Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2966     return false;
2967   }
2968   case AsmToken::LBrac: {
2969     SMLoc Loc = Parser.getTok().getLoc();
2970     Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
2971                                                    getContext()));
2972     Parser.Lex(); // Eat '['
2973 
2974     // There's no comma after a '[', so we can parse the next operand
2975     // immediately.
2976     return parseOperand(Operands, false, false);
2977   }
2978   case AsmToken::LCurly:
2979     return parseVectorList(Operands);
2980   case AsmToken::Identifier: {
2981     // If we're expecting a Condition Code operand, then just parse that.
2982     if (isCondCode)
2983       return parseCondCode(Operands, invertCondCode);
2984 
2985     // If it's a register name, parse it.
2986     if (!parseRegister(Operands))
2987       return false;
2988 
2989     // This could be an optional "shift" or "extend" operand.
2990     OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
2991     // We can only continue if no tokens were eaten.
2992     if (GotShift != MatchOperand_NoMatch)
2993       return GotShift;
2994 
2995     // This was not a register so parse other operands that start with an
2996     // identifier (like labels) as expressions and create them as immediates.
2997     const MCExpr *IdVal;
2998     S = getLoc();
2999     if (getParser().parseExpression(IdVal))
3000       return true;
3001     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3002     Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3003     return false;
3004   }
3005   case AsmToken::Integer:
3006   case AsmToken::Real:
3007   case AsmToken::Hash: {
3008     // #42 -> immediate.
3009     S = getLoc();
3010 
3011     parseOptionalToken(AsmToken::Hash);
3012 
3013     // Parse a negative sign
3014     bool isNegative = false;
3015     if (Parser.getTok().is(AsmToken::Minus)) {
3016       isNegative = true;
3017       // We need to consume this token only when we have a Real, otherwise
3018       // we let parseSymbolicImmVal take care of it
3019       if (Parser.getLexer().peekTok().is(AsmToken::Real))
3020         Parser.Lex();
3021     }
3022 
3023     // The only Real that should come through here is a literal #0.0 for
3024     // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3025     // so convert the value.
3026     const AsmToken &Tok = Parser.getTok();
3027     if (Tok.is(AsmToken::Real)) {
3028       APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
3029       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3030       if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3031           Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3032           Mnemonic != "fcmlt")
3033         return TokError("unexpected floating point literal");
3034       else if (IntVal != 0 || isNegative)
3035         return TokError("expected floating-point constant #0.0");
3036       Parser.Lex(); // Eat the token.
3037 
3038       Operands.push_back(
3039           AArch64Operand::CreateToken("#0", false, S, getContext()));
3040       Operands.push_back(
3041           AArch64Operand::CreateToken(".0", false, S, getContext()));
3042       return false;
3043     }
3044 
3045     const MCExpr *ImmVal;
3046     if (parseSymbolicImmVal(ImmVal))
3047       return true;
3048 
3049     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3050     Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3051     return false;
3052   }
3053   case AsmToken::Equal: {
3054     SMLoc Loc = getLoc();
3055     if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3056       return TokError("unexpected token in operand");
3057     Parser.Lex(); // Eat '='
3058     const MCExpr *SubExprVal;
3059     if (getParser().parseExpression(SubExprVal))
3060       return true;
3061 
3062     if (Operands.size() < 2 ||
3063         !static_cast<AArch64Operand &>(*Operands[1]).isReg())
3064       return Error(Loc, "Only valid when first operand is register");
3065 
3066     bool IsXReg =
3067         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3068             Operands[1]->getReg());
3069 
3070     MCContext& Ctx = getContext();
3071     E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3072     // If the op is an imm and can be fit into a mov, then replace ldr with mov.
3073     if (isa<MCConstantExpr>(SubExprVal)) {
3074       uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3075       uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3076       while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3077         ShiftAmt += 16;
3078         Imm >>= 16;
3079       }
3080       if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3081           Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3082           Operands.push_back(AArch64Operand::CreateImm(
3083                      MCConstantExpr::create(Imm, Ctx), S, E, Ctx));
3084         if (ShiftAmt)
3085           Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3086                      ShiftAmt, true, S, E, Ctx));
3087         return false;
3088       }
3089       APInt Simm = APInt(64, Imm << ShiftAmt);
3090       // check if the immediate is an unsigned or signed 32-bit int for W regs
3091       if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
3092         return Error(Loc, "Immediate too large for register");
3093     }
3094     // If it is a label or an imm that cannot fit in a movz, put it into CP.
3095     const MCExpr *CPLoc =
3096         getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
3097     Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3098     return false;
3099   }
3100   }
3101 }
3102 
3103 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3104 /// operands.
3105 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3106                                         StringRef Name, SMLoc NameLoc,
3107                                         OperandVector &Operands) {
3108   MCAsmParser &Parser = getParser();
3109   Name = StringSwitch<StringRef>(Name.lower())
3110              .Case("beq", "b.eq")
3111              .Case("bne", "b.ne")
3112              .Case("bhs", "b.hs")
3113              .Case("bcs", "b.cs")
3114              .Case("blo", "b.lo")
3115              .Case("bcc", "b.cc")
3116              .Case("bmi", "b.mi")
3117              .Case("bpl", "b.pl")
3118              .Case("bvs", "b.vs")
3119              .Case("bvc", "b.vc")
3120              .Case("bhi", "b.hi")
3121              .Case("bls", "b.ls")
3122              .Case("bge", "b.ge")
3123              .Case("blt", "b.lt")
3124              .Case("bgt", "b.gt")
3125              .Case("ble", "b.le")
3126              .Case("bal", "b.al")
3127              .Case("bnv", "b.nv")
3128              .Default(Name);
3129 
3130   // First check for the AArch64-specific .req directive.
3131   if (Parser.getTok().is(AsmToken::Identifier) &&
3132       Parser.getTok().getIdentifier() == ".req") {
3133     parseDirectiveReq(Name, NameLoc);
3134     // We always return 'error' for this, as we're done with this
3135     // statement and don't need to match the 'instruction."
3136     return true;
3137   }
3138 
3139   // Create the leading tokens for the mnemonic, split by '.' characters.
3140   size_t Start = 0, Next = Name.find('.');
3141   StringRef Head = Name.slice(Start, Next);
3142 
3143   // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3144   if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi")
3145     return parseSysAlias(Head, NameLoc, Operands);
3146 
3147   Operands.push_back(
3148       AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3149   Mnemonic = Head;
3150 
3151   // Handle condition codes for a branch mnemonic
3152   if (Head == "b" && Next != StringRef::npos) {
3153     Start = Next;
3154     Next = Name.find('.', Start + 1);
3155     Head = Name.slice(Start + 1, Next);
3156 
3157     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3158                                             (Head.data() - Name.data()));
3159     AArch64CC::CondCode CC = parseCondCodeString(Head);
3160     if (CC == AArch64CC::Invalid)
3161       return Error(SuffixLoc, "invalid condition code");
3162     Operands.push_back(
3163         AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3164     Operands.push_back(
3165         AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3166   }
3167 
3168   // Add the remaining tokens in the mnemonic.
3169   while (Next != StringRef::npos) {
3170     Start = Next;
3171     Next = Name.find('.', Start + 1);
3172     Head = Name.slice(Start, Next);
3173     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3174                                             (Head.data() - Name.data()) + 1);
3175     Operands.push_back(
3176         AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3177   }
3178 
3179   // Conditional compare instructions have a Condition Code operand, which needs
3180   // to be parsed and an immediate operand created.
3181   bool condCodeFourthOperand =
3182       (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3183        Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3184        Head == "csinc" || Head == "csinv" || Head == "csneg");
3185 
3186   // These instructions are aliases to some of the conditional select
3187   // instructions. However, the condition code is inverted in the aliased
3188   // instruction.
3189   //
3190   // FIXME: Is this the correct way to handle these? Or should the parser
3191   //        generate the aliased instructions directly?
3192   bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3193   bool condCodeThirdOperand =
3194       (Head == "cinc" || Head == "cinv" || Head == "cneg");
3195 
3196   // Read the remaining operands.
3197   if (getLexer().isNot(AsmToken::EndOfStatement)) {
3198     // Read the first operand.
3199     if (parseOperand(Operands, false, false)) {
3200       return true;
3201     }
3202 
3203     unsigned N = 2;
3204     while (parseOptionalToken(AsmToken::Comma)) {
3205       // Parse and remember the operand.
3206       if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3207                                      (N == 3 && condCodeThirdOperand) ||
3208                                      (N == 2 && condCodeSecondOperand),
3209                        condCodeSecondOperand || condCodeThirdOperand)) {
3210         return true;
3211       }
3212 
3213       // After successfully parsing some operands there are two special cases to
3214       // consider (i.e. notional operands not separated by commas). Both are due
3215       // to memory specifiers:
3216       //  + An RBrac will end an address for load/store/prefetch
3217       //  + An '!' will indicate a pre-indexed operation.
3218       //
3219       // It's someone else's responsibility to make sure these tokens are sane
3220       // in the given context!
3221 
3222       SMLoc RLoc = Parser.getTok().getLoc();
3223       if (parseOptionalToken(AsmToken::RBrac))
3224         Operands.push_back(
3225             AArch64Operand::CreateToken("]", false, RLoc, getContext()));
3226       SMLoc ELoc = Parser.getTok().getLoc();
3227       if (parseOptionalToken(AsmToken::Exclaim))
3228         Operands.push_back(
3229             AArch64Operand::CreateToken("!", false, ELoc, getContext()));
3230 
3231       ++N;
3232     }
3233   }
3234 
3235   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
3236     return true;
3237 
3238   return false;
3239 }
3240 
3241 // FIXME: This entire function is a giant hack to provide us with decent
3242 // operand range validation/diagnostics until TableGen/MC can be extended
3243 // to support autogeneration of this kind of validation.
3244 bool AArch64AsmParser::validateInstruction(MCInst &Inst,
3245                                          SmallVectorImpl<SMLoc> &Loc) {
3246   const MCRegisterInfo *RI = getContext().getRegisterInfo();
3247   // Check for indexed addressing modes w/ the base register being the
3248   // same as a destination/source register or pair load where
3249   // the Rt == Rt2. All of those are undefined behaviour.
3250   switch (Inst.getOpcode()) {
3251   case AArch64::LDPSWpre:
3252   case AArch64::LDPWpost:
3253   case AArch64::LDPWpre:
3254   case AArch64::LDPXpost:
3255   case AArch64::LDPXpre: {
3256     unsigned Rt = Inst.getOperand(1).getReg();
3257     unsigned Rt2 = Inst.getOperand(2).getReg();
3258     unsigned Rn = Inst.getOperand(3).getReg();
3259     if (RI->isSubRegisterEq(Rn, Rt))
3260       return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3261                            "is also a destination");
3262     if (RI->isSubRegisterEq(Rn, Rt2))
3263       return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3264                            "is also a destination");
3265     LLVM_FALLTHROUGH;
3266   }
3267   case AArch64::LDPDi:
3268   case AArch64::LDPQi:
3269   case AArch64::LDPSi:
3270   case AArch64::LDPSWi:
3271   case AArch64::LDPWi:
3272   case AArch64::LDPXi: {
3273     unsigned Rt = Inst.getOperand(0).getReg();
3274     unsigned Rt2 = Inst.getOperand(1).getReg();
3275     if (Rt == Rt2)
3276       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3277     break;
3278   }
3279   case AArch64::LDPDpost:
3280   case AArch64::LDPDpre:
3281   case AArch64::LDPQpost:
3282   case AArch64::LDPQpre:
3283   case AArch64::LDPSpost:
3284   case AArch64::LDPSpre:
3285   case AArch64::LDPSWpost: {
3286     unsigned Rt = Inst.getOperand(1).getReg();
3287     unsigned Rt2 = Inst.getOperand(2).getReg();
3288     if (Rt == Rt2)
3289       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3290     break;
3291   }
3292   case AArch64::STPDpost:
3293   case AArch64::STPDpre:
3294   case AArch64::STPQpost:
3295   case AArch64::STPQpre:
3296   case AArch64::STPSpost:
3297   case AArch64::STPSpre:
3298   case AArch64::STPWpost:
3299   case AArch64::STPWpre:
3300   case AArch64::STPXpost:
3301   case AArch64::STPXpre: {
3302     unsigned Rt = Inst.getOperand(1).getReg();
3303     unsigned Rt2 = Inst.getOperand(2).getReg();
3304     unsigned Rn = Inst.getOperand(3).getReg();
3305     if (RI->isSubRegisterEq(Rn, Rt))
3306       return Error(Loc[0], "unpredictable STP instruction, writeback base "
3307                            "is also a source");
3308     if (RI->isSubRegisterEq(Rn, Rt2))
3309       return Error(Loc[1], "unpredictable STP instruction, writeback base "
3310                            "is also a source");
3311     break;
3312   }
3313   case AArch64::LDRBBpre:
3314   case AArch64::LDRBpre:
3315   case AArch64::LDRHHpre:
3316   case AArch64::LDRHpre:
3317   case AArch64::LDRSBWpre:
3318   case AArch64::LDRSBXpre:
3319   case AArch64::LDRSHWpre:
3320   case AArch64::LDRSHXpre:
3321   case AArch64::LDRSWpre:
3322   case AArch64::LDRWpre:
3323   case AArch64::LDRXpre:
3324   case AArch64::LDRBBpost:
3325   case AArch64::LDRBpost:
3326   case AArch64::LDRHHpost:
3327   case AArch64::LDRHpost:
3328   case AArch64::LDRSBWpost:
3329   case AArch64::LDRSBXpost:
3330   case AArch64::LDRSHWpost:
3331   case AArch64::LDRSHXpost:
3332   case AArch64::LDRSWpost:
3333   case AArch64::LDRWpost:
3334   case AArch64::LDRXpost: {
3335     unsigned Rt = Inst.getOperand(1).getReg();
3336     unsigned Rn = Inst.getOperand(2).getReg();
3337     if (RI->isSubRegisterEq(Rn, Rt))
3338       return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3339                            "is also a source");
3340     break;
3341   }
3342   case AArch64::STRBBpost:
3343   case AArch64::STRBpost:
3344   case AArch64::STRHHpost:
3345   case AArch64::STRHpost:
3346   case AArch64::STRWpost:
3347   case AArch64::STRXpost:
3348   case AArch64::STRBBpre:
3349   case AArch64::STRBpre:
3350   case AArch64::STRHHpre:
3351   case AArch64::STRHpre:
3352   case AArch64::STRWpre:
3353   case AArch64::STRXpre: {
3354     unsigned Rt = Inst.getOperand(1).getReg();
3355     unsigned Rn = Inst.getOperand(2).getReg();
3356     if (RI->isSubRegisterEq(Rn, Rt))
3357       return Error(Loc[0], "unpredictable STR instruction, writeback base "
3358                            "is also a source");
3359     break;
3360   }
3361   }
3362 
3363   // Now check immediate ranges. Separate from the above as there is overlap
3364   // in the instructions being checked and this keeps the nested conditionals
3365   // to a minimum.
3366   switch (Inst.getOpcode()) {
3367   case AArch64::ADDSWri:
3368   case AArch64::ADDSXri:
3369   case AArch64::ADDWri:
3370   case AArch64::ADDXri:
3371   case AArch64::SUBSWri:
3372   case AArch64::SUBSXri:
3373   case AArch64::SUBWri:
3374   case AArch64::SUBXri: {
3375     // Annoyingly we can't do this in the isAddSubImm predicate, so there is
3376     // some slight duplication here.
3377     if (Inst.getOperand(2).isExpr()) {
3378       const MCExpr *Expr = Inst.getOperand(2).getExpr();
3379       AArch64MCExpr::VariantKind ELFRefKind;
3380       MCSymbolRefExpr::VariantKind DarwinRefKind;
3381       int64_t Addend;
3382       if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3383 
3384         // Only allow these with ADDXri.
3385         if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3386              DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
3387             Inst.getOpcode() == AArch64::ADDXri)
3388           return false;
3389 
3390         // Only allow these with ADDXri/ADDWri
3391         if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
3392              ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
3393              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
3394              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
3395              ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
3396              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
3397              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
3398              ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
3399             (Inst.getOpcode() == AArch64::ADDXri ||
3400              Inst.getOpcode() == AArch64::ADDWri))
3401           return false;
3402 
3403         // Don't allow symbol refs in the immediate field otherwise
3404         // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of
3405         // operands of the original instruction (i.e. 'add w0, w1, borked' vs
3406         // 'cmp w0, 'borked')
3407         return Error(Loc.back(), "invalid immediate expression");
3408       }
3409       // We don't validate more complex expressions here
3410     }
3411     return false;
3412   }
3413   default:
3414     return false;
3415   }
3416 }
3417 
3418 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
3419   switch (ErrCode) {
3420   case Match_MissingFeature:
3421     return Error(Loc,
3422                  "instruction requires a CPU feature not currently enabled");
3423   case Match_InvalidOperand:
3424     return Error(Loc, "invalid operand for instruction");
3425   case Match_InvalidSuffix:
3426     return Error(Loc, "invalid type suffix for instruction");
3427   case Match_InvalidCondCode:
3428     return Error(Loc, "expected AArch64 condition code");
3429   case Match_AddSubRegExtendSmall:
3430     return Error(Loc,
3431       "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3432   case Match_AddSubRegExtendLarge:
3433     return Error(Loc,
3434       "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3435   case Match_AddSubSecondSource:
3436     return Error(Loc,
3437       "expected compatible register, symbol or integer in range [0, 4095]");
3438   case Match_LogicalSecondSource:
3439     return Error(Loc, "expected compatible register or logical immediate");
3440   case Match_InvalidMovImm32Shift:
3441     return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
3442   case Match_InvalidMovImm64Shift:
3443     return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
3444   case Match_AddSubRegShift32:
3445     return Error(Loc,
3446        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3447   case Match_AddSubRegShift64:
3448     return Error(Loc,
3449        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3450   case Match_InvalidFPImm:
3451     return Error(Loc,
3452                  "expected compatible register or floating-point constant");
3453   case Match_InvalidMemoryIndexedSImm9:
3454     return Error(Loc, "index must be an integer in range [-256, 255].");
3455   case Match_InvalidMemoryIndexed4SImm7:
3456     return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
3457   case Match_InvalidMemoryIndexed8SImm7:
3458     return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
3459   case Match_InvalidMemoryIndexed16SImm7:
3460     return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
3461   case Match_InvalidMemoryWExtend8:
3462     return Error(Loc,
3463                  "expected 'uxtw' or 'sxtw' with optional shift of #0");
3464   case Match_InvalidMemoryWExtend16:
3465     return Error(Loc,
3466                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3467   case Match_InvalidMemoryWExtend32:
3468     return Error(Loc,
3469                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3470   case Match_InvalidMemoryWExtend64:
3471     return Error(Loc,
3472                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3473   case Match_InvalidMemoryWExtend128:
3474     return Error(Loc,
3475                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3476   case Match_InvalidMemoryXExtend8:
3477     return Error(Loc,
3478                  "expected 'lsl' or 'sxtx' with optional shift of #0");
3479   case Match_InvalidMemoryXExtend16:
3480     return Error(Loc,
3481                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3482   case Match_InvalidMemoryXExtend32:
3483     return Error(Loc,
3484                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3485   case Match_InvalidMemoryXExtend64:
3486     return Error(Loc,
3487                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3488   case Match_InvalidMemoryXExtend128:
3489     return Error(Loc,
3490                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3491   case Match_InvalidMemoryIndexed1:
3492     return Error(Loc, "index must be an integer in range [0, 4095].");
3493   case Match_InvalidMemoryIndexed2:
3494     return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
3495   case Match_InvalidMemoryIndexed4:
3496     return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
3497   case Match_InvalidMemoryIndexed8:
3498     return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
3499   case Match_InvalidMemoryIndexed16:
3500     return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
3501   case Match_InvalidImm0_1:
3502     return Error(Loc, "immediate must be an integer in range [0, 1].");
3503   case Match_InvalidImm0_7:
3504     return Error(Loc, "immediate must be an integer in range [0, 7].");
3505   case Match_InvalidImm0_15:
3506     return Error(Loc, "immediate must be an integer in range [0, 15].");
3507   case Match_InvalidImm0_31:
3508     return Error(Loc, "immediate must be an integer in range [0, 31].");
3509   case Match_InvalidImm0_63:
3510     return Error(Loc, "immediate must be an integer in range [0, 63].");
3511   case Match_InvalidImm0_127:
3512     return Error(Loc, "immediate must be an integer in range [0, 127].");
3513   case Match_InvalidImm0_255:
3514     return Error(Loc, "immediate must be an integer in range [0, 255].");
3515   case Match_InvalidImm0_65535:
3516     return Error(Loc, "immediate must be an integer in range [0, 65535].");
3517   case Match_InvalidImm1_8:
3518     return Error(Loc, "immediate must be an integer in range [1, 8].");
3519   case Match_InvalidImm1_16:
3520     return Error(Loc, "immediate must be an integer in range [1, 16].");
3521   case Match_InvalidImm1_32:
3522     return Error(Loc, "immediate must be an integer in range [1, 32].");
3523   case Match_InvalidImm1_64:
3524     return Error(Loc, "immediate must be an integer in range [1, 64].");
3525   case Match_InvalidIndex1:
3526     return Error(Loc, "expected lane specifier '[1]'");
3527   case Match_InvalidIndexB:
3528     return Error(Loc, "vector lane must be an integer in range [0, 15].");
3529   case Match_InvalidIndexH:
3530     return Error(Loc, "vector lane must be an integer in range [0, 7].");
3531   case Match_InvalidIndexS:
3532     return Error(Loc, "vector lane must be an integer in range [0, 3].");
3533   case Match_InvalidIndexD:
3534     return Error(Loc, "vector lane must be an integer in range [0, 1].");
3535   case Match_InvalidLabel:
3536     return Error(Loc, "expected label or encodable integer pc offset");
3537   case Match_MRS:
3538     return Error(Loc, "expected readable system register");
3539   case Match_MSR:
3540     return Error(Loc, "expected writable system register or pstate");
3541   case Match_MnemonicFail:
3542     return Error(Loc, "unrecognized instruction mnemonic");
3543   default:
3544     llvm_unreachable("unexpected error code!");
3545   }
3546 }
3547 
3548 static const char *getSubtargetFeatureName(uint64_t Val);
3549 
3550 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3551                                                OperandVector &Operands,
3552                                                MCStreamer &Out,
3553                                                uint64_t &ErrorInfo,
3554                                                bool MatchingInlineAsm) {
3555   assert(!Operands.empty() && "Unexpect empty operand list!");
3556   AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
3557   assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3558 
3559   StringRef Tok = Op.getToken();
3560   unsigned NumOperands = Operands.size();
3561 
3562   if (NumOperands == 4 && Tok == "lsl") {
3563     AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
3564     AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3565     if (Op2.isReg() && Op3.isImm()) {
3566       const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3567       if (Op3CE) {
3568         uint64_t Op3Val = Op3CE->getValue();
3569         uint64_t NewOp3Val = 0;
3570         uint64_t NewOp4Val = 0;
3571         if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
3572                 Op2.getReg())) {
3573           NewOp3Val = (32 - Op3Val) & 0x1f;
3574           NewOp4Val = 31 - Op3Val;
3575         } else {
3576           NewOp3Val = (64 - Op3Val) & 0x3f;
3577           NewOp4Val = 63 - Op3Val;
3578         }
3579 
3580         const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext());
3581         const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext());
3582 
3583         Operands[0] = AArch64Operand::CreateToken(
3584             "ubfm", false, Op.getStartLoc(), getContext());
3585         Operands.push_back(AArch64Operand::CreateImm(
3586             NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3587         Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3588                                                 Op3.getEndLoc(), getContext());
3589       }
3590     }
3591   } else if (NumOperands == 4 && Tok == "bfc") {
3592     // FIXME: Horrible hack to handle BFC->BFM alias.
3593     AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3594     AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]);
3595     AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]);
3596 
3597     if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) {
3598       const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
3599       const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
3600 
3601       if (LSBCE && WidthCE) {
3602         uint64_t LSB = LSBCE->getValue();
3603         uint64_t Width = WidthCE->getValue();
3604 
3605         uint64_t RegWidth = 0;
3606         if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3607                 Op1.getReg()))
3608           RegWidth = 64;
3609         else
3610           RegWidth = 32;
3611 
3612         if (LSB >= RegWidth)
3613           return Error(LSBOp.getStartLoc(),
3614                        "expected integer in range [0, 31]");
3615         if (Width < 1 || Width > RegWidth)
3616           return Error(WidthOp.getStartLoc(),
3617                        "expected integer in range [1, 32]");
3618 
3619         uint64_t ImmR = 0;
3620         if (RegWidth == 32)
3621           ImmR = (32 - LSB) & 0x1f;
3622         else
3623           ImmR = (64 - LSB) & 0x3f;
3624 
3625         uint64_t ImmS = Width - 1;
3626 
3627         if (ImmR != 0 && ImmS >= ImmR)
3628           return Error(WidthOp.getStartLoc(),
3629                        "requested insert overflows register");
3630 
3631         const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext());
3632         const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext());
3633         Operands[0] = AArch64Operand::CreateToken(
3634               "bfm", false, Op.getStartLoc(), getContext());
3635         Operands[2] = AArch64Operand::CreateReg(
3636             RegWidth == 32 ? AArch64::WZR : AArch64::XZR, false, SMLoc(),
3637             SMLoc(), getContext());
3638         Operands[3] = AArch64Operand::CreateImm(
3639             ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
3640         Operands.emplace_back(
3641             AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
3642                                       WidthOp.getEndLoc(), getContext()));
3643       }
3644     }
3645   } else if (NumOperands == 5) {
3646     // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
3647     // UBFIZ -> UBFM aliases.
3648     if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
3649       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3650       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3651       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3652 
3653       if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3654         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3655         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3656 
3657         if (Op3CE && Op4CE) {
3658           uint64_t Op3Val = Op3CE->getValue();
3659           uint64_t Op4Val = Op4CE->getValue();
3660 
3661           uint64_t RegWidth = 0;
3662           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3663                   Op1.getReg()))
3664             RegWidth = 64;
3665           else
3666             RegWidth = 32;
3667 
3668           if (Op3Val >= RegWidth)
3669             return Error(Op3.getStartLoc(),
3670                          "expected integer in range [0, 31]");
3671           if (Op4Val < 1 || Op4Val > RegWidth)
3672             return Error(Op4.getStartLoc(),
3673                          "expected integer in range [1, 32]");
3674 
3675           uint64_t NewOp3Val = 0;
3676           if (RegWidth == 32)
3677             NewOp3Val = (32 - Op3Val) & 0x1f;
3678           else
3679             NewOp3Val = (64 - Op3Val) & 0x3f;
3680 
3681           uint64_t NewOp4Val = Op4Val - 1;
3682 
3683           if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
3684             return Error(Op4.getStartLoc(),
3685                          "requested insert overflows register");
3686 
3687           const MCExpr *NewOp3 =
3688               MCConstantExpr::create(NewOp3Val, getContext());
3689           const MCExpr *NewOp4 =
3690               MCConstantExpr::create(NewOp4Val, getContext());
3691           Operands[3] = AArch64Operand::CreateImm(
3692               NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
3693           Operands[4] = AArch64Operand::CreateImm(
3694               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3695           if (Tok == "bfi")
3696             Operands[0] = AArch64Operand::CreateToken(
3697                 "bfm", false, Op.getStartLoc(), getContext());
3698           else if (Tok == "sbfiz")
3699             Operands[0] = AArch64Operand::CreateToken(
3700                 "sbfm", false, Op.getStartLoc(), getContext());
3701           else if (Tok == "ubfiz")
3702             Operands[0] = AArch64Operand::CreateToken(
3703                 "ubfm", false, Op.getStartLoc(), getContext());
3704           else
3705             llvm_unreachable("No valid mnemonic for alias?");
3706         }
3707       }
3708 
3709       // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
3710       // UBFX -> UBFM aliases.
3711     } else if (NumOperands == 5 &&
3712                (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
3713       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3714       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3715       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3716 
3717       if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3718         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3719         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3720 
3721         if (Op3CE && Op4CE) {
3722           uint64_t Op3Val = Op3CE->getValue();
3723           uint64_t Op4Val = Op4CE->getValue();
3724 
3725           uint64_t RegWidth = 0;
3726           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3727                   Op1.getReg()))
3728             RegWidth = 64;
3729           else
3730             RegWidth = 32;
3731 
3732           if (Op3Val >= RegWidth)
3733             return Error(Op3.getStartLoc(),
3734                          "expected integer in range [0, 31]");
3735           if (Op4Val < 1 || Op4Val > RegWidth)
3736             return Error(Op4.getStartLoc(),
3737                          "expected integer in range [1, 32]");
3738 
3739           uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3740 
3741           if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
3742             return Error(Op4.getStartLoc(),
3743                          "requested extract overflows register");
3744 
3745           const MCExpr *NewOp4 =
3746               MCConstantExpr::create(NewOp4Val, getContext());
3747           Operands[4] = AArch64Operand::CreateImm(
3748               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3749           if (Tok == "bfxil")
3750             Operands[0] = AArch64Operand::CreateToken(
3751                 "bfm", false, Op.getStartLoc(), getContext());
3752           else if (Tok == "sbfx")
3753             Operands[0] = AArch64Operand::CreateToken(
3754                 "sbfm", false, Op.getStartLoc(), getContext());
3755           else if (Tok == "ubfx")
3756             Operands[0] = AArch64Operand::CreateToken(
3757                 "ubfm", false, Op.getStartLoc(), getContext());
3758           else
3759             llvm_unreachable("No valid mnemonic for alias?");
3760         }
3761       }
3762     }
3763   }
3764   // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
3765   //        InstAlias can't quite handle this since the reg classes aren't
3766   //        subclasses.
3767   if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
3768     // The source register can be Wn here, but the matcher expects a
3769     // GPR64. Twiddle it here if necessary.
3770     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3771     if (Op.isReg()) {
3772       unsigned Reg = getXRegFromWReg(Op.getReg());
3773       Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3774                                               Op.getEndLoc(), getContext());
3775     }
3776   }
3777   // FIXME: Likewise for sxt[bh] with a Xd dst operand
3778   else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
3779     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3780     if (Op.isReg() &&
3781         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3782             Op.getReg())) {
3783       // The source register can be Wn here, but the matcher expects a
3784       // GPR64. Twiddle it here if necessary.
3785       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3786       if (Op.isReg()) {
3787         unsigned Reg = getXRegFromWReg(Op.getReg());
3788         Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3789                                                 Op.getEndLoc(), getContext());
3790       }
3791     }
3792   }
3793   // FIXME: Likewise for uxt[bh] with a Xd dst operand
3794   else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
3795     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3796     if (Op.isReg() &&
3797         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3798             Op.getReg())) {
3799       // The source register can be Wn here, but the matcher expects a
3800       // GPR32. Twiddle it here if necessary.
3801       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3802       if (Op.isReg()) {
3803         unsigned Reg = getWRegFromXReg(Op.getReg());
3804         Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3805                                                 Op.getEndLoc(), getContext());
3806       }
3807     }
3808   }
3809 
3810   // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
3811   if (NumOperands == 3 && Tok == "fmov") {
3812     AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
3813     AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
3814     if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
3815       unsigned zreg =
3816           !AArch64MCRegisterClasses[AArch64::FPR64RegClassID].contains(
3817               RegOp.getReg())
3818               ? AArch64::WZR
3819               : AArch64::XZR;
3820       Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
3821                                               Op.getEndLoc(), getContext());
3822     }
3823   }
3824 
3825   MCInst Inst;
3826   // First try to match against the secondary set of tables containing the
3827   // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
3828   unsigned MatchResult =
3829       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3830 
3831   // If that fails, try against the alternate table containing long-form NEON:
3832   // "fadd v0.2s, v1.2s, v2.2s"
3833   if (MatchResult != Match_Success) {
3834     // But first, save the short-form match result: we can use it in case the
3835     // long-form match also fails.
3836     auto ShortFormNEONErrorInfo = ErrorInfo;
3837     auto ShortFormNEONMatchResult = MatchResult;
3838 
3839     MatchResult =
3840         MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3841 
3842     // Now, both matches failed, and the long-form match failed on the mnemonic
3843     // suffix token operand.  The short-form match failure is probably more
3844     // relevant: use it instead.
3845     if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
3846         Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
3847         ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
3848       MatchResult = ShortFormNEONMatchResult;
3849       ErrorInfo = ShortFormNEONErrorInfo;
3850     }
3851   }
3852 
3853   switch (MatchResult) {
3854   case Match_Success: {
3855     // Perform range checking and other semantic validations
3856     SmallVector<SMLoc, 8> OperandLocs;
3857     NumOperands = Operands.size();
3858     for (unsigned i = 1; i < NumOperands; ++i)
3859       OperandLocs.push_back(Operands[i]->getStartLoc());
3860     if (validateInstruction(Inst, OperandLocs))
3861       return true;
3862 
3863     Inst.setLoc(IDLoc);
3864     Out.EmitInstruction(Inst, getSTI());
3865     return false;
3866   }
3867   case Match_MissingFeature: {
3868     assert(ErrorInfo && "Unknown missing feature!");
3869     // Special case the error message for the very common case where only
3870     // a single subtarget feature is missing (neon, e.g.).
3871     std::string Msg = "instruction requires:";
3872     uint64_t Mask = 1;
3873     for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
3874       if (ErrorInfo & Mask) {
3875         Msg += " ";
3876         Msg += getSubtargetFeatureName(ErrorInfo & Mask);
3877       }
3878       Mask <<= 1;
3879     }
3880     return Error(IDLoc, Msg);
3881   }
3882   case Match_MnemonicFail:
3883     return showMatchError(IDLoc, MatchResult);
3884   case Match_InvalidOperand: {
3885     SMLoc ErrorLoc = IDLoc;
3886 
3887     if (ErrorInfo != ~0ULL) {
3888       if (ErrorInfo >= Operands.size())
3889         return Error(IDLoc, "too few operands for instruction",
3890                      SMRange(IDLoc, getTok().getLoc()));
3891 
3892       ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3893       if (ErrorLoc == SMLoc())
3894         ErrorLoc = IDLoc;
3895     }
3896     // If the match failed on a suffix token operand, tweak the diagnostic
3897     // accordingly.
3898     if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3899         ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
3900       MatchResult = Match_InvalidSuffix;
3901 
3902     return showMatchError(ErrorLoc, MatchResult);
3903   }
3904   case Match_InvalidMemoryIndexed1:
3905   case Match_InvalidMemoryIndexed2:
3906   case Match_InvalidMemoryIndexed4:
3907   case Match_InvalidMemoryIndexed8:
3908   case Match_InvalidMemoryIndexed16:
3909   case Match_InvalidCondCode:
3910   case Match_AddSubRegExtendSmall:
3911   case Match_AddSubRegExtendLarge:
3912   case Match_AddSubSecondSource:
3913   case Match_LogicalSecondSource:
3914   case Match_AddSubRegShift32:
3915   case Match_AddSubRegShift64:
3916   case Match_InvalidMovImm32Shift:
3917   case Match_InvalidMovImm64Shift:
3918   case Match_InvalidFPImm:
3919   case Match_InvalidMemoryWExtend8:
3920   case Match_InvalidMemoryWExtend16:
3921   case Match_InvalidMemoryWExtend32:
3922   case Match_InvalidMemoryWExtend64:
3923   case Match_InvalidMemoryWExtend128:
3924   case Match_InvalidMemoryXExtend8:
3925   case Match_InvalidMemoryXExtend16:
3926   case Match_InvalidMemoryXExtend32:
3927   case Match_InvalidMemoryXExtend64:
3928   case Match_InvalidMemoryXExtend128:
3929   case Match_InvalidMemoryIndexed4SImm7:
3930   case Match_InvalidMemoryIndexed8SImm7:
3931   case Match_InvalidMemoryIndexed16SImm7:
3932   case Match_InvalidMemoryIndexedSImm9:
3933   case Match_InvalidImm0_1:
3934   case Match_InvalidImm0_7:
3935   case Match_InvalidImm0_15:
3936   case Match_InvalidImm0_31:
3937   case Match_InvalidImm0_63:
3938   case Match_InvalidImm0_127:
3939   case Match_InvalidImm0_255:
3940   case Match_InvalidImm0_65535:
3941   case Match_InvalidImm1_8:
3942   case Match_InvalidImm1_16:
3943   case Match_InvalidImm1_32:
3944   case Match_InvalidImm1_64:
3945   case Match_InvalidIndex1:
3946   case Match_InvalidIndexB:
3947   case Match_InvalidIndexH:
3948   case Match_InvalidIndexS:
3949   case Match_InvalidIndexD:
3950   case Match_InvalidLabel:
3951   case Match_MSR:
3952   case Match_MRS: {
3953     if (ErrorInfo >= Operands.size())
3954       return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc()));
3955     // Any time we get here, there's nothing fancy to do. Just get the
3956     // operand SMLoc and display the diagnostic.
3957     SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3958     if (ErrorLoc == SMLoc())
3959       ErrorLoc = IDLoc;
3960     return showMatchError(ErrorLoc, MatchResult);
3961   }
3962   }
3963 
3964   llvm_unreachable("Implement any new match types added!");
3965 }
3966 
3967 /// ParseDirective parses the arm specific directives
3968 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
3969   const MCObjectFileInfo::Environment Format =
3970     getContext().getObjectFileInfo()->getObjectFileType();
3971   bool IsMachO = Format == MCObjectFileInfo::IsMachO;
3972   bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
3973 
3974   StringRef IDVal = DirectiveID.getIdentifier();
3975   SMLoc Loc = DirectiveID.getLoc();
3976   if (IDVal == ".arch")
3977     parseDirectiveArch(Loc);
3978   else if (IDVal == ".cpu")
3979     parseDirectiveCPU(Loc);
3980   else if (IDVal == ".hword")
3981     parseDirectiveWord(2, Loc);
3982   else if (IDVal == ".word")
3983     parseDirectiveWord(4, Loc);
3984   else if (IDVal == ".xword")
3985     parseDirectiveWord(8, Loc);
3986   else if (IDVal == ".tlsdesccall")
3987     parseDirectiveTLSDescCall(Loc);
3988   else if (IDVal == ".ltorg" || IDVal == ".pool")
3989     parseDirectiveLtorg(Loc);
3990   else if (IDVal == ".unreq")
3991     parseDirectiveUnreq(Loc);
3992   else if (!IsMachO && !IsCOFF) {
3993     if (IDVal == ".inst")
3994       parseDirectiveInst(Loc);
3995     else
3996       return true;
3997   } else if (IDVal == MCLOHDirectiveName())
3998     parseDirectiveLOH(IDVal, Loc);
3999   else
4000     return true;
4001   return false;
4002 }
4003 
4004 static const struct {
4005   const char *Name;
4006   const FeatureBitset Features;
4007 } ExtensionMap[] = {
4008   { "crc", {AArch64::FeatureCRC} },
4009   { "crypto", {AArch64::FeatureCrypto} },
4010   { "fp", {AArch64::FeatureFPARMv8} },
4011   { "simd", {AArch64::FeatureNEON} },
4012   { "ras", {AArch64::FeatureRAS} },
4013   { "lse", {AArch64::FeatureLSE} },
4014 
4015   // FIXME: Unsupported extensions
4016   { "pan", {} },
4017   { "lor", {} },
4018   { "rdma", {} },
4019   { "profile", {} },
4020 };
4021 
4022 /// parseDirectiveArch
4023 ///   ::= .arch token
4024 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
4025   SMLoc ArchLoc = getLoc();
4026 
4027   StringRef Arch, ExtensionString;
4028   std::tie(Arch, ExtensionString) =
4029       getParser().parseStringToEndOfStatement().trim().split('+');
4030 
4031   unsigned ID = AArch64::parseArch(Arch);
4032   if (ID == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
4033     return Error(ArchLoc, "unknown arch name");
4034 
4035   if (parseToken(AsmToken::EndOfStatement))
4036     return true;
4037 
4038   // Get the architecture and extension features.
4039   std::vector<StringRef> AArch64Features;
4040   AArch64::getArchFeatures(ID, AArch64Features);
4041   AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID),
4042                                 AArch64Features);
4043 
4044   MCSubtargetInfo &STI = copySTI();
4045   std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
4046   STI.setDefaultFeatures("generic", join(ArchFeatures.begin(), ArchFeatures.end(), ","));
4047 
4048   SmallVector<StringRef, 4> RequestedExtensions;
4049   if (!ExtensionString.empty())
4050     ExtensionString.split(RequestedExtensions, '+');
4051 
4052   FeatureBitset Features = STI.getFeatureBits();
4053   for (auto Name : RequestedExtensions) {
4054     bool EnableFeature = true;
4055 
4056     if (Name.startswith_lower("no")) {
4057       EnableFeature = false;
4058       Name = Name.substr(2);
4059     }
4060 
4061     for (const auto &Extension : ExtensionMap) {
4062       if (Extension.Name != Name)
4063         continue;
4064 
4065       if (Extension.Features.none())
4066         report_fatal_error("unsupported architectural extension: " + Name);
4067 
4068       FeatureBitset ToggleFeatures = EnableFeature
4069                                          ? (~Features & Extension.Features)
4070                                          : ( Features & Extension.Features);
4071       uint64_t Features =
4072           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
4073       setAvailableFeatures(Features);
4074       break;
4075     }
4076   }
4077   return false;
4078 }
4079 
4080 /// parseDirectiveCPU
4081 ///   ::= .cpu id
4082 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
4083   SMLoc CPULoc = getLoc();
4084 
4085   StringRef CPU, ExtensionString;
4086   std::tie(CPU, ExtensionString) =
4087       getParser().parseStringToEndOfStatement().trim().split('+');
4088 
4089   if (parseToken(AsmToken::EndOfStatement))
4090     return true;
4091 
4092   SmallVector<StringRef, 4> RequestedExtensions;
4093   if (!ExtensionString.empty())
4094     ExtensionString.split(RequestedExtensions, '+');
4095 
4096   // FIXME This is using tablegen data, but should be moved to ARMTargetParser
4097   // once that is tablegen'ed
4098   if (!getSTI().isCPUStringValid(CPU)) {
4099     Error(CPULoc, "unknown CPU name");
4100     return false;
4101   }
4102 
4103   MCSubtargetInfo &STI = copySTI();
4104   STI.setDefaultFeatures(CPU, "");
4105 
4106   FeatureBitset Features = STI.getFeatureBits();
4107   for (auto Name : RequestedExtensions) {
4108     bool EnableFeature = true;
4109 
4110     if (Name.startswith_lower("no")) {
4111       EnableFeature = false;
4112       Name = Name.substr(2);
4113     }
4114 
4115     for (const auto &Extension : ExtensionMap) {
4116       if (Extension.Name != Name)
4117         continue;
4118 
4119       if (Extension.Features.none())
4120         report_fatal_error("unsupported architectural extension: " + Name);
4121 
4122       FeatureBitset ToggleFeatures = EnableFeature
4123                                          ? (~Features & Extension.Features)
4124                                          : ( Features & Extension.Features);
4125       uint64_t Features =
4126           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
4127       setAvailableFeatures(Features);
4128 
4129       break;
4130     }
4131   }
4132   return false;
4133 }
4134 
4135 /// parseDirectiveWord
4136 ///  ::= .word [ expression (, expression)* ]
4137 bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4138   auto parseOp = [&]() -> bool {
4139     const MCExpr *Value;
4140     if (getParser().parseExpression(Value))
4141       return true;
4142     getParser().getStreamer().EmitValue(Value, Size, L);
4143     return false;
4144   };
4145 
4146   if (parseMany(parseOp))
4147     return true;
4148   return false;
4149 }
4150 
4151 /// parseDirectiveInst
4152 ///  ::= .inst opcode [, ...]
4153 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
4154   if (getLexer().is(AsmToken::EndOfStatement))
4155     return Error(Loc, "expected expression following '.inst' directive");
4156 
4157   auto parseOp = [&]() -> bool {
4158     SMLoc L = getLoc();
4159     const MCExpr *Expr;
4160     if (check(getParser().parseExpression(Expr), L, "expected expression"))
4161       return true;
4162     const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4163     if (check(!Value, L, "expected constant expression"))
4164       return true;
4165     getTargetStreamer().emitInst(Value->getValue());
4166     return false;
4167   };
4168 
4169   if (parseMany(parseOp))
4170     return addErrorSuffix(" in '.inst' directive");
4171   return false;
4172 }
4173 
4174 // parseDirectiveTLSDescCall:
4175 //   ::= .tlsdesccall symbol
4176 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
4177   StringRef Name;
4178   if (check(getParser().parseIdentifier(Name), L,
4179             "expected symbol after directive") ||
4180       parseToken(AsmToken::EndOfStatement))
4181     return true;
4182 
4183   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4184   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
4185   Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
4186 
4187   MCInst Inst;
4188   Inst.setOpcode(AArch64::TLSDESCCALL);
4189   Inst.addOperand(MCOperand::createExpr(Expr));
4190 
4191   getParser().getStreamer().EmitInstruction(Inst, getSTI());
4192   return false;
4193 }
4194 
4195 /// ::= .loh <lohName | lohId> label1, ..., labelN
4196 /// The number of arguments depends on the loh identifier.
4197 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
4198   MCLOHType Kind;
4199   if (getParser().getTok().isNot(AsmToken::Identifier)) {
4200     if (getParser().getTok().isNot(AsmToken::Integer))
4201       return TokError("expected an identifier or a number in directive");
4202     // We successfully get a numeric value for the identifier.
4203     // Check if it is valid.
4204     int64_t Id = getParser().getTok().getIntVal();
4205     if (Id <= -1U && !isValidMCLOHType(Id))
4206       return TokError("invalid numeric identifier in directive");
4207     Kind = (MCLOHType)Id;
4208   } else {
4209     StringRef Name = getTok().getIdentifier();
4210     // We successfully parse an identifier.
4211     // Check if it is a recognized one.
4212     int Id = MCLOHNameToId(Name);
4213 
4214     if (Id == -1)
4215       return TokError("invalid identifier in directive");
4216     Kind = (MCLOHType)Id;
4217   }
4218   // Consume the identifier.
4219   Lex();
4220   // Get the number of arguments of this LOH.
4221   int NbArgs = MCLOHIdToNbArgs(Kind);
4222 
4223   assert(NbArgs != -1 && "Invalid number of arguments");
4224 
4225   SmallVector<MCSymbol *, 3> Args;
4226   for (int Idx = 0; Idx < NbArgs; ++Idx) {
4227     StringRef Name;
4228     if (getParser().parseIdentifier(Name))
4229       return TokError("expected identifier in directive");
4230     Args.push_back(getContext().getOrCreateSymbol(Name));
4231 
4232     if (Idx + 1 == NbArgs)
4233       break;
4234     if (parseToken(AsmToken::Comma,
4235                    "unexpected token in '" + Twine(IDVal) + "' directive"))
4236       return true;
4237   }
4238   if (parseToken(AsmToken::EndOfStatement,
4239                  "unexpected token in '" + Twine(IDVal) + "' directive"))
4240     return true;
4241 
4242   getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4243   return false;
4244 }
4245 
4246 /// parseDirectiveLtorg
4247 ///  ::= .ltorg | .pool
4248 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
4249   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
4250     return true;
4251   getTargetStreamer().emitCurrentConstantPool();
4252   return false;
4253 }
4254 
4255 /// parseDirectiveReq
4256 ///  ::= name .req registername
4257 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
4258   MCAsmParser &Parser = getParser();
4259   Parser.Lex(); // Eat the '.req' token.
4260   SMLoc SRegLoc = getLoc();
4261   unsigned RegNum = tryParseRegister();
4262   bool IsVector = false;
4263 
4264   if (RegNum == static_cast<unsigned>(-1)) {
4265     StringRef Kind;
4266     RegNum = tryMatchVectorRegister(Kind, false);
4267     if (!Kind.empty())
4268       return Error(SRegLoc, "vector register without type specifier expected");
4269     IsVector = true;
4270   }
4271 
4272   if (RegNum == static_cast<unsigned>(-1))
4273     return Error(SRegLoc, "register name or alias expected");
4274 
4275   // Shouldn't be anything else.
4276   if (parseToken(AsmToken::EndOfStatement,
4277                  "unexpected input in .req directive"))
4278     return true;
4279 
4280   auto pair = std::make_pair(IsVector, RegNum);
4281   if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
4282     Warning(L, "ignoring redefinition of register alias '" + Name + "'");
4283 
4284   return false;
4285 }
4286 
4287 /// parseDirectiveUneq
4288 ///  ::= .unreq registername
4289 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
4290   MCAsmParser &Parser = getParser();
4291   if (getTok().isNot(AsmToken::Identifier))
4292     return TokError("unexpected input in .unreq directive.");
4293   RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
4294   Parser.Lex(); // Eat the identifier.
4295   if (parseToken(AsmToken::EndOfStatement))
4296     return addErrorSuffix("in '.unreq' directive");
4297   return false;
4298 }
4299 
4300 bool
4301 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
4302                                     AArch64MCExpr::VariantKind &ELFRefKind,
4303                                     MCSymbolRefExpr::VariantKind &DarwinRefKind,
4304                                     int64_t &Addend) {
4305   ELFRefKind = AArch64MCExpr::VK_INVALID;
4306   DarwinRefKind = MCSymbolRefExpr::VK_None;
4307   Addend = 0;
4308 
4309   if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4310     ELFRefKind = AE->getKind();
4311     Expr = AE->getSubExpr();
4312   }
4313 
4314   const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4315   if (SE) {
4316     // It's a simple symbol reference with no addend.
4317     DarwinRefKind = SE->getKind();
4318     return true;
4319   }
4320 
4321   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4322   if (!BE)
4323     return false;
4324 
4325   SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4326   if (!SE)
4327     return false;
4328   DarwinRefKind = SE->getKind();
4329 
4330   if (BE->getOpcode() != MCBinaryExpr::Add &&
4331       BE->getOpcode() != MCBinaryExpr::Sub)
4332     return false;
4333 
4334   // See if the addend is is a constant, otherwise there's more going
4335   // on here than we can deal with.
4336   auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
4337   if (!AddendExpr)
4338     return false;
4339 
4340   Addend = AddendExpr->getValue();
4341   if (BE->getOpcode() == MCBinaryExpr::Sub)
4342     Addend = -Addend;
4343 
4344   // It's some symbol reference + a constant addend, but really
4345   // shouldn't use both Darwin and ELF syntax.
4346   return ELFRefKind == AArch64MCExpr::VK_INVALID ||
4347          DarwinRefKind == MCSymbolRefExpr::VK_None;
4348 }
4349 
4350 /// Force static initialization.
4351 extern "C" void LLVMInitializeAArch64AsmParser() {
4352   RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget());
4353   RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget());
4354   RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target());
4355 }
4356 
4357 #define GET_REGISTER_MATCHER
4358 #define GET_SUBTARGET_FEATURE_NAME
4359 #define GET_MATCHER_IMPLEMENTATION
4360 #include "AArch64GenAsmMatcher.inc"
4361 
4362 // Define this matcher function after the auto-generated include so we
4363 // have the match class enum definitions.
4364 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
4365                                                       unsigned Kind) {
4366   AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
4367   // If the kind is a token for a literal immediate, check if our asm
4368   // operand matches. This is for InstAliases which have a fixed-value
4369   // immediate in the syntax.
4370   int64_t ExpectedVal;
4371   switch (Kind) {
4372   default:
4373     return Match_InvalidOperand;
4374   case MCK__35_0:
4375     ExpectedVal = 0;
4376     break;
4377   case MCK__35_1:
4378     ExpectedVal = 1;
4379     break;
4380   case MCK__35_12:
4381     ExpectedVal = 12;
4382     break;
4383   case MCK__35_16:
4384     ExpectedVal = 16;
4385     break;
4386   case MCK__35_2:
4387     ExpectedVal = 2;
4388     break;
4389   case MCK__35_24:
4390     ExpectedVal = 24;
4391     break;
4392   case MCK__35_3:
4393     ExpectedVal = 3;
4394     break;
4395   case MCK__35_32:
4396     ExpectedVal = 32;
4397     break;
4398   case MCK__35_4:
4399     ExpectedVal = 4;
4400     break;
4401   case MCK__35_48:
4402     ExpectedVal = 48;
4403     break;
4404   case MCK__35_6:
4405     ExpectedVal = 6;
4406     break;
4407   case MCK__35_64:
4408     ExpectedVal = 64;
4409     break;
4410   case MCK__35_8:
4411     ExpectedVal = 8;
4412     break;
4413   }
4414   if (!Op.isImm())
4415     return Match_InvalidOperand;
4416   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
4417   if (!CE)
4418     return Match_InvalidOperand;
4419   if (CE->getValue() == ExpectedVal)
4420     return Match_Success;
4421   return Match_InvalidOperand;
4422 }
4423 
4424 OperandMatchResultTy
4425 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
4426 
4427   SMLoc S = getLoc();
4428 
4429   if (getParser().getTok().isNot(AsmToken::Identifier)) {
4430     Error(S, "expected register");
4431     return MatchOperand_ParseFail;
4432   }
4433 
4434   int FirstReg = tryParseRegister();
4435   if (FirstReg == -1) {
4436     return MatchOperand_ParseFail;
4437   }
4438   const MCRegisterClass &WRegClass =
4439       AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
4440   const MCRegisterClass &XRegClass =
4441       AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
4442 
4443   bool isXReg = XRegClass.contains(FirstReg),
4444        isWReg = WRegClass.contains(FirstReg);
4445   if (!isXReg && !isWReg) {
4446     Error(S, "expected first even register of a "
4447              "consecutive same-size even/odd register pair");
4448     return MatchOperand_ParseFail;
4449   }
4450 
4451   const MCRegisterInfo *RI = getContext().getRegisterInfo();
4452   unsigned FirstEncoding = RI->getEncodingValue(FirstReg);
4453 
4454   if (FirstEncoding & 0x1) {
4455     Error(S, "expected first even register of a "
4456              "consecutive same-size even/odd register pair");
4457     return MatchOperand_ParseFail;
4458   }
4459 
4460   SMLoc M = getLoc();
4461   if (getParser().getTok().isNot(AsmToken::Comma)) {
4462     Error(M, "expected comma");
4463     return MatchOperand_ParseFail;
4464   }
4465   // Eat the comma
4466   getParser().Lex();
4467 
4468   SMLoc E = getLoc();
4469   int SecondReg = tryParseRegister();
4470   if (SecondReg ==-1) {
4471     return MatchOperand_ParseFail;
4472   }
4473 
4474   if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 ||
4475       (isXReg && !XRegClass.contains(SecondReg)) ||
4476       (isWReg && !WRegClass.contains(SecondReg))) {
4477     Error(E,"expected second odd register of a "
4478              "consecutive same-size even/odd register pair");
4479     return MatchOperand_ParseFail;
4480   }
4481 
4482   unsigned Pair = 0;
4483   if (isXReg) {
4484     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64,
4485            &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
4486   } else {
4487     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32,
4488            &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
4489   }
4490 
4491   Operands.push_back(AArch64Operand::CreateReg(Pair, false, S, getLoc(),
4492       getContext()));
4493 
4494   return MatchOperand_Success;
4495 }
4496