LCOV - code coverage report
Current view: top level - lib/Target/AArch64/AsmParser - AArch64AsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 1972 2169 90.9 %
Date: 2017-09-14 15:23:50 Functions: 137 150 91.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13