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   MCAsmParser &Parser = getParser();
2727   SMLoc S = getLoc();
2728   // Try for a vector register.
2729   if (!tryParseVectorRegister(Operands))
2730     return false;
2731 
2732   // Try for a scalar register.
2733   int64_t Reg = tryParseRegister();
2734   if (Reg == -1)
2735     return true;
2736   Operands.push_back(
2737       AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
2738 
2739   // A small number of instructions (FMOVXDhighr, for example) have "[1]"
2740   // as a string token in the instruction itself.
2741   SMLoc LBracS = getLoc();
2742   const AsmToken &Tok = Parser.getTok();
2743   if (parseOptionalToken(AsmToken::LBrac)) {
2744     if (Tok.is(AsmToken::Integer)) {
2745       SMLoc IntS = getLoc();
2746       int64_t Val = Tok.getIntVal();
2747       if (Val == 1) {
2748         Parser.Lex();
2749         SMLoc RBracS = getLoc();
2750         if (parseOptionalToken(AsmToken::RBrac)) {
2751           Operands.push_back(
2752               AArch64Operand::CreateToken("[", false, LBracS, getContext()));
2753           Operands.push_back(
2754               AArch64Operand::CreateToken("1", false, IntS, getContext()));
2755           Operands.push_back(
2756               AArch64Operand::CreateToken("]", false, RBracS, getContext()));
2757           return false;
2758         }
2759       }
2760     }
2761   }
2762 
2763   return false;
2764 }
2765 
2766 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
2767   MCAsmParser &Parser = getParser();
2768   bool HasELFModifier = false;
2769   AArch64MCExpr::VariantKind RefKind;
2770 
2771   if (parseOptionalToken(AsmToken::Colon)) {
2772     HasELFModifier = true;
2773 
2774     if (Parser.getTok().isNot(AsmToken::Identifier))
2775       return TokError("expect relocation specifier in operand after ':'");
2776 
2777     std::string LowerCase = Parser.getTok().getIdentifier().lower();
2778     RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
2779                   .Case("lo12", AArch64MCExpr::VK_LO12)
2780                   .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
2781                   .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
2782                   .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
2783                   .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
2784                   .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
2785                   .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
2786                   .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
2787                   .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
2788                   .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
2789                   .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
2790                   .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
2791                   .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
2792                   .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
2793                   .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
2794                   .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
2795                   .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
2796                   .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
2797                   .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
2798                   .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
2799                   .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
2800                   .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
2801                   .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
2802                   .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
2803                   .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
2804                   .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
2805                   .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
2806                   .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
2807                   .Case("got", AArch64MCExpr::VK_GOT_PAGE)
2808                   .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
2809                   .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
2810                   .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
2811                   .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
2812                   .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
2813                   .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
2814                   .Default(AArch64MCExpr::VK_INVALID);
2815 
2816     if (RefKind == AArch64MCExpr::VK_INVALID)
2817       return TokError("expect relocation specifier in operand after ':'");
2818 
2819     Parser.Lex(); // Eat identifier
2820 
2821     if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier"))
2822       return true;
2823   }
2824 
2825   if (getParser().parseExpression(ImmVal))
2826     return true;
2827 
2828   if (HasELFModifier)
2829     ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext());
2830 
2831   return false;
2832 }
2833 
2834 /// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
2835 bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
2836   MCAsmParser &Parser = getParser();
2837   assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
2838   SMLoc S = getLoc();
2839   Parser.Lex(); // Eat left bracket token.
2840   StringRef Kind;
2841   int64_t FirstReg = tryMatchVectorRegister(Kind, true);
2842   if (FirstReg == -1)
2843     return true;
2844   int64_t PrevReg = FirstReg;
2845   unsigned Count = 1;
2846 
2847   if (parseOptionalToken(AsmToken::Minus)) {
2848     SMLoc Loc = getLoc();
2849     StringRef NextKind;
2850     int64_t Reg = tryMatchVectorRegister(NextKind, true);
2851     if (Reg == -1)
2852       return true;
2853     // Any Kind suffices must match on all regs in the list.
2854     if (Kind != NextKind)
2855       return Error(Loc, "mismatched register size suffix");
2856 
2857     unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
2858 
2859     if (Space == 0 || Space > 3) {
2860       return Error(Loc, "invalid number of vectors");
2861     }
2862 
2863     Count += Space;
2864   }
2865   else {
2866     while (parseOptionalToken(AsmToken::Comma)) {
2867       SMLoc Loc = getLoc();
2868       StringRef NextKind;
2869       int64_t Reg = tryMatchVectorRegister(NextKind, true);
2870       if (Reg == -1)
2871         return true;
2872       // Any Kind suffices must match on all regs in the list.
2873       if (Kind != NextKind)
2874         return Error(Loc, "mismatched register size suffix");
2875 
2876       // Registers must be incremental (with wraparound at 31)
2877       if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2878           (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2879        return Error(Loc, "registers must be sequential");
2880 
2881       PrevReg = Reg;
2882       ++Count;
2883     }
2884   }
2885 
2886   if (parseToken(AsmToken::RCurly, "'}' expected"))
2887     return true;
2888 
2889   if (Count > 4)
2890     return Error(S, "invalid number of vectors");
2891 
2892   unsigned NumElements = 0;
2893   char ElementKind = 0;
2894   if (!Kind.empty())
2895     parseValidVectorKind(Kind, NumElements, ElementKind);
2896 
2897   Operands.push_back(AArch64Operand::CreateVectorList(
2898       FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2899 
2900   // If there is an index specifier following the list, parse that too.
2901   SMLoc SIdx = getLoc();
2902   if (parseOptionalToken(AsmToken::LBrac)) { // Eat left bracket token.
2903     const MCExpr *ImmVal;
2904     if (getParser().parseExpression(ImmVal))
2905       return false;
2906     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2907     if (!MCE) {
2908       TokError("immediate value expected for vector index");
2909       return false;
2910     }
2911 
2912     SMLoc E = getLoc();
2913     if (parseToken(AsmToken::RBrac, "']' expected"))
2914       return false;
2915 
2916     Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2917                                                          E, getContext()));
2918   }
2919   return false;
2920 }
2921 
2922 OperandMatchResultTy
2923 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
2924   MCAsmParser &Parser = getParser();
2925   const AsmToken &Tok = Parser.getTok();
2926   if (!Tok.is(AsmToken::Identifier))
2927     return MatchOperand_NoMatch;
2928 
2929   unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false);
2930 
2931   MCContext &Ctx = getContext();
2932   const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2933   if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
2934     return MatchOperand_NoMatch;
2935 
2936   SMLoc S = getLoc();
2937   Parser.Lex(); // Eat register
2938 
2939   if (!parseOptionalToken(AsmToken::Comma)) {
2940     Operands.push_back(
2941         AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2942     return MatchOperand_Success;
2943   }
2944 
2945   parseOptionalToken(AsmToken::Hash);
2946 
2947   if (Parser.getTok().isNot(AsmToken::Integer)) {
2948     Error(getLoc(), "index must be absent or #0");
2949     return MatchOperand_ParseFail;
2950   }
2951 
2952   const MCExpr *ImmVal;
2953   if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
2954       cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
2955     Error(getLoc(), "index must be absent or #0");
2956     return MatchOperand_ParseFail;
2957   }
2958 
2959   Operands.push_back(
2960       AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2961   return MatchOperand_Success;
2962 }
2963 
2964 /// parseOperand - Parse a arm instruction operand.  For now this parses the
2965 /// operand regardless of the mnemonic.
2966 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
2967                                   bool invertCondCode) {
2968   MCAsmParser &Parser = getParser();
2969   // Check if the current operand has a custom associated parser, if so, try to
2970   // custom parse the operand, or fallback to the general approach.
2971   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2972   if (ResTy == MatchOperand_Success)
2973     return false;
2974   // If there wasn't a custom match, try the generic matcher below. Otherwise,
2975   // there was a match, but an error occurred, in which case, just return that
2976   // the operand parsing failed.
2977   if (ResTy == MatchOperand_ParseFail)
2978     return true;
2979 
2980   // Nothing custom, so do general case parsing.
2981   SMLoc S, E;
2982   switch (getLexer().getKind()) {
2983   default: {
2984     SMLoc S = getLoc();
2985     const MCExpr *Expr;
2986     if (parseSymbolicImmVal(Expr))
2987       return Error(S, "invalid operand");
2988 
2989     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2990     Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2991     return false;
2992   }
2993   case AsmToken::LBrac: {
2994     SMLoc Loc = Parser.getTok().getLoc();
2995     Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
2996                                                    getContext()));
2997     Parser.Lex(); // Eat '['
2998 
2999     // There's no comma after a '[', so we can parse the next operand
3000     // immediately.
3001     return parseOperand(Operands, false, false);
3002   }
3003   case AsmToken::LCurly:
3004     return parseVectorList(Operands);
3005   case AsmToken::Identifier: {
3006     // If we're expecting a Condition Code operand, then just parse that.
3007     if (isCondCode)
3008       return parseCondCode(Operands, invertCondCode);
3009 
3010     // If it's a register name, parse it.
3011     if (!parseRegister(Operands))
3012       return false;
3013 
3014     // This could be an optional "shift" or "extend" operand.
3015     OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3016     // We can only continue if no tokens were eaten.
3017     if (GotShift != MatchOperand_NoMatch)
3018       return GotShift;
3019 
3020     // This was not a register so parse other operands that start with an
3021     // identifier (like labels) as expressions and create them as immediates.
3022     const MCExpr *IdVal;
3023     S = getLoc();
3024     if (getParser().parseExpression(IdVal))
3025       return true;
3026     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3027     Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3028     return false;
3029   }
3030   case AsmToken::Integer:
3031   case AsmToken::Real:
3032   case AsmToken::Hash: {
3033     // #42 -> immediate.
3034     S = getLoc();
3035 
3036     parseOptionalToken(AsmToken::Hash);
3037 
3038     // Parse a negative sign
3039     bool isNegative = false;
3040     if (Parser.getTok().is(AsmToken::Minus)) {
3041       isNegative = true;
3042       // We need to consume this token only when we have a Real, otherwise
3043       // we let parseSymbolicImmVal take care of it
3044       if (Parser.getLexer().peekTok().is(AsmToken::Real))
3045         Parser.Lex();
3046     }
3047 
3048     // The only Real that should come through here is a literal #0.0 for
3049     // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3050     // so convert the value.
3051     const AsmToken &Tok = Parser.getTok();
3052     if (Tok.is(AsmToken::Real)) {
3053       APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
3054       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3055       if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3056           Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3057           Mnemonic != "fcmlt")
3058         return TokError("unexpected floating point literal");
3059       else if (IntVal != 0 || isNegative)
3060         return TokError("expected floating-point constant #0.0");
3061       Parser.Lex(); // Eat the token.
3062 
3063       Operands.push_back(
3064           AArch64Operand::CreateToken("#0", false, S, getContext()));
3065       Operands.push_back(
3066           AArch64Operand::CreateToken(".0", false, S, getContext()));
3067       return false;
3068     }
3069 
3070     const MCExpr *ImmVal;
3071     if (parseSymbolicImmVal(ImmVal))
3072       return true;
3073 
3074     E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3075     Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3076     return false;
3077   }
3078   case AsmToken::Equal: {
3079     SMLoc Loc = getLoc();
3080     if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3081       return TokError("unexpected token in operand");
3082     Parser.Lex(); // Eat '='
3083     const MCExpr *SubExprVal;
3084     if (getParser().parseExpression(SubExprVal))
3085       return true;
3086 
3087     if (Operands.size() < 2 ||
3088         !static_cast<AArch64Operand &>(*Operands[1]).isReg())
3089       return Error(Loc, "Only valid when first operand is register");
3090 
3091     bool IsXReg =
3092         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3093             Operands[1]->getReg());
3094 
3095     MCContext& Ctx = getContext();
3096     E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3097     // If the op is an imm and can be fit into a mov, then replace ldr with mov.
3098     if (isa<MCConstantExpr>(SubExprVal)) {
3099       uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3100       uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3101       while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3102         ShiftAmt += 16;
3103         Imm >>= 16;
3104       }
3105       if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3106           Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3107           Operands.push_back(AArch64Operand::CreateImm(
3108                      MCConstantExpr::create(Imm, Ctx), S, E, Ctx));
3109         if (ShiftAmt)
3110           Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3111                      ShiftAmt, true, S, E, Ctx));
3112         return false;
3113       }
3114       APInt Simm = APInt(64, Imm << ShiftAmt);
3115       // check if the immediate is an unsigned or signed 32-bit int for W regs
3116       if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
3117         return Error(Loc, "Immediate too large for register");
3118     }
3119     // If it is a label or an imm that cannot fit in a movz, put it into CP.
3120     const MCExpr *CPLoc =
3121         getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
3122     Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3123     return false;
3124   }
3125   }
3126 }
3127 
3128 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3129 /// operands.
3130 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3131                                         StringRef Name, SMLoc NameLoc,
3132                                         OperandVector &Operands) {
3133   MCAsmParser &Parser = getParser();
3134   Name = StringSwitch<StringRef>(Name.lower())
3135              .Case("beq", "b.eq")
3136              .Case("bne", "b.ne")
3137              .Case("bhs", "b.hs")
3138              .Case("bcs", "b.cs")
3139              .Case("blo", "b.lo")
3140              .Case("bcc", "b.cc")
3141              .Case("bmi", "b.mi")
3142              .Case("bpl", "b.pl")
3143              .Case("bvs", "b.vs")
3144              .Case("bvc", "b.vc")
3145              .Case("bhi", "b.hi")
3146              .Case("bls", "b.ls")
3147              .Case("bge", "b.ge")
3148              .Case("blt", "b.lt")
3149              .Case("bgt", "b.gt")
3150              .Case("ble", "b.le")
3151              .Case("bal", "b.al")
3152              .Case("bnv", "b.nv")
3153              .Default(Name);
3154 
3155   // First check for the AArch64-specific .req directive.
3156   if (Parser.getTok().is(AsmToken::Identifier) &&
3157       Parser.getTok().getIdentifier() == ".req") {
3158     parseDirectiveReq(Name, NameLoc);
3159     // We always return 'error' for this, as we're done with this
3160     // statement and don't need to match the 'instruction."
3161     return true;
3162   }
3163 
3164   // Create the leading tokens for the mnemonic, split by '.' characters.
3165   size_t Start = 0, Next = Name.find('.');
3166   StringRef Head = Name.slice(Start, Next);
3167 
3168   // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3169   if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi")
3170     return parseSysAlias(Head, NameLoc, Operands);
3171 
3172   Operands.push_back(
3173       AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3174   Mnemonic = Head;
3175 
3176   // Handle condition codes for a branch mnemonic
3177   if (Head == "b" && Next != StringRef::npos) {
3178     Start = Next;
3179     Next = Name.find('.', Start + 1);
3180     Head = Name.slice(Start + 1, Next);
3181 
3182     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3183                                             (Head.data() - Name.data()));
3184     AArch64CC::CondCode CC = parseCondCodeString(Head);
3185     if (CC == AArch64CC::Invalid)
3186       return Error(SuffixLoc, "invalid condition code");
3187     Operands.push_back(
3188         AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3189     Operands.push_back(
3190         AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3191   }
3192 
3193   // Add the remaining tokens in the mnemonic.
3194   while (Next != StringRef::npos) {
3195     Start = Next;
3196     Next = Name.find('.', Start + 1);
3197     Head = Name.slice(Start, Next);
3198     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3199                                             (Head.data() - Name.data()) + 1);
3200     Operands.push_back(
3201         AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3202   }
3203 
3204   // Conditional compare instructions have a Condition Code operand, which needs
3205   // to be parsed and an immediate operand created.
3206   bool condCodeFourthOperand =
3207       (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3208        Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3209        Head == "csinc" || Head == "csinv" || Head == "csneg");
3210 
3211   // These instructions are aliases to some of the conditional select
3212   // instructions. However, the condition code is inverted in the aliased
3213   // instruction.
3214   //
3215   // FIXME: Is this the correct way to handle these? Or should the parser
3216   //        generate the aliased instructions directly?
3217   bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3218   bool condCodeThirdOperand =
3219       (Head == "cinc" || Head == "cinv" || Head == "cneg");
3220 
3221   // Read the remaining operands.
3222   if (getLexer().isNot(AsmToken::EndOfStatement)) {
3223     // Read the first operand.
3224     if (parseOperand(Operands, false, false)) {
3225       return true;
3226     }
3227 
3228     unsigned N = 2;
3229     while (parseOptionalToken(AsmToken::Comma)) {
3230       // Parse and remember the operand.
3231       if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3232                                      (N == 3 && condCodeThirdOperand) ||
3233                                      (N == 2 && condCodeSecondOperand),
3234                        condCodeSecondOperand || condCodeThirdOperand)) {
3235         return true;
3236       }
3237 
3238       // After successfully parsing some operands there are two special cases to
3239       // consider (i.e. notional operands not separated by commas). Both are due
3240       // to memory specifiers:
3241       //  + An RBrac will end an address for load/store/prefetch
3242       //  + An '!' will indicate a pre-indexed operation.
3243       //
3244       // It's someone else's responsibility to make sure these tokens are sane
3245       // in the given context!
3246 
3247       SMLoc RLoc = Parser.getTok().getLoc();
3248       if (parseOptionalToken(AsmToken::RBrac))
3249         Operands.push_back(
3250             AArch64Operand::CreateToken("]", false, RLoc, getContext()));
3251       SMLoc ELoc = Parser.getTok().getLoc();
3252       if (parseOptionalToken(AsmToken::Exclaim))
3253         Operands.push_back(
3254             AArch64Operand::CreateToken("!", false, ELoc, getContext()));
3255 
3256       ++N;
3257     }
3258   }
3259 
3260   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
3261     return true;
3262 
3263   return false;
3264 }
3265 
3266 // FIXME: This entire function is a giant hack to provide us with decent
3267 // operand range validation/diagnostics until TableGen/MC can be extended
3268 // to support autogeneration of this kind of validation.
3269 bool AArch64AsmParser::validateInstruction(MCInst &Inst,
3270                                          SmallVectorImpl<SMLoc> &Loc) {
3271   const MCRegisterInfo *RI = getContext().getRegisterInfo();
3272   // Check for indexed addressing modes w/ the base register being the
3273   // same as a destination/source register or pair load where
3274   // the Rt == Rt2. All of those are undefined behaviour.
3275   switch (Inst.getOpcode()) {
3276   case AArch64::LDPSWpre:
3277   case AArch64::LDPWpost:
3278   case AArch64::LDPWpre:
3279   case AArch64::LDPXpost:
3280   case AArch64::LDPXpre: {
3281     unsigned Rt = Inst.getOperand(1).getReg();
3282     unsigned Rt2 = Inst.getOperand(2).getReg();
3283     unsigned Rn = Inst.getOperand(3).getReg();
3284     if (RI->isSubRegisterEq(Rn, Rt))
3285       return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3286                            "is also a destination");
3287     if (RI->isSubRegisterEq(Rn, Rt2))
3288       return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3289                            "is also a destination");
3290     LLVM_FALLTHROUGH;
3291   }
3292   case AArch64::LDPDi:
3293   case AArch64::LDPQi:
3294   case AArch64::LDPSi:
3295   case AArch64::LDPSWi:
3296   case AArch64::LDPWi:
3297   case AArch64::LDPXi: {
3298     unsigned Rt = Inst.getOperand(0).getReg();
3299     unsigned Rt2 = Inst.getOperand(1).getReg();
3300     if (Rt == Rt2)
3301       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3302     break;
3303   }
3304   case AArch64::LDPDpost:
3305   case AArch64::LDPDpre:
3306   case AArch64::LDPQpost:
3307   case AArch64::LDPQpre:
3308   case AArch64::LDPSpost:
3309   case AArch64::LDPSpre:
3310   case AArch64::LDPSWpost: {
3311     unsigned Rt = Inst.getOperand(1).getReg();
3312     unsigned Rt2 = Inst.getOperand(2).getReg();
3313     if (Rt == Rt2)
3314       return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3315     break;
3316   }
3317   case AArch64::STPDpost:
3318   case AArch64::STPDpre:
3319   case AArch64::STPQpost:
3320   case AArch64::STPQpre:
3321   case AArch64::STPSpost:
3322   case AArch64::STPSpre:
3323   case AArch64::STPWpost:
3324   case AArch64::STPWpre:
3325   case AArch64::STPXpost:
3326   case AArch64::STPXpre: {
3327     unsigned Rt = Inst.getOperand(1).getReg();
3328     unsigned Rt2 = Inst.getOperand(2).getReg();
3329     unsigned Rn = Inst.getOperand(3).getReg();
3330     if (RI->isSubRegisterEq(Rn, Rt))
3331       return Error(Loc[0], "unpredictable STP instruction, writeback base "
3332                            "is also a source");
3333     if (RI->isSubRegisterEq(Rn, Rt2))
3334       return Error(Loc[1], "unpredictable STP instruction, writeback base "
3335                            "is also a source");
3336     break;
3337   }
3338   case AArch64::LDRBBpre:
3339   case AArch64::LDRBpre:
3340   case AArch64::LDRHHpre:
3341   case AArch64::LDRHpre:
3342   case AArch64::LDRSBWpre:
3343   case AArch64::LDRSBXpre:
3344   case AArch64::LDRSHWpre:
3345   case AArch64::LDRSHXpre:
3346   case AArch64::LDRSWpre:
3347   case AArch64::LDRWpre:
3348   case AArch64::LDRXpre:
3349   case AArch64::LDRBBpost:
3350   case AArch64::LDRBpost:
3351   case AArch64::LDRHHpost:
3352   case AArch64::LDRHpost:
3353   case AArch64::LDRSBWpost:
3354   case AArch64::LDRSBXpost:
3355   case AArch64::LDRSHWpost:
3356   case AArch64::LDRSHXpost:
3357   case AArch64::LDRSWpost:
3358   case AArch64::LDRWpost:
3359   case AArch64::LDRXpost: {
3360     unsigned Rt = Inst.getOperand(1).getReg();
3361     unsigned Rn = Inst.getOperand(2).getReg();
3362     if (RI->isSubRegisterEq(Rn, Rt))
3363       return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3364                            "is also a source");
3365     break;
3366   }
3367   case AArch64::STRBBpost:
3368   case AArch64::STRBpost:
3369   case AArch64::STRHHpost:
3370   case AArch64::STRHpost:
3371   case AArch64::STRWpost:
3372   case AArch64::STRXpost:
3373   case AArch64::STRBBpre:
3374   case AArch64::STRBpre:
3375   case AArch64::STRHHpre:
3376   case AArch64::STRHpre:
3377   case AArch64::STRWpre:
3378   case AArch64::STRXpre: {
3379     unsigned Rt = Inst.getOperand(1).getReg();
3380     unsigned Rn = Inst.getOperand(2).getReg();
3381     if (RI->isSubRegisterEq(Rn, Rt))
3382       return Error(Loc[0], "unpredictable STR instruction, writeback base "
3383                            "is also a source");
3384     break;
3385   }
3386   }
3387 
3388   // Now check immediate ranges. Separate from the above as there is overlap
3389   // in the instructions being checked and this keeps the nested conditionals
3390   // to a minimum.
3391   switch (Inst.getOpcode()) {
3392   case AArch64::ADDSWri:
3393   case AArch64::ADDSXri:
3394   case AArch64::ADDWri:
3395   case AArch64::ADDXri:
3396   case AArch64::SUBSWri:
3397   case AArch64::SUBSXri:
3398   case AArch64::SUBWri:
3399   case AArch64::SUBXri: {
3400     // Annoyingly we can't do this in the isAddSubImm predicate, so there is
3401     // some slight duplication here.
3402     if (Inst.getOperand(2).isExpr()) {
3403       const MCExpr *Expr = Inst.getOperand(2).getExpr();
3404       AArch64MCExpr::VariantKind ELFRefKind;
3405       MCSymbolRefExpr::VariantKind DarwinRefKind;
3406       int64_t Addend;
3407       if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3408 
3409         // Only allow these with ADDXri.
3410         if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3411              DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
3412             Inst.getOpcode() == AArch64::ADDXri)
3413           return false;
3414 
3415         // Only allow these with ADDXri/ADDWri
3416         if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
3417              ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
3418              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
3419              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
3420              ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
3421              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
3422              ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
3423              ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
3424             (Inst.getOpcode() == AArch64::ADDXri ||
3425              Inst.getOpcode() == AArch64::ADDWri))
3426           return false;
3427 
3428         // Don't allow symbol refs in the immediate field otherwise
3429         // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of
3430         // operands of the original instruction (i.e. 'add w0, w1, borked' vs
3431         // 'cmp w0, 'borked')
3432         return Error(Loc.back(), "invalid immediate expression");
3433       }
3434       // We don't validate more complex expressions here
3435     }
3436     return false;
3437   }
3438   default:
3439     return false;
3440   }
3441 }
3442 
3443 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
3444   switch (ErrCode) {
3445   case Match_MissingFeature:
3446     return Error(Loc,
3447                  "instruction requires a CPU feature not currently enabled");
3448   case Match_InvalidOperand:
3449     return Error(Loc, "invalid operand for instruction");
3450   case Match_InvalidSuffix:
3451     return Error(Loc, "invalid type suffix for instruction");
3452   case Match_InvalidCondCode:
3453     return Error(Loc, "expected AArch64 condition code");
3454   case Match_AddSubRegExtendSmall:
3455     return Error(Loc,
3456       "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3457   case Match_AddSubRegExtendLarge:
3458     return Error(Loc,
3459       "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3460   case Match_AddSubSecondSource:
3461     return Error(Loc,
3462       "expected compatible register, symbol or integer in range [0, 4095]");
3463   case Match_LogicalSecondSource:
3464     return Error(Loc, "expected compatible register or logical immediate");
3465   case Match_InvalidMovImm32Shift:
3466     return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
3467   case Match_InvalidMovImm64Shift:
3468     return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
3469   case Match_AddSubRegShift32:
3470     return Error(Loc,
3471        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3472   case Match_AddSubRegShift64:
3473     return Error(Loc,
3474        "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3475   case Match_InvalidFPImm:
3476     return Error(Loc,
3477                  "expected compatible register or floating-point constant");
3478   case Match_InvalidMemoryIndexedSImm9:
3479     return Error(Loc, "index must be an integer in range [-256, 255].");
3480   case Match_InvalidMemoryIndexed4SImm7:
3481     return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
3482   case Match_InvalidMemoryIndexed8SImm7:
3483     return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
3484   case Match_InvalidMemoryIndexed16SImm7:
3485     return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
3486   case Match_InvalidMemoryWExtend8:
3487     return Error(Loc,
3488                  "expected 'uxtw' or 'sxtw' with optional shift of #0");
3489   case Match_InvalidMemoryWExtend16:
3490     return Error(Loc,
3491                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3492   case Match_InvalidMemoryWExtend32:
3493     return Error(Loc,
3494                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3495   case Match_InvalidMemoryWExtend64:
3496     return Error(Loc,
3497                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3498   case Match_InvalidMemoryWExtend128:
3499     return Error(Loc,
3500                  "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3501   case Match_InvalidMemoryXExtend8:
3502     return Error(Loc,
3503                  "expected 'lsl' or 'sxtx' with optional shift of #0");
3504   case Match_InvalidMemoryXExtend16:
3505     return Error(Loc,
3506                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3507   case Match_InvalidMemoryXExtend32:
3508     return Error(Loc,
3509                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3510   case Match_InvalidMemoryXExtend64:
3511     return Error(Loc,
3512                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3513   case Match_InvalidMemoryXExtend128:
3514     return Error(Loc,
3515                  "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3516   case Match_InvalidMemoryIndexed1:
3517     return Error(Loc, "index must be an integer in range [0, 4095].");
3518   case Match_InvalidMemoryIndexed2:
3519     return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
3520   case Match_InvalidMemoryIndexed4:
3521     return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
3522   case Match_InvalidMemoryIndexed8:
3523     return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
3524   case Match_InvalidMemoryIndexed16:
3525     return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
3526   case Match_InvalidImm0_1:
3527     return Error(Loc, "immediate must be an integer in range [0, 1].");
3528   case Match_InvalidImm0_7:
3529     return Error(Loc, "immediate must be an integer in range [0, 7].");
3530   case Match_InvalidImm0_15:
3531     return Error(Loc, "immediate must be an integer in range [0, 15].");
3532   case Match_InvalidImm0_31:
3533     return Error(Loc, "immediate must be an integer in range [0, 31].");
3534   case Match_InvalidImm0_63:
3535     return Error(Loc, "immediate must be an integer in range [0, 63].");
3536   case Match_InvalidImm0_127:
3537     return Error(Loc, "immediate must be an integer in range [0, 127].");
3538   case Match_InvalidImm0_255:
3539     return Error(Loc, "immediate must be an integer in range [0, 255].");
3540   case Match_InvalidImm0_65535:
3541     return Error(Loc, "immediate must be an integer in range [0, 65535].");
3542   case Match_InvalidImm1_8:
3543     return Error(Loc, "immediate must be an integer in range [1, 8].");
3544   case Match_InvalidImm1_16:
3545     return Error(Loc, "immediate must be an integer in range [1, 16].");
3546   case Match_InvalidImm1_32:
3547     return Error(Loc, "immediate must be an integer in range [1, 32].");
3548   case Match_InvalidImm1_64:
3549     return Error(Loc, "immediate must be an integer in range [1, 64].");
3550   case Match_InvalidIndex1:
3551     return Error(Loc, "expected lane specifier '[1]'");
3552   case Match_InvalidIndexB:
3553     return Error(Loc, "vector lane must be an integer in range [0, 15].");
3554   case Match_InvalidIndexH:
3555     return Error(Loc, "vector lane must be an integer in range [0, 7].");
3556   case Match_InvalidIndexS:
3557     return Error(Loc, "vector lane must be an integer in range [0, 3].");
3558   case Match_InvalidIndexD:
3559     return Error(Loc, "vector lane must be an integer in range [0, 1].");
3560   case Match_InvalidLabel:
3561     return Error(Loc, "expected label or encodable integer pc offset");
3562   case Match_MRS:
3563     return Error(Loc, "expected readable system register");
3564   case Match_MSR:
3565     return Error(Loc, "expected writable system register or pstate");
3566   case Match_MnemonicFail:
3567     return Error(Loc, "unrecognized instruction mnemonic");
3568   default:
3569     llvm_unreachable("unexpected error code!");
3570   }
3571 }
3572 
3573 static const char *getSubtargetFeatureName(uint64_t Val);
3574 
3575 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3576                                                OperandVector &Operands,
3577                                                MCStreamer &Out,
3578                                                uint64_t &ErrorInfo,
3579                                                bool MatchingInlineAsm) {
3580   assert(!Operands.empty() && "Unexpect empty operand list!");
3581   AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
3582   assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3583 
3584   StringRef Tok = Op.getToken();
3585   unsigned NumOperands = Operands.size();
3586 
3587   if (NumOperands == 4 && Tok == "lsl") {
3588     AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
3589     AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3590     if (Op2.isReg() && Op3.isImm()) {
3591       const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3592       if (Op3CE) {
3593         uint64_t Op3Val = Op3CE->getValue();
3594         uint64_t NewOp3Val = 0;
3595         uint64_t NewOp4Val = 0;
3596         if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
3597                 Op2.getReg())) {
3598           NewOp3Val = (32 - Op3Val) & 0x1f;
3599           NewOp4Val = 31 - Op3Val;
3600         } else {
3601           NewOp3Val = (64 - Op3Val) & 0x3f;
3602           NewOp4Val = 63 - Op3Val;
3603         }
3604 
3605         const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext());
3606         const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext());
3607 
3608         Operands[0] = AArch64Operand::CreateToken(
3609             "ubfm", false, Op.getStartLoc(), getContext());
3610         Operands.push_back(AArch64Operand::CreateImm(
3611             NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3612         Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3613                                                 Op3.getEndLoc(), getContext());
3614       }
3615     }
3616   } else if (NumOperands == 4 && Tok == "bfc") {
3617     // FIXME: Horrible hack to handle BFC->BFM alias.
3618     AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3619     AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]);
3620     AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]);
3621 
3622     if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) {
3623       const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
3624       const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
3625 
3626       if (LSBCE && WidthCE) {
3627         uint64_t LSB = LSBCE->getValue();
3628         uint64_t Width = WidthCE->getValue();
3629 
3630         uint64_t RegWidth = 0;
3631         if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3632                 Op1.getReg()))
3633           RegWidth = 64;
3634         else
3635           RegWidth = 32;
3636 
3637         if (LSB >= RegWidth)
3638           return Error(LSBOp.getStartLoc(),
3639                        "expected integer in range [0, 31]");
3640         if (Width < 1 || Width > RegWidth)
3641           return Error(WidthOp.getStartLoc(),
3642                        "expected integer in range [1, 32]");
3643 
3644         uint64_t ImmR = 0;
3645         if (RegWidth == 32)
3646           ImmR = (32 - LSB) & 0x1f;
3647         else
3648           ImmR = (64 - LSB) & 0x3f;
3649 
3650         uint64_t ImmS = Width - 1;
3651 
3652         if (ImmR != 0 && ImmS >= ImmR)
3653           return Error(WidthOp.getStartLoc(),
3654                        "requested insert overflows register");
3655 
3656         const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext());
3657         const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext());
3658         Operands[0] = AArch64Operand::CreateToken(
3659               "bfm", false, Op.getStartLoc(), getContext());
3660         Operands[2] = AArch64Operand::CreateReg(
3661             RegWidth == 32 ? AArch64::WZR : AArch64::XZR, false, SMLoc(),
3662             SMLoc(), getContext());
3663         Operands[3] = AArch64Operand::CreateImm(
3664             ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
3665         Operands.emplace_back(
3666             AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
3667                                       WidthOp.getEndLoc(), getContext()));
3668       }
3669     }
3670   } else if (NumOperands == 5) {
3671     // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
3672     // UBFIZ -> UBFM aliases.
3673     if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
3674       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3675       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3676       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3677 
3678       if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3679         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3680         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3681 
3682         if (Op3CE && Op4CE) {
3683           uint64_t Op3Val = Op3CE->getValue();
3684           uint64_t Op4Val = Op4CE->getValue();
3685 
3686           uint64_t RegWidth = 0;
3687           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3688                   Op1.getReg()))
3689             RegWidth = 64;
3690           else
3691             RegWidth = 32;
3692 
3693           if (Op3Val >= RegWidth)
3694             return Error(Op3.getStartLoc(),
3695                          "expected integer in range [0, 31]");
3696           if (Op4Val < 1 || Op4Val > RegWidth)
3697             return Error(Op4.getStartLoc(),
3698                          "expected integer in range [1, 32]");
3699 
3700           uint64_t NewOp3Val = 0;
3701           if (RegWidth == 32)
3702             NewOp3Val = (32 - Op3Val) & 0x1f;
3703           else
3704             NewOp3Val = (64 - Op3Val) & 0x3f;
3705 
3706           uint64_t NewOp4Val = Op4Val - 1;
3707 
3708           if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
3709             return Error(Op4.getStartLoc(),
3710                          "requested insert overflows register");
3711 
3712           const MCExpr *NewOp3 =
3713               MCConstantExpr::create(NewOp3Val, getContext());
3714           const MCExpr *NewOp4 =
3715               MCConstantExpr::create(NewOp4Val, getContext());
3716           Operands[3] = AArch64Operand::CreateImm(
3717               NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
3718           Operands[4] = AArch64Operand::CreateImm(
3719               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3720           if (Tok == "bfi")
3721             Operands[0] = AArch64Operand::CreateToken(
3722                 "bfm", false, Op.getStartLoc(), getContext());
3723           else if (Tok == "sbfiz")
3724             Operands[0] = AArch64Operand::CreateToken(
3725                 "sbfm", false, Op.getStartLoc(), getContext());
3726           else if (Tok == "ubfiz")
3727             Operands[0] = AArch64Operand::CreateToken(
3728                 "ubfm", false, Op.getStartLoc(), getContext());
3729           else
3730             llvm_unreachable("No valid mnemonic for alias?");
3731         }
3732       }
3733 
3734       // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
3735       // UBFX -> UBFM aliases.
3736     } else if (NumOperands == 5 &&
3737                (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
3738       AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3739       AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3740       AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3741 
3742       if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3743         const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3744         const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3745 
3746         if (Op3CE && Op4CE) {
3747           uint64_t Op3Val = Op3CE->getValue();
3748           uint64_t Op4Val = Op4CE->getValue();
3749 
3750           uint64_t RegWidth = 0;
3751           if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3752                   Op1.getReg()))
3753             RegWidth = 64;
3754           else
3755             RegWidth = 32;
3756 
3757           if (Op3Val >= RegWidth)
3758             return Error(Op3.getStartLoc(),
3759                          "expected integer in range [0, 31]");
3760           if (Op4Val < 1 || Op4Val > RegWidth)
3761             return Error(Op4.getStartLoc(),
3762                          "expected integer in range [1, 32]");
3763 
3764           uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3765 
3766           if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
3767             return Error(Op4.getStartLoc(),
3768                          "requested extract overflows register");
3769 
3770           const MCExpr *NewOp4 =
3771               MCConstantExpr::create(NewOp4Val, getContext());
3772           Operands[4] = AArch64Operand::CreateImm(
3773               NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3774           if (Tok == "bfxil")
3775             Operands[0] = AArch64Operand::CreateToken(
3776                 "bfm", false, Op.getStartLoc(), getContext());
3777           else if (Tok == "sbfx")
3778             Operands[0] = AArch64Operand::CreateToken(
3779                 "sbfm", false, Op.getStartLoc(), getContext());
3780           else if (Tok == "ubfx")
3781             Operands[0] = AArch64Operand::CreateToken(
3782                 "ubfm", false, Op.getStartLoc(), getContext());
3783           else
3784             llvm_unreachable("No valid mnemonic for alias?");
3785         }
3786       }
3787     }
3788   }
3789   // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
3790   //        InstAlias can't quite handle this since the reg classes aren't
3791   //        subclasses.
3792   if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
3793     // The source register can be Wn here, but the matcher expects a
3794     // GPR64. Twiddle it here if necessary.
3795     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3796     if (Op.isReg()) {
3797       unsigned Reg = getXRegFromWReg(Op.getReg());
3798       Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3799                                               Op.getEndLoc(), getContext());
3800     }
3801   }
3802   // FIXME: Likewise for sxt[bh] with a Xd dst operand
3803   else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
3804     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3805     if (Op.isReg() &&
3806         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3807             Op.getReg())) {
3808       // The source register can be Wn here, but the matcher expects a
3809       // GPR64. Twiddle it here if necessary.
3810       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3811       if (Op.isReg()) {
3812         unsigned Reg = getXRegFromWReg(Op.getReg());
3813         Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3814                                                 Op.getEndLoc(), getContext());
3815       }
3816     }
3817   }
3818   // FIXME: Likewise for uxt[bh] with a Xd dst operand
3819   else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
3820     AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3821     if (Op.isReg() &&
3822         AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3823             Op.getReg())) {
3824       // The source register can be Wn here, but the matcher expects a
3825       // GPR32. Twiddle it here if necessary.
3826       AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3827       if (Op.isReg()) {
3828         unsigned Reg = getWRegFromXReg(Op.getReg());
3829         Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3830                                                 Op.getEndLoc(), getContext());
3831       }
3832     }
3833   }
3834 
3835   // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
3836   if (NumOperands == 3 && Tok == "fmov") {
3837     AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
3838     AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
3839     if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
3840       unsigned zreg =
3841           !AArch64MCRegisterClasses[AArch64::FPR64RegClassID].contains(
3842               RegOp.getReg())
3843               ? AArch64::WZR
3844               : AArch64::XZR;
3845       Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
3846                                               Op.getEndLoc(), getContext());
3847     }
3848   }
3849 
3850   MCInst Inst;
3851   // First try to match against the secondary set of tables containing the
3852   // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
3853   unsigned MatchResult =
3854       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3855 
3856   // If that fails, try against the alternate table containing long-form NEON:
3857   // "fadd v0.2s, v1.2s, v2.2s"
3858   if (MatchResult != Match_Success) {
3859     // But first, save the short-form match result: we can use it in case the
3860     // long-form match also fails.
3861     auto ShortFormNEONErrorInfo = ErrorInfo;
3862     auto ShortFormNEONMatchResult = MatchResult;
3863 
3864     MatchResult =
3865         MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3866 
3867     // Now, both matches failed, and the long-form match failed on the mnemonic
3868     // suffix token operand.  The short-form match failure is probably more
3869     // relevant: use it instead.
3870     if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
3871         Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
3872         ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
3873       MatchResult = ShortFormNEONMatchResult;
3874       ErrorInfo = ShortFormNEONErrorInfo;
3875     }
3876   }
3877 
3878   switch (MatchResult) {
3879   case Match_Success: {
3880     // Perform range checking and other semantic validations
3881     SmallVector<SMLoc, 8> OperandLocs;
3882     NumOperands = Operands.size();
3883     for (unsigned i = 1; i < NumOperands; ++i)
3884       OperandLocs.push_back(Operands[i]->getStartLoc());
3885     if (validateInstruction(Inst, OperandLocs))
3886       return true;
3887 
3888     Inst.setLoc(IDLoc);
3889     Out.EmitInstruction(Inst, getSTI());
3890     return false;
3891   }
3892   case Match_MissingFeature: {
3893     assert(ErrorInfo && "Unknown missing feature!");
3894     // Special case the error message for the very common case where only
3895     // a single subtarget feature is missing (neon, e.g.).
3896     std::string Msg = "instruction requires:";
3897     uint64_t Mask = 1;
3898     for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
3899       if (ErrorInfo & Mask) {
3900         Msg += " ";
3901         Msg += getSubtargetFeatureName(ErrorInfo & Mask);
3902       }
3903       Mask <<= 1;
3904     }
3905     return Error(IDLoc, Msg);
3906   }
3907   case Match_MnemonicFail:
3908     return showMatchError(IDLoc, MatchResult);
3909   case Match_InvalidOperand: {
3910     SMLoc ErrorLoc = IDLoc;
3911 
3912     if (ErrorInfo != ~0ULL) {
3913       if (ErrorInfo >= Operands.size())
3914         return Error(IDLoc, "too few operands for instruction",
3915                      SMRange(IDLoc, getTok().getLoc()));
3916 
3917       ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3918       if (ErrorLoc == SMLoc())
3919         ErrorLoc = IDLoc;
3920     }
3921     // If the match failed on a suffix token operand, tweak the diagnostic
3922     // accordingly.
3923     if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3924         ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
3925       MatchResult = Match_InvalidSuffix;
3926 
3927     return showMatchError(ErrorLoc, MatchResult);
3928   }
3929   case Match_InvalidMemoryIndexed1:
3930   case Match_InvalidMemoryIndexed2:
3931   case Match_InvalidMemoryIndexed4:
3932   case Match_InvalidMemoryIndexed8:
3933   case Match_InvalidMemoryIndexed16:
3934   case Match_InvalidCondCode:
3935   case Match_AddSubRegExtendSmall:
3936   case Match_AddSubRegExtendLarge:
3937   case Match_AddSubSecondSource:
3938   case Match_LogicalSecondSource:
3939   case Match_AddSubRegShift32:
3940   case Match_AddSubRegShift64:
3941   case Match_InvalidMovImm32Shift:
3942   case Match_InvalidMovImm64Shift:
3943   case Match_InvalidFPImm:
3944   case Match_InvalidMemoryWExtend8:
3945   case Match_InvalidMemoryWExtend16:
3946   case Match_InvalidMemoryWExtend32:
3947   case Match_InvalidMemoryWExtend64:
3948   case Match_InvalidMemoryWExtend128:
3949   case Match_InvalidMemoryXExtend8:
3950   case Match_InvalidMemoryXExtend16:
3951   case Match_InvalidMemoryXExtend32:
3952   case Match_InvalidMemoryXExtend64:
3953   case Match_InvalidMemoryXExtend128:
3954   case Match_InvalidMemoryIndexed4SImm7:
3955   case Match_InvalidMemoryIndexed8SImm7:
3956   case Match_InvalidMemoryIndexed16SImm7:
3957   case Match_InvalidMemoryIndexedSImm9:
3958   case Match_InvalidImm0_1:
3959   case Match_InvalidImm0_7:
3960   case Match_InvalidImm0_15:
3961   case Match_InvalidImm0_31:
3962   case Match_InvalidImm0_63:
3963   case Match_InvalidImm0_127:
3964   case Match_InvalidImm0_255:
3965   case Match_InvalidImm0_65535:
3966   case Match_InvalidImm1_8:
3967   case Match_InvalidImm1_16:
3968   case Match_InvalidImm1_32:
3969   case Match_InvalidImm1_64:
3970   case Match_InvalidIndex1:
3971   case Match_InvalidIndexB:
3972   case Match_InvalidIndexH:
3973   case Match_InvalidIndexS:
3974   case Match_InvalidIndexD:
3975   case Match_InvalidLabel:
3976   case Match_MSR:
3977   case Match_MRS: {
3978     if (ErrorInfo >= Operands.size())
3979       return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc()));
3980     // Any time we get here, there's nothing fancy to do. Just get the
3981     // operand SMLoc and display the diagnostic.
3982     SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3983     if (ErrorLoc == SMLoc())
3984       ErrorLoc = IDLoc;
3985     return showMatchError(ErrorLoc, MatchResult);
3986   }
3987   }
3988 
3989   llvm_unreachable("Implement any new match types added!");
3990 }
3991 
3992 /// ParseDirective parses the arm specific directives
3993 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
3994   const MCObjectFileInfo::Environment Format =
3995     getContext().getObjectFileInfo()->getObjectFileType();
3996   bool IsMachO = Format == MCObjectFileInfo::IsMachO;
3997   bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
3998 
3999   StringRef IDVal = DirectiveID.getIdentifier();
4000   SMLoc Loc = DirectiveID.getLoc();
4001   if (IDVal == ".arch")
4002     parseDirectiveArch(Loc);
4003   else if (IDVal == ".cpu")
4004     parseDirectiveCPU(Loc);
4005   else if (IDVal == ".hword")
4006     parseDirectiveWord(2, Loc);
4007   else if (IDVal == ".word")
4008     parseDirectiveWord(4, Loc);
4009   else if (IDVal == ".xword")
4010     parseDirectiveWord(8, Loc);
4011   else if (IDVal == ".tlsdesccall")
4012     parseDirectiveTLSDescCall(Loc);
4013   else if (IDVal == ".ltorg" || IDVal == ".pool")
4014     parseDirectiveLtorg(Loc);
4015   else if (IDVal == ".unreq")
4016     parseDirectiveUnreq(Loc);
4017   else if (!IsMachO && !IsCOFF) {
4018     if (IDVal == ".inst")
4019       parseDirectiveInst(Loc);
4020     else
4021       return true;
4022   } else if (IDVal == MCLOHDirectiveName())
4023     parseDirectiveLOH(IDVal, Loc);
4024   else
4025     return true;
4026   return false;
4027 }
4028 
4029 static const struct {
4030   const char *Name;
4031   const FeatureBitset Features;
4032 } ExtensionMap[] = {
4033   { "crc", {AArch64::FeatureCRC} },
4034   { "crypto", {AArch64::FeatureCrypto} },
4035   { "fp", {AArch64::FeatureFPARMv8} },
4036   { "simd", {AArch64::FeatureNEON} },
4037   { "ras", {AArch64::FeatureRAS} },
4038   { "lse", {AArch64::FeatureLSE} },
4039 
4040   // FIXME: Unsupported extensions
4041   { "pan", {} },
4042   { "lor", {} },
4043   { "rdma", {} },
4044   { "profile", {} },
4045 };
4046 
4047 /// parseDirectiveArch
4048 ///   ::= .arch token
4049 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
4050   SMLoc ArchLoc = getLoc();
4051 
4052   StringRef Arch, ExtensionString;
4053   std::tie(Arch, ExtensionString) =
4054       getParser().parseStringToEndOfStatement().trim().split('+');
4055 
4056   unsigned ID = AArch64::parseArch(Arch);
4057   if (ID == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
4058     return Error(ArchLoc, "unknown arch name");
4059 
4060   if (parseToken(AsmToken::EndOfStatement))
4061     return true;
4062 
4063   // Get the architecture and extension features.
4064   std::vector<StringRef> AArch64Features;
4065   AArch64::getArchFeatures(ID, AArch64Features);
4066   AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID),
4067                                 AArch64Features);
4068 
4069   MCSubtargetInfo &STI = copySTI();
4070   std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
4071   STI.setDefaultFeatures("generic", join(ArchFeatures.begin(), ArchFeatures.end(), ","));
4072 
4073   SmallVector<StringRef, 4> RequestedExtensions;
4074   if (!ExtensionString.empty())
4075     ExtensionString.split(RequestedExtensions, '+');
4076 
4077   FeatureBitset Features = STI.getFeatureBits();
4078   for (auto Name : RequestedExtensions) {
4079     bool EnableFeature = true;
4080 
4081     if (Name.startswith_lower("no")) {
4082       EnableFeature = false;
4083       Name = Name.substr(2);
4084     }
4085 
4086     for (const auto &Extension : ExtensionMap) {
4087       if (Extension.Name != Name)
4088         continue;
4089 
4090       if (Extension.Features.none())
4091         report_fatal_error("unsupported architectural extension: " + Name);
4092 
4093       FeatureBitset ToggleFeatures = EnableFeature
4094                                          ? (~Features & Extension.Features)
4095                                          : ( Features & Extension.Features);
4096       uint64_t Features =
4097           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
4098       setAvailableFeatures(Features);
4099       break;
4100     }
4101   }
4102   return false;
4103 }
4104 
4105 /// parseDirectiveCPU
4106 ///   ::= .cpu id
4107 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
4108   SMLoc CPULoc = getLoc();
4109 
4110   StringRef CPU, ExtensionString;
4111   std::tie(CPU, ExtensionString) =
4112       getParser().parseStringToEndOfStatement().trim().split('+');
4113 
4114   if (parseToken(AsmToken::EndOfStatement))
4115     return true;
4116 
4117   SmallVector<StringRef, 4> RequestedExtensions;
4118   if (!ExtensionString.empty())
4119     ExtensionString.split(RequestedExtensions, '+');
4120 
4121   // FIXME This is using tablegen data, but should be moved to ARMTargetParser
4122   // once that is tablegen'ed
4123   if (!getSTI().isCPUStringValid(CPU)) {
4124     Error(CPULoc, "unknown CPU name");
4125     return false;
4126   }
4127 
4128   MCSubtargetInfo &STI = copySTI();
4129   STI.setDefaultFeatures(CPU, "");
4130 
4131   FeatureBitset Features = STI.getFeatureBits();
4132   for (auto Name : RequestedExtensions) {
4133     bool EnableFeature = true;
4134 
4135     if (Name.startswith_lower("no")) {
4136       EnableFeature = false;
4137       Name = Name.substr(2);
4138     }
4139 
4140     for (const auto &Extension : ExtensionMap) {
4141       if (Extension.Name != Name)
4142         continue;
4143 
4144       if (Extension.Features.none())
4145         report_fatal_error("unsupported architectural extension: " + Name);
4146 
4147       FeatureBitset ToggleFeatures = EnableFeature
4148                                          ? (~Features & Extension.Features)
4149                                          : ( Features & Extension.Features);
4150       uint64_t Features =
4151           ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
4152       setAvailableFeatures(Features);
4153 
4154       break;
4155     }
4156   }
4157   return false;
4158 }
4159 
4160 /// parseDirectiveWord
4161 ///  ::= .word [ expression (, expression)* ]
4162 bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4163   auto parseOp = [&]() -> bool {
4164     const MCExpr *Value;
4165     if (getParser().parseExpression(Value))
4166       return true;
4167     getParser().getStreamer().EmitValue(Value, Size, L);
4168     return false;
4169   };
4170 
4171   if (parseMany(parseOp))
4172     return true;
4173   return false;
4174 }
4175 
4176 /// parseDirectiveInst
4177 ///  ::= .inst opcode [, ...]
4178 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
4179   if (getLexer().is(AsmToken::EndOfStatement))
4180     return Error(Loc, "expected expression following '.inst' directive");
4181 
4182   auto parseOp = [&]() -> bool {
4183     SMLoc L = getLoc();
4184     const MCExpr *Expr;
4185     if (check(getParser().parseExpression(Expr), L, "expected expression"))
4186       return true;
4187     const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4188     if (check(!Value, L, "expected constant expression"))
4189       return true;
4190     getTargetStreamer().emitInst(Value->getValue());
4191     return false;
4192   };
4193 
4194   if (parseMany(parseOp))
4195     return addErrorSuffix(" in '.inst' directive");
4196   return false;
4197 }
4198 
4199 // parseDirectiveTLSDescCall:
4200 //   ::= .tlsdesccall symbol
4201 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
4202   StringRef Name;
4203   if (check(getParser().parseIdentifier(Name), L,
4204             "expected symbol after directive") ||
4205       parseToken(AsmToken::EndOfStatement))
4206     return true;
4207 
4208   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4209   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
4210   Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
4211 
4212   MCInst Inst;
4213   Inst.setOpcode(AArch64::TLSDESCCALL);
4214   Inst.addOperand(MCOperand::createExpr(Expr));
4215 
4216   getParser().getStreamer().EmitInstruction(Inst, getSTI());
4217   return false;
4218 }
4219 
4220 /// ::= .loh <lohName | lohId> label1, ..., labelN
4221 /// The number of arguments depends on the loh identifier.
4222 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
4223   MCLOHType Kind;
4224   if (getParser().getTok().isNot(AsmToken::Identifier)) {
4225     if (getParser().getTok().isNot(AsmToken::Integer))
4226       return TokError("expected an identifier or a number in directive");
4227     // We successfully get a numeric value for the identifier.
4228     // Check if it is valid.
4229     int64_t Id = getParser().getTok().getIntVal();
4230     if (Id <= -1U && !isValidMCLOHType(Id))
4231       return TokError("invalid numeric identifier in directive");
4232     Kind = (MCLOHType)Id;
4233   } else {
4234     StringRef Name = getTok().getIdentifier();
4235     // We successfully parse an identifier.
4236     // Check if it is a recognized one.
4237     int Id = MCLOHNameToId(Name);
4238 
4239     if (Id == -1)
4240       return TokError("invalid identifier in directive");
4241     Kind = (MCLOHType)Id;
4242   }
4243   // Consume the identifier.
4244   Lex();
4245   // Get the number of arguments of this LOH.
4246   int NbArgs = MCLOHIdToNbArgs(Kind);
4247 
4248   assert(NbArgs != -1 && "Invalid number of arguments");
4249 
4250   SmallVector<MCSymbol *, 3> Args;
4251   for (int Idx = 0; Idx < NbArgs; ++Idx) {
4252     StringRef Name;
4253     if (getParser().parseIdentifier(Name))
4254       return TokError("expected identifier in directive");
4255     Args.push_back(getContext().getOrCreateSymbol(Name));
4256 
4257     if (Idx + 1 == NbArgs)
4258       break;
4259     if (parseToken(AsmToken::Comma,
4260                    "unexpected token in '" + Twine(IDVal) + "' directive"))
4261       return true;
4262   }
4263   if (parseToken(AsmToken::EndOfStatement,
4264                  "unexpected token in '" + Twine(IDVal) + "' directive"))
4265     return true;
4266 
4267   getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4268   return false;
4269 }
4270 
4271 /// parseDirectiveLtorg
4272 ///  ::= .ltorg | .pool
4273 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
4274   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
4275     return true;
4276   getTargetStreamer().emitCurrentConstantPool();
4277   return false;
4278 }
4279 
4280 /// parseDirectiveReq
4281 ///  ::= name .req registername
4282 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
4283   MCAsmParser &Parser = getParser();
4284   Parser.Lex(); // Eat the '.req' token.
4285   SMLoc SRegLoc = getLoc();
4286   unsigned RegNum = tryParseRegister();
4287   bool IsVector = false;
4288 
4289   if (RegNum == static_cast<unsigned>(-1)) {
4290     StringRef Kind;
4291     RegNum = tryMatchVectorRegister(Kind, false);
4292     if (!Kind.empty())
4293       return Error(SRegLoc, "vector register without type specifier expected");
4294     IsVector = true;
4295   }
4296 
4297   if (RegNum == static_cast<unsigned>(-1))
4298     return Error(SRegLoc, "register name or alias expected");
4299 
4300   // Shouldn't be anything else.
4301   if (parseToken(AsmToken::EndOfStatement,
4302                  "unexpected input in .req directive"))
4303     return true;
4304 
4305   auto pair = std::make_pair(IsVector, RegNum);
4306   if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
4307     Warning(L, "ignoring redefinition of register alias '" + Name + "'");
4308 
4309   return false;
4310 }
4311 
4312 /// parseDirectiveUneq
4313 ///  ::= .unreq registername
4314 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
4315   MCAsmParser &Parser = getParser();
4316   if (getTok().isNot(AsmToken::Identifier))
4317     return TokError("unexpected input in .unreq directive.");
4318   RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
4319   Parser.Lex(); // Eat the identifier.
4320   if (parseToken(AsmToken::EndOfStatement))
4321     return addErrorSuffix("in '.unreq' directive");
4322   return false;
4323 }
4324 
4325 bool
4326 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
4327                                     AArch64MCExpr::VariantKind &ELFRefKind,
4328                                     MCSymbolRefExpr::VariantKind &DarwinRefKind,
4329                                     int64_t &Addend) {
4330   ELFRefKind = AArch64MCExpr::VK_INVALID;
4331   DarwinRefKind = MCSymbolRefExpr::VK_None;
4332   Addend = 0;
4333 
4334   if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4335     ELFRefKind = AE->getKind();
4336     Expr = AE->getSubExpr();
4337   }
4338 
4339   const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4340   if (SE) {
4341     // It's a simple symbol reference with no addend.
4342     DarwinRefKind = SE->getKind();
4343     return true;
4344   }
4345 
4346   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4347   if (!BE)
4348     return false;
4349 
4350   SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4351   if (!SE)
4352     return false;
4353   DarwinRefKind = SE->getKind();
4354 
4355   if (BE->getOpcode() != MCBinaryExpr::Add &&
4356       BE->getOpcode() != MCBinaryExpr::Sub)
4357     return false;
4358 
4359   // See if the addend is is a constant, otherwise there's more going
4360   // on here than we can deal with.
4361   auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
4362   if (!AddendExpr)
4363     return false;
4364 
4365   Addend = AddendExpr->getValue();
4366   if (BE->getOpcode() == MCBinaryExpr::Sub)
4367     Addend = -Addend;
4368 
4369   // It's some symbol reference + a constant addend, but really
4370   // shouldn't use both Darwin and ELF syntax.
4371   return ELFRefKind == AArch64MCExpr::VK_INVALID ||
4372          DarwinRefKind == MCSymbolRefExpr::VK_None;
4373 }
4374 
4375 /// Force static initialization.
4376 extern "C" void LLVMInitializeAArch64AsmParser() {
4377   RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget());
4378   RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget());
4379   RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target());
4380 }
4381 
4382 #define GET_REGISTER_MATCHER
4383 #define GET_SUBTARGET_FEATURE_NAME
4384 #define GET_MATCHER_IMPLEMENTATION
4385 #include "AArch64GenAsmMatcher.inc"
4386 
4387 // Define this matcher function after the auto-generated include so we
4388 // have the match class enum definitions.
4389 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
4390                                                       unsigned Kind) {
4391   AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
4392   // If the kind is a token for a literal immediate, check if our asm
4393   // operand matches. This is for InstAliases which have a fixed-value
4394   // immediate in the syntax.
4395   int64_t ExpectedVal;
4396   switch (Kind) {
4397   default:
4398     return Match_InvalidOperand;
4399   case MCK__35_0:
4400     ExpectedVal = 0;
4401     break;
4402   case MCK__35_1:
4403     ExpectedVal = 1;
4404     break;
4405   case MCK__35_12:
4406     ExpectedVal = 12;
4407     break;
4408   case MCK__35_16:
4409     ExpectedVal = 16;
4410     break;
4411   case MCK__35_2:
4412     ExpectedVal = 2;
4413     break;
4414   case MCK__35_24:
4415     ExpectedVal = 24;
4416     break;
4417   case MCK__35_3:
4418     ExpectedVal = 3;
4419     break;
4420   case MCK__35_32:
4421     ExpectedVal = 32;
4422     break;
4423   case MCK__35_4:
4424     ExpectedVal = 4;
4425     break;
4426   case MCK__35_48:
4427     ExpectedVal = 48;
4428     break;
4429   case MCK__35_6:
4430     ExpectedVal = 6;
4431     break;
4432   case MCK__35_64:
4433     ExpectedVal = 64;
4434     break;
4435   case MCK__35_8:
4436     ExpectedVal = 8;
4437     break;
4438   }
4439   if (!Op.isImm())
4440     return Match_InvalidOperand;
4441   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
4442   if (!CE)
4443     return Match_InvalidOperand;
4444   if (CE->getValue() == ExpectedVal)
4445     return Match_Success;
4446   return Match_InvalidOperand;
4447 }
4448 
4449 OperandMatchResultTy
4450 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
4451 
4452   SMLoc S = getLoc();
4453 
4454   if (getParser().getTok().isNot(AsmToken::Identifier)) {
4455     Error(S, "expected register");
4456     return MatchOperand_ParseFail;
4457   }
4458 
4459   int FirstReg = tryParseRegister();
4460   if (FirstReg == -1) {
4461     return MatchOperand_ParseFail;
4462   }
4463   const MCRegisterClass &WRegClass =
4464       AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
4465   const MCRegisterClass &XRegClass =
4466       AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
4467 
4468   bool isXReg = XRegClass.contains(FirstReg),
4469        isWReg = WRegClass.contains(FirstReg);
4470   if (!isXReg && !isWReg) {
4471     Error(S, "expected first even register of a "
4472              "consecutive same-size even/odd register pair");
4473     return MatchOperand_ParseFail;
4474   }
4475 
4476   const MCRegisterInfo *RI = getContext().getRegisterInfo();
4477   unsigned FirstEncoding = RI->getEncodingValue(FirstReg);
4478 
4479   if (FirstEncoding & 0x1) {
4480     Error(S, "expected first even register of a "
4481              "consecutive same-size even/odd register pair");
4482     return MatchOperand_ParseFail;
4483   }
4484 
4485   SMLoc M = getLoc();
4486   if (getParser().getTok().isNot(AsmToken::Comma)) {
4487     Error(M, "expected comma");
4488     return MatchOperand_ParseFail;
4489   }
4490   // Eat the comma
4491   getParser().Lex();
4492 
4493   SMLoc E = getLoc();
4494   int SecondReg = tryParseRegister();
4495   if (SecondReg ==-1) {
4496     return MatchOperand_ParseFail;
4497   }
4498 
4499   if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 ||
4500       (isXReg && !XRegClass.contains(SecondReg)) ||
4501       (isWReg && !WRegClass.contains(SecondReg))) {
4502     Error(E,"expected second odd register of a "
4503              "consecutive same-size even/odd register pair");
4504     return MatchOperand_ParseFail;
4505   }
4506 
4507   unsigned Pair = 0;
4508   if (isXReg) {
4509     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64,
4510            &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
4511   } else {
4512     Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32,
4513            &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
4514   }
4515 
4516   Operands.push_back(AArch64Operand::CreateReg(Pair, false, S, getLoc(),
4517       getContext()));
4518 
4519   return MatchOperand_Success;
4520 }
4521