172062f5744557e270a38192554c3126ea5f97434Tim Northover//==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
972062f5744557e270a38192554c3126ea5f97434Tim Northover
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "MCTargetDesc/AArch64AddressingModes.h"
1172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64MCExpr.h"
1219254c49a8752fe8c6fa648a6eb29f20a1f62c8bTim Northover#include "Utils/AArch64BaseInfo.h"
1372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCParser/MCAsmLexer.h"
1472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCParser/MCAsmParser.h"
1572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCContext.h"
17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCExpr.h"
18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCInst.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCRegisterInfo.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCStreamer.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSubtargetInfo.h"
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCSymbol.h"
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCTargetAsmParser.h"
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/SourceMgr.h"
2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/TargetRegistry.h"
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/ErrorHandling.h"
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/raw_ostream.h"
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/SmallString.h"
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/SmallVector.h"
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/STLExtras.h"
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/StringSwitch.h"
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/Twine.h"
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include <cstdio>
3472062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
3572062f5744557e270a38192554c3126ea5f97434Tim Northover
3672062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
3772062f5744557e270a38192554c3126ea5f97434Tim Northover
3872062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64Operand;
3972062f5744557e270a38192554c3126ea5f97434Tim Northover
4072062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64AsmParser : public MCTargetAsmParser {
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesprivate:
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Mnemonic; ///< Instruction mnemonic.
4372062f5744557e270a38192554c3126ea5f97434Tim Northover  MCSubtargetInfo &STI;
4472062f5744557e270a38192554c3126ea5f97434Tim Northover  MCAsmParser &Parser;
4572062f5744557e270a38192554c3126ea5f97434Tim Northover
46cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Map of register aliases registers via the .req directive.
47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  StringMap<std::pair<bool, unsigned> > RegisterReqs;
48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  AArch64TargetStreamer &getTargetStreamer() {
50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return static_cast<AArch64TargetStreamer &>(TS);
52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCAsmParser &getParser() const { return Parser; }
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getLoc() const { return Parser.getTok().getLoc(); }
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode parseCondCodeString(StringRef Cond);
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseCondCode(OperandVector &Operands, bool invertCondCode);
62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned matchRegisterNameAlias(StringRef Name, bool isVector);
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int tryParseRegister();
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int tryMatchVectorRegister(StringRef &Kind, bool expected);
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseRegister(OperandVector &Operands);
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseSymbolicImmVal(const MCExpr *&ImmVal);
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseVectorList(OperandVector &Operands);
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseOperand(OperandVector &Operands, bool isCondCode,
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    bool invertCondCode);
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool showMatchError(SMLoc Loc, unsigned ErrCode);
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseDirectiveWord(unsigned Size, SMLoc L);
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseDirectiveTLSDescCall(SMLoc L);
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseDirectiveLOH(StringRef LOH, SMLoc L);
79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool parseDirectiveLtorg(SMLoc L);
80cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool parseDirectiveReq(StringRef Name, SMLoc L);
82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool parseDirectiveUnreq(SMLoc L);
83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc);
85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               OperandVector &Operands, MCStreamer &Out,
87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               unsigned &ErrorInfo,
88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               bool MatchingInlineAsm) override;
89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// @name Auto-generated Match Functions
90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// {
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
9272062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_ASSEMBLER_HEADER
9372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenAsmMatcher.inc"
9472062f5744557e270a38192554c3126ea5f97434Tim Northover
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// }
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands);
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool tryParseVectorRegister(OperandVector &Operands);
109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
11072062f5744557e270a38192554c3126ea5f97434Tim Northoverpublic:
111b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  enum AArch64MatchResultTy {
112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
113b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover#define GET_OPERAND_DIAGNOSTIC_TYPES
114b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover#include "AArch64GenAsmMatcher.inc"
115b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  };
116715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly  AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 const MCInstrInfo &MII,
118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 const MCTargetOptions &Options)
119715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly      : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
12072062f5744557e270a38192554c3126ea5f97434Tim Northover    MCAsmParserExtension::Initialize(_Parser);
121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Parser.getStreamer().getTargetStreamer() == nullptr)
122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      new AArch64TargetStreamer(Parser.getStreamer());
12372062f5744557e270a38192554c3126ea5f97434Tim Northover
12472062f5744557e270a38192554c3126ea5f97434Tim Northover    // Initialize the set of available features.
12572062f5744557e270a38192554c3126ea5f97434Tim Northover    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
12672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
12772062f5744557e270a38192554c3126ea5f97434Tim Northover
128dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                        SMLoc NameLoc, OperandVector &Operands) override;
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseDirective(AsmToken DirectiveID) override;
132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      unsigned Kind) override;
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static bool classifySymbolRef(const MCExpr *Expr,
136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                AArch64MCExpr::VariantKind &ELFRefKind,
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                MCSymbolRefExpr::VariantKind &DarwinRefKind,
138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                int64_t &Addend);
13972062f5744557e270a38192554c3126ea5f97434Tim Northover};
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} // end anonymous namespace
14172062f5744557e270a38192554c3126ea5f97434Tim Northover
14272062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
14372062f5744557e270a38192554c3126ea5f97434Tim Northover
144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// AArch64Operand - Instances of this class represent a parsed AArch64 machine
145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// instruction.
14672062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64Operand : public MCParsedAsmOperand {
14772062f5744557e270a38192554c3126ea5f97434Tim Northoverprivate:
14872062f5744557e270a38192554c3126ea5f97434Tim Northover  enum KindTy {
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_Immediate,
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_ShiftedImm,
151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_CondCode,
15272062f5744557e270a38192554c3126ea5f97434Tim Northover    k_Register,
153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_VectorList,
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_VectorIndex,
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_Token,
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_SysReg,
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_SysCR,
158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_Prefetch,
15972062f5744557e270a38192554c3126ea5f97434Tim Northover    k_ShiftExtend,
160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_FPImm,
161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    k_Barrier
16272062f5744557e270a38192554c3126ea5f97434Tim Northover  } Kind;
16372062f5744557e270a38192554c3126ea5f97434Tim Northover
16472062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc StartLoc, EndLoc;
16572062f5744557e270a38192554c3126ea5f97434Tim Northover
166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct TokOp {
167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const char *Data;
168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Length;
169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool IsSuffix; // Is the operand actually a suffix on the mnemonic.
170a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
171a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct RegOp {
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned RegNum;
174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isVector;
175a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
176a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct VectorListOp {
178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned RegNum;
179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Count;
180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned NumElements;
181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ElementKind;
182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct VectorIndexOp {
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val;
186a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
187a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
188a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
189a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
190a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
191a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct ShiftedImmOp {
193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *Val;
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ShiftAmount;
195a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
196a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct CondCodeOp {
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64CC::CondCode Code;
199a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
200a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct FPImmOp {
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val; // Encoded 8-bit representation.
203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct BarrierOp {
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val; // Not the enum since not all values have names.
2076a5a667517160ca1b557002a29d08868ae029451Hao Liu  };
2086a5a667517160ca1b557002a29d08868ae029451Hao Liu
209a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct SysRegOp {
210a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
211a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FeatureBits; // We need to pass through information about which
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                          // core we are compiling for so that the SysReg
214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                          // Mappers can appropriately conditionalize.
215a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
216a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct SysCRImmOp {
218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val;
219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct PrefetchOp {
222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val;
223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct ShiftExtendOp {
226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType Type;
227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Amount;
228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool HasExplicitAmount;
229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct ExtendOp {
232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Val;
233a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
234a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
23572062f5744557e270a38192554c3126ea5f97434Tim Northover  union {
236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct TokOp Tok;
237a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct RegOp Reg;
2386a5a667517160ca1b557002a29d08868ae029451Hao Liu    struct VectorListOp VectorList;
239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct VectorIndexOp VectorIndex;
240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct ImmOp Imm;
241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct ShiftedImmOp ShiftedImm;
242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct CondCodeOp CondCode;
243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct FPImmOp FPImm;
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct BarrierOp Barrier;
245a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct SysRegOp SysReg;
246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct SysCRImmOp SysCRImm;
247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct PrefetchOp Prefetch;
248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    struct ShiftExtendOp ShiftExtend;
24972062f5744557e270a38192554c3126ea5f97434Tim Northover  };
25072062f5744557e270a38192554c3126ea5f97434Tim Northover
251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Keep the MCContext around as the MCExprs may need manipulated during
252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // the add<>Operands() calls.
253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCContext &Ctx;
254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic:
256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64Operand(KindTy K, MCContext &_Ctx)
257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      : MCParsedAsmOperand(), Kind(K), Ctx(_Ctx) {}
25872062f5744557e270a38192554c3126ea5f97434Tim Northover
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Kind = o.Kind;
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StartLoc = o.StartLoc;
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EndLoc = o.EndLoc;
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Kind) {
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Token:
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Tok = o.Tok;
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Immediate:
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Imm = o.Imm;
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_ShiftedImm:
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ShiftedImm = o.ShiftedImm;
272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_CondCode:
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CondCode = o.CondCode;
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_FPImm:
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FPImm = o.FPImm;
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Barrier:
280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Barrier = o.Barrier;
281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Register:
283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Reg = o.Reg;
284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_VectorList:
286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      VectorList = o.VectorList;
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_VectorIndex:
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      VectorIndex = o.VectorIndex;
290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_SysReg:
292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SysReg = o.SysReg;
293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_SysCR:
295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SysCRImm = o.SysCRImm;
296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Prefetch:
298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Prefetch = o.Prefetch;
299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_ShiftExtend:
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ShiftExtend = o.ShiftExtend;
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
30472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
30572062f5744557e270a38192554c3126ea5f97434Tim Northover
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// getStartLoc - Get the location of the first token of this operand.
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getStartLoc() const override { return StartLoc; }
308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// getEndLoc - Get the location of the last token of this operand.
309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getEndLoc() const override { return EndLoc; }
31072062f5744557e270a38192554c3126ea5f97434Tim Northover
31172062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef getToken() const {
31272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(Kind == k_Token && "Invalid access!");
31372062f5744557e270a38192554c3126ea5f97434Tim Northover    return StringRef(Tok.Data, Tok.Length);
31472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
31572062f5744557e270a38192554c3126ea5f97434Tim Northover
316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isTokenSuffix() const {
317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_Token && "Invalid access!");
318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Tok.IsSuffix;
31972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
32072062f5744557e270a38192554c3126ea5f97434Tim Northover
32172062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCExpr *getImm() const {
32272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(Kind == k_Immediate && "Invalid access!");
32372062f5744557e270a38192554c3126ea5f97434Tim Northover    return Imm.Val;
32472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
32572062f5744557e270a38192554c3126ea5f97434Tim Northover
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *getShiftedImmVal() const {
327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_ShiftedImm && "Invalid access!");
328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return ShiftedImm.Val;
32972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
33072062f5744557e270a38192554c3126ea5f97434Tim Northover
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getShiftedImmShift() const {
332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_ShiftedImm && "Invalid access!");
333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return ShiftedImm.ShiftAmount;
33472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
33572062f5744557e270a38192554c3126ea5f97434Tim Northover
336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode getCondCode() const {
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_CondCode && "Invalid access!");
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return CondCode.Code;
33972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
34072062f5744557e270a38192554c3126ea5f97434Tim Northover
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getFPImm() const {
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_FPImm && "Invalid access!");
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return FPImm.Val;
34472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
34572062f5744557e270a38192554c3126ea5f97434Tim Northover
346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getBarrier() const {
347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_Barrier && "Invalid access!");
348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Barrier.Val;
34972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
35072062f5744557e270a38192554c3126ea5f97434Tim Northover
351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getReg() const override {
352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_Register && "Invalid access!");
353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Reg.RegNum;
35472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
35572062f5744557e270a38192554c3126ea5f97434Tim Northover
356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getVectorListStart() const {
357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_VectorList && "Invalid access!");
358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return VectorList.RegNum;
35972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
36072062f5744557e270a38192554c3126ea5f97434Tim Northover
361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getVectorListCount() const {
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_VectorList && "Invalid access!");
363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return VectorList.Count;
36472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
36572062f5744557e270a38192554c3126ea5f97434Tim Northover
366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getVectorIndex() const {
367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_VectorIndex && "Invalid access!");
368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return VectorIndex.Val;
36972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
37072062f5744557e270a38192554c3126ea5f97434Tim Northover
371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef getSysReg() const {
372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_SysReg && "Invalid access!");
373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return StringRef(SysReg.Data, SysReg.Length);
37472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
37572062f5744557e270a38192554c3126ea5f97434Tim Northover
376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t getSysRegFeatureBits() const {
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_SysReg && "Invalid access!");
378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return SysReg.FeatureBits;
37972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
38072062f5744557e270a38192554c3126ea5f97434Tim Northover
381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getSysCR() const {
382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_SysCR && "Invalid access!");
383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return SysCRImm.Val;
38472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
38572062f5744557e270a38192554c3126ea5f97434Tim Northover
386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getPrefetch() const {
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_Prefetch && "Invalid access!");
388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Prefetch.Val;
38972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
39072062f5744557e270a38192554c3126ea5f97434Tim Northover
391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64_AM::ShiftExtendType getShiftExtendType() const {
392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_ShiftExtend && "Invalid access!");
393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return ShiftExtend.Type;
39472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
39572062f5744557e270a38192554c3126ea5f97434Tim Northover
396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getShiftExtendAmount() const {
397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_ShiftExtend && "Invalid access!");
398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return ShiftExtend.Amount;
39972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
40072062f5744557e270a38192554c3126ea5f97434Tim Northover
401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool hasShiftExtendAmount() const {
402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(Kind == k_ShiftExtend && "Invalid access!");
403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return ShiftExtend.HasExplicitAmount;
40472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
40572062f5744557e270a38192554c3126ea5f97434Tim Northover
406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm() const override { return Kind == k_Immediate; }
407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMem() const override { return false; }
408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSImm9() const {
409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
41072062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= -256 && Val < 256);
41672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSImm7s4() const {
418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
42572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSImm7s8() const {
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
43472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSImm7s16() const {
436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
43772062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64MCExpr::VariantKind ELFRefKind;
447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MCSymbolRefExpr::VariantKind DarwinRefKind;
448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Addend;
449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                           Addend)) {
451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // If we don't understand the expression, assume the best and
452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // let the fixup and relocation code deal with it.
453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
45472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
45572062f5744557e270a38192554c3126ea5f97434Tim Northover
456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_LO12 ||
458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) {
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Note that we don't range-check the addend. It's adjusted modulo page
466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // size when converted, so there is no "out of range" condition when using
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // @pageoff.
468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Addend >= 0 && (Addend % Scale) == 0;
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Addend == 0;
47372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
47472062f5744557e270a38192554c3126ea5f97434Tim Northover
475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
47672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
47772062f5744557e270a38192554c3126ea5f97434Tim Northover
478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template <int Scale> bool isUImm12Offset() const {
479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
48172062f5744557e270a38192554c3126ea5f97434Tim Northover
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return isSymbolicUImm12Offset(getImm(), Scale);
48572062f5744557e270a38192554c3126ea5f97434Tim Northover
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
48872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
48972062f5744557e270a38192554c3126ea5f97434Tim Northover
490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm0_7() const {
491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 0 && Val < 8);
49872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm1_8() const {
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val > 0 && Val < 9);
50772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm0_15() const {
509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
51072062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 0 && Val < 16);
51672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm1_16() const {
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
51972062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val > 0 && Val < 17);
52572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm0_31() const {
527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
52872062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 0 && Val < 32);
53472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm1_31() const {
53619fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu    if (!isImm())
53719fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return false;
538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
54019fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu      return false;
541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 1 && Val < 32);
54319fdc268c316b3b0bdcb2b558449819f4f402d6aHao Liu  }
544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm1_32() const {
5451d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier    if (!isImm())
5461d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier      return false;
547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
5491d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier      return false;
550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 1 && Val < 33);
5521d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier  }
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm0_63() const {
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 0 && Val < 64);
561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm1_63() const {
563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 1 && Val < 64);
570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm1_64() const {
572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 1 && Val < 65);
579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm0_127() const {
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 0 && Val < 128);
588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm0_255() const {
590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 0 && Val < 256);
597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm0_65535() const {
599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 0 && Val < 65536);
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm32_63() const {
608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= 32 && Val < 64);
615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isLogicalImm32() const {
617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    int64_t Val = MCE->getValue();
623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Val >> 32 != 0 && Val >> 32 != ~0LL)
624cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
625cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Val &= 0xFFFFFFFF;
626cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return AArch64_AM::isLogicalImmediate(Val, 32);
627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isLogicalImm64() const {
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64);
635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
636cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isLogicalImm32Not() const {
637cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isImm())
638cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
639cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
640cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!MCE)
641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
642cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
643cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return AArch64_AM::isLogicalImmediate(Val, 32);
644cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
645cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isLogicalImm64Not() const {
646cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isImm())
647cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
648cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
649cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!MCE)
650cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return AArch64_AM::isLogicalImmediate(~MCE->getValue(), 64);
652cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isShiftedImm() const { return Kind == k_ShiftedImm; }
654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isAddSubImm() const {
655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShiftedImm() && !isImm())
656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
6571d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier
658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *Expr;
6591d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier
660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isShiftedImm()) {
662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned Shift = ShiftedImm.ShiftAmount;
663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Expr = ShiftedImm.Val;
664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Shift != 0 && Shift != 12)
665dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Expr = getImm();
668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
6691d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier
670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64MCExpr::VariantKind ELFRefKind;
671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MCSymbolRefExpr::VariantKind DarwinRefKind;
672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Addend;
673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          DarwinRefKind, Addend)) {
675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_LO12
679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12;
686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
6871d28917dc39f38847f5c69c0a60cd1491430bdadChad Rosier
688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Otherwise it should be a real immediate in range:
689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *CE = cast<MCConstantExpr>(Expr);
690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return CE->getValue() >= 0 && CE->getValue() <= 0xfff;
691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isCondCode() const { return Kind == k_CondCode; }
693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSIMDImmType10() const {
694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
69587773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
696dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
69887773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
699dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue());
70087773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
701dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isBranchTarget26() const {
702dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
70387773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
708dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Val & 0x3)
70987773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= -(0x2000000 << 2) && Val <= (0x1ffffff << 2));
711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isPCRelLabel19() const {
713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Val & 0x3)
720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= -(0x40000 << 2) && Val <= (0x3ffff << 2));
722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isBranchTarget14() const {
724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val = MCE->getValue();
730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Val & 0x3)
731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2));
73387773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
73487773c318fcee853fb34a80a10c4347d523bdafbTim Northover
735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool
736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const {
737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
73887773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
73987773c318fcee853fb34a80a10c4347d523bdafbTim Northover
740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64MCExpr::VariantKind ELFRefKind;
741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MCSymbolRefExpr::VariantKind DarwinRefKind;
742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Addend;
743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
744dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             DarwinRefKind, Addend)) {
745dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DarwinRefKind != MCSymbolRefExpr::VK_None)
74887773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
74987773c318fcee853fb34a80a10c4347d523bdafbTim Northover
750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (ELFRefKind == AllowedModifiers[i])
752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return Addend == 0;
753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
75487773c318fcee853fb34a80a10c4347d523bdafbTim Northover
755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
7566a5a667517160ca1b557002a29d08868ae029451Hao Liu  }
7576a5a667517160ca1b557002a29d08868ae029451Hao Liu
758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovZSymbolG3() const {
759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = { AArch64MCExpr::VK_ABS_G3 };
760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
76272062f5744557e270a38192554c3126ea5f97434Tim Northover
763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovZSymbolG2() const {
764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = {
765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S,
766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_TPREL_G2, AArch64MCExpr::VK_DTPREL_G2};
767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
76972062f5744557e270a38192554c3126ea5f97434Tim Northover
770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovZSymbolG1() const {
771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = {
772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_ABS_G1,      AArch64MCExpr::VK_ABS_G1_S,
773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1,
774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_DTPREL_G1,
775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    };
776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
77872062f5744557e270a38192554c3126ea5f97434Tim Northover
779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovZSymbolG0() const {
780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = {
781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S,
782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_TPREL_G0, AArch64MCExpr::VK_DTPREL_G0};
783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
78572062f5744557e270a38192554c3126ea5f97434Tim Northover
786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovKSymbolG3() const {
787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = { AArch64MCExpr::VK_ABS_G3 };
788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
78972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
79072062f5744557e270a38192554c3126ea5f97434Tim Northover
791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovKSymbolG2() const {
792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = {
793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCExpr::VK_ABS_G2_NC};
794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
79672062f5744557e270a38192554c3126ea5f97434Tim Northover
797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovKSymbolG1() const {
798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = {
799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64MCExpr::VK_ABS_G1_NC, AArch64MCExpr::VK_TPREL_G1_NC,
800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64MCExpr::VK_DTPREL_G1_NC
801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    };
802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
80472062f5744557e270a38192554c3126ea5f97434Tim Northover
805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovKSymbolG0() const {
806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static AArch64MCExpr::VariantKind Variants[] = {
807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64MCExpr::VK_ABS_G0_NC,   AArch64MCExpr::VK_GOTTPREL_G0_NC,
808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC
809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    };
810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isMovWSymbol(Variants);
81172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
81272062f5744557e270a38192554c3126ea5f97434Tim Northover
813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int RegWidth, int Shift>
814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMOVZMovAlias() const {
81572062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
81672062f5744557e270a38192554c3126ea5f97434Tim Northover
81772062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
81872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t Value = CE->getValue();
82072062f5744557e270a38192554c3126ea5f97434Tim Northover
821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RegWidth == 32)
822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value &= 0xffffffffULL;
82372062f5744557e270a38192554c3126ea5f97434Tim Northover
824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // "lsl #0" takes precedence: in practice this only affects "#0, lsl #0".
825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value == 0 && Shift != 0)
826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
82772062f5744557e270a38192554c3126ea5f97434Tim Northover
828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Value & ~(0xffffULL << Shift)) == 0;
82972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
83072062f5744557e270a38192554c3126ea5f97434Tim Northover
831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int RegWidth, int Shift>
832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMOVNMovAlias() const {
833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm()) return false;
83487773c318fcee853fb34a80a10c4347d523bdafbTim Northover
83587773c318fcee853fb34a80a10c4347d523bdafbTim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!CE) return false;
83787773c318fcee853fb34a80a10c4347d523bdafbTim Northover    uint64_t Value = CE->getValue();
83887773c318fcee853fb34a80a10c4347d523bdafbTim Northover
839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // MOVZ takes precedence over MOVN.
840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (int MOVZShift = 0; MOVZShift <= 48; MOVZShift += 16)
841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if ((Value & ~(0xffffULL << MOVZShift)) == 0)
84287773c318fcee853fb34a80a10c4347d523bdafbTim Northover        return false;
843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value = ~Value;
845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RegWidth == 32)
846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value &= 0xffffffffULL;
847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
848dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Value & ~(0xffffULL << Shift)) == 0;
84987773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
85087773c318fcee853fb34a80a10c4347d523bdafbTim Northover
851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isFPImm() const { return Kind == k_FPImm; }
852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isBarrier() const { return Kind == k_Barrier; }
853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSysReg() const { return Kind == k_SysReg; }
854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMRSSystemRegister() const {
855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isSysReg()) return false;
856591c2f738a3e12026ff5504a486d54fc21fb3049Hao Liu
857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool IsKnownRegister;
858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    auto Mapper = AArch64SysReg::MRSMapper(getSysRegFeatureBits());
859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Mapper.fromString(getSysReg(), IsKnownRegister);
860591c2f738a3e12026ff5504a486d54fc21fb3049Hao Liu
861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return IsKnownRegister;
862591c2f738a3e12026ff5504a486d54fc21fb3049Hao Liu  }
863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMSRSystemRegister() const {
864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isSysReg()) return false;
865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool IsKnownRegister;
867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    auto Mapper = AArch64SysReg::MSRMapper(getSysRegFeatureBits());
868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Mapper.fromString(getSysReg(), IsKnownRegister);
869591c2f738a3e12026ff5504a486d54fc21fb3049Hao Liu
870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return IsKnownRegister;
87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSystemPStateField() const {
873dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isSysReg()) return false;
87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
875dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool IsKnownRegister;
876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64PState::PStateMapper().fromString(getSysReg(), IsKnownRegister);
877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return IsKnownRegister;
879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
880dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isReg() const override { return Kind == k_Register && !Reg.isVector; }
881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isVectorReg() const { return Kind == k_Register && Reg.isVector; }
882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isVectorRegLo() const {
883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_Register && Reg.isVector &&
884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
885dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               Reg.RegNum);
886dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
887dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isGPR32as64() const {
888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_Register && !Reg.isVector &&
889dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
89072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
89172062f5744557e270a38192554c3126ea5f97434Tim Northover
892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isGPR64sp0() const {
893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_Register && !Reg.isVector &&
894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum);
89572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
89672062f5744557e270a38192554c3126ea5f97434Tim Northover
897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Is this a vector list with the type implicit (presumably attached to the
898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// instruction itself)?
899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template <unsigned NumRegs> bool isImplicitlyTypedVectorList() const {
900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_VectorList && VectorList.Count == NumRegs &&
901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           !VectorList.ElementKind;
90272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
90372062f5744557e270a38192554c3126ea5f97434Tim Northover
904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template <unsigned NumRegs, unsigned NumElements, char ElementKind>
905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isTypedVectorList() const {
906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Kind != k_VectorList)
907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (VectorList.Count != NumRegs)
909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (VectorList.ElementKind != ElementKind)
911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return VectorList.NumElements == NumElements;
91372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
91472062f5744557e270a38192554c3126ea5f97434Tim Northover
915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isVectorIndex1() const {
916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_VectorIndex && VectorIndex.Val == 1;
91772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isVectorIndexB() const {
919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_VectorIndex && VectorIndex.Val < 16;
920dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isVectorIndexH() const {
922dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_VectorIndex && VectorIndex.Val < 8;
923dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isVectorIndexS() const {
925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_VectorIndex && VectorIndex.Val < 4;
926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isVectorIndexD() const {
928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_VectorIndex && VectorIndex.Val < 2;
929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isToken() const override { return Kind == k_Token; }
931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isTokenEqual(StringRef Str) const {
932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Kind == k_Token && getToken() == Str;
933dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSysCR() const { return Kind == k_SysCR; }
935dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isPrefetch() const { return Kind == k_Prefetch; }
936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isShiftExtend() const { return Kind == k_ShiftExtend; }
937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isShifter() const {
938dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShiftExtend())
939dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
94072062f5744557e270a38192554c3126ea5f97434Tim Northover
941dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ST = getShiftExtendType();
942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ST == AArch64_AM::ASR || ST == AArch64_AM::ROR ||
944dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ST == AArch64_AM::MSL);
94572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
946dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isExtend() const {
947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShiftExtend())
948dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
94972062f5744557e270a38192554c3126ea5f97434Tim Northover
950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
951dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
952dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
953dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW ||
954dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ET == AArch64_AM::LSL) &&
956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           getShiftExtendAmount() <= 4;
95772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
95872062f5744557e270a38192554c3126ea5f97434Tim Northover
959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isExtend64() const {
960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isExtend())
961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class).
963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX;
965dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
966dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isExtendLSL64() const {
967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isExtend())
968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ET == AArch64_AM::LSL) &&
972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           getShiftExtendAmount() <= 4;
97372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
97472062f5744557e270a38192554c3126ea5f97434Tim Northover
975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int Width> bool isMemXExtend() const {
976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isExtend())
977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
978dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) &&
980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           (getShiftExtendAmount() == Log2_32(Width / 8) ||
981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            getShiftExtendAmount() == 0);
9826a5a667517160ca1b557002a29d08868ae029451Hao Liu  }
9836a5a667517160ca1b557002a29d08868ae029451Hao Liu
984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int Width> bool isMemWExtend() const {
985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isExtend())
986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) &&
989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           (getShiftExtendAmount() == Log2_32(Width / 8) ||
990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            getShiftExtendAmount() == 0);
99172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
99272062f5744557e270a38192554c3126ea5f97434Tim Northover
993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template <unsigned width>
994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isArithmeticShifter() const {
995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShifter())
996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
99772062f5744557e270a38192554c3126ea5f97434Tim Northover
998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // An arithmetic shifter is LSL, LSR, or ASR.
999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ST == AArch64_AM::ASR) && getShiftExtendAmount() < width;
100272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
100372062f5744557e270a38192554c3126ea5f97434Tim Northover
1004dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template <unsigned width>
1005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isLogicalShifter() const {
1006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShifter())
1007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
100872062f5744557e270a38192554c3126ea5f97434Tim Northover
1009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A logical shifter is LSL, LSR, ASR or ROR.
1010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) &&
1013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           getShiftExtendAmount() < width;
101472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
101572062f5744557e270a38192554c3126ea5f97434Tim Northover
1016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovImm32Shifter() const {
1017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShifter())
1018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
101972062f5744557e270a38192554c3126ea5f97434Tim Northover
1020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A MOVi shifter is LSL of 0, 16, 32, or 48.
1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ST != AArch64_AM::LSL)
1023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t Val = getShiftExtendAmount();
1025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val == 0 || Val == 16);
1026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMovImm64Shifter() const {
1029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShifter())
1030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
103172062f5744557e270a38192554c3126ea5f97434Tim Northover
1032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A MOVi shifter is LSL of 0 or 16.
1033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ST != AArch64_AM::LSL)
1035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
1036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t Val = getShiftExtendAmount();
1037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
103872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
103972062f5744557e270a38192554c3126ea5f97434Tim Northover
1040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isLogicalVecShifter() const {
1041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShifter())
1042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
1043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A logical vector shifter is a left shift by 0, 8, 16, or 24.
1045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Shift = getShiftExtendAmount();
1046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return getShiftExtendType() == AArch64_AM::LSL &&
1047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
104872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
104972062f5744557e270a38192554c3126ea5f97434Tim Northover
1050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isLogicalVecHalfWordShifter() const {
1051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isLogicalVecShifter())
1052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
105372062f5744557e270a38192554c3126ea5f97434Tim Northover
1054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A logical vector shifter is a left shift by 0 or 8.
1055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Shift = getShiftExtendAmount();
1056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return getShiftExtendType() == AArch64_AM::LSL &&
1057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           (Shift == 0 || Shift == 8);
105872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
105972062f5744557e270a38192554c3126ea5f97434Tim Northover
1060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMoveVecShifter() const {
1061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isShiftExtend())
1062dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
106372062f5744557e270a38192554c3126ea5f97434Tim Northover
1064dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // A logical vector shifter is a left shift by 8 or 16.
1065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Shift = getShiftExtendAmount();
1066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return getShiftExtendType() == AArch64_AM::MSL &&
1067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           (Shift == 8 || Shift == 16);
1068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
106972062f5744557e270a38192554c3126ea5f97434Tim Northover
1070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Fallback unscaled operands are for aliases of LDR/STR that fall back
1071dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // to LDUR/STUR when the offset is not legal for the former but is for
1072dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // the latter. As such, in addition to checking for being a legal unscaled
1073dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // address, also check that it is not a legal scaled address. This avoids
1074dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // ambiguity in the matcher.
1075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int Width>
1076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isSImm9OffsetFB() const {
1077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isSImm9() && !isUImm12Offset<Width / 8>();
107872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
107972062f5744557e270a38192554c3126ea5f97434Tim Northover
1080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isAdrpLabel() const {
1081dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Validation was handled during parsing, so we just sanity check that
1082dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // something didn't go haywire.
1083dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
1084dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
1085dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1086dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1087dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Val = CE->getValue();
1088dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Min = - (4096 * (1LL << (21 - 1)));
1089dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Max = 4096 * ((1LL << (21 - 1)) - 1);
1090dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return (Val % 4096) == 0 && Val >= Min && Val <= Max;
1091dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1092dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1093dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
109472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
109572062f5744557e270a38192554c3126ea5f97434Tim Northover
1096dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isAdrLabel() const {
1097dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Validation was handled during parsing, so we just sanity check that
1098dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // something didn't go haywire.
1099dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isImm())
1100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
1101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Val = CE->getValue();
1104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Min = - (1LL << (21 - 1));
1105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Max = ((1LL << (21 - 1)) - 1);
1106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Val >= Min && Val <= Max;
1107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
111036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
111136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Add as immediates when possible.  Null MCExpr = 0.
1114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Expr)
1115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Inst.addOperand(MCOperand::CreateImm(0));
1116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
1119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Inst.addOperand(MCOperand::CreateExpr(Expr));
112072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
112172062f5744557e270a38192554c3126ea5f97434Tim Northover
112272062f5744557e270a38192554c3126ea5f97434Tim Northover  void addRegOperands(MCInst &Inst, unsigned N) const {
112372062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
112472062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateReg(getReg()));
112572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
112672062f5744557e270a38192554c3126ea5f97434Tim Northover
1127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
112872062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(
1130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg()));
113172062f5744557e270a38192554c3126ea5f97434Tim Northover
1132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister(
1134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        RI->getEncodingValue(getReg()));
113572062f5744557e270a38192554c3126ea5f97434Tim Northover
1136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(Reg));
113772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
113872062f5744557e270a38192554c3126ea5f97434Tim Northover
1139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
114072062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(
1142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(AArch64::D0 + getReg() - AArch64::Q0));
114472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
114572062f5744557e270a38192554c3126ea5f97434Tim Northover
1146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorReg128Operands(MCInst &Inst, unsigned N) const {
1147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(
1149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(getReg()));
115172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
115272062f5744557e270a38192554c3126ea5f97434Tim Northover
1153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorRegLoOperands(MCInst &Inst, unsigned N) const {
115472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(getReg()));
1156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
115772062f5744557e270a38192554c3126ea5f97434Tim Northover
1158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template <unsigned NumRegs>
1159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorList64Operands(MCInst &Inst, unsigned N) const {
1160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static unsigned FirstRegs[] = { AArch64::D0,       AArch64::D0_D1,
1162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 };
1163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned FirstReg = FirstRegs[NumRegs - 1];
116472062f5744557e270a38192554c3126ea5f97434Tim Northover
1165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(
1166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MCOperand::CreateReg(FirstReg + getVectorListStart() - AArch64::Q0));
1167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
116872062f5744557e270a38192554c3126ea5f97434Tim Northover
1169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template <unsigned NumRegs>
1170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorList128Operands(MCInst &Inst, unsigned N) const {
1171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static unsigned FirstRegs[] = { AArch64::Q0,       AArch64::Q0_Q1,
1173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 };
1174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned FirstReg = FirstRegs[NumRegs - 1];
117572062f5744557e270a38192554c3126ea5f97434Tim Northover
1176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(
1177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MCOperand::CreateReg(FirstReg + getVectorListStart() - AArch64::Q0));
117872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
117972062f5744557e270a38192554c3126ea5f97434Tim Northover
1180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorIndex1Operands(MCInst &Inst, unsigned N) const {
118172062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
118472062f5744557e270a38192554c3126ea5f97434Tim Northover
1185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorIndexBOperands(MCInst &Inst, unsigned N) const {
1186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorIndexHOperands(MCInst &Inst, unsigned N) const {
1191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorIndexSOperands(MCInst &Inst, unsigned N) const {
1196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addVectorIndexDOperands(MCInst &Inst, unsigned N) const {
1201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImmOperands(MCInst &Inst, unsigned N) const {
1206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If this is a pageoff symrefexpr with an addend, adjust the addend
1208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // to be only the page-offset portion. Otherwise, just add the expr
1209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // as-is.
1210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    addExpr(Inst, getImm());
1211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addAddSubImmOperands(MCInst &Inst, unsigned N) const {
1214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 2 && "Invalid number of operands!");
1215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isShiftedImm()) {
1216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      addExpr(Inst, getShiftedImmVal());
1217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Inst.addOperand(MCOperand::CreateImm(getShiftedImmShift()));
121872062f5744557e270a38192554c3126ea5f97434Tim Northover    } else {
1219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      addExpr(Inst, getImm());
1220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Inst.addOperand(MCOperand::CreateImm(0));
122172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
122272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
122372062f5744557e270a38192554c3126ea5f97434Tim Northover
1224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getCondCode()));
1227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
122872062f5744557e270a38192554c3126ea5f97434Tim Northover
1229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addAdrpLabelOperands(MCInst &Inst, unsigned N) const {
1230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE)
1233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      addExpr(Inst, getImm());
1234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
1235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Inst.addOperand(MCOperand::CreateImm(MCE->getValue() >> 12));
1236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
123772062f5744557e270a38192554c3126ea5f97434Tim Northover
1238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    addImmOperands(Inst, N);
124072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
124172062f5744557e270a38192554c3126ea5f97434Tim Northover
1242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int Scale>
1243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
124472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
124672062f5744557e270a38192554c3126ea5f97434Tim Northover
1247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
1248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
1250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / Scale));
1252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
125372062f5744557e270a38192554c3126ea5f97434Tim Northover
1254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addSImm9Operands(MCInst &Inst, unsigned N) const {
1255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
125972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
126072062f5744557e270a38192554c3126ea5f97434Tim Northover
1261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addSImm7s4Operands(MCInst &Inst, unsigned N) const {
126272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 4));
1266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
126772062f5744557e270a38192554c3126ea5f97434Tim Northover
1268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addSImm7s8Operands(MCInst &Inst, unsigned N) const {
1269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 8));
1273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
127472062f5744557e270a38192554c3126ea5f97434Tim Northover
1275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addSImm7s16Operands(MCInst &Inst, unsigned N) const {
1276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 16));
128072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
128172062f5744557e270a38192554c3126ea5f97434Tim Northover
1282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
128372062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
128872062f5744557e270a38192554c3126ea5f97434Tim Northover
1289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm1_8Operands(MCInst &Inst, unsigned N) const {
1290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
129572062f5744557e270a38192554c3126ea5f97434Tim Northover
1296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
1297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
130172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
130272062f5744557e270a38192554c3126ea5f97434Tim Northover
1303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
130972062f5744557e270a38192554c3126ea5f97434Tim Northover
1310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
1311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
131672062f5744557e270a38192554c3126ea5f97434Tim Northover
1317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm1_31Operands(MCInst &Inst, unsigned N) const {
1318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
132372062f5744557e270a38192554c3126ea5f97434Tim Northover
1324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
1325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
132972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
133072062f5744557e270a38192554c3126ea5f97434Tim Northover
1331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm0_63Operands(MCInst &Inst, unsigned N) const {
1332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
133772062f5744557e270a38192554c3126ea5f97434Tim Northover
1338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm1_63Operands(MCInst &Inst, unsigned N) const {
1339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
134472062f5744557e270a38192554c3126ea5f97434Tim Northover
1345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm1_64Operands(MCInst &Inst, unsigned N) const {
1346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
135172062f5744557e270a38192554c3126ea5f97434Tim Northover
1352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm0_127Operands(MCInst &Inst, unsigned N) const {
1353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
135872062f5744557e270a38192554c3126ea5f97434Tim Northover
1359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
1360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
136472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
136572062f5744557e270a38192554c3126ea5f97434Tim Northover
1366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
136772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
137272062f5744557e270a38192554c3126ea5f97434Tim Northover
1373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addImm32_63Operands(MCInst &Inst, unsigned N) const {
1374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue()));
1378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
137972062f5744557e270a38192554c3126ea5f97434Tim Northover
1380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addLogicalImm32Operands(MCInst &Inst, unsigned N) const {
1381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid logical immediate operand!");
1384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    uint64_t encoding =
1385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32);
1386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(encoding));
138772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
138872062f5744557e270a38192554c3126ea5f97434Tim Northover
1389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addLogicalImm64Operands(MCInst &Inst, unsigned N) const {
139072062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid logical immediate operand!");
1393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
1394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(encoding));
1395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
139672062f5744557e270a38192554c3126ea5f97434Tim Northover
1397cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void addLogicalImm32NotOperands(MCInst &Inst, unsigned N) const {
1398cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    assert(N == 1 && "Invalid number of operands!");
1399cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
1401cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, 32);
1402cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Inst.addOperand(MCOperand::CreateImm(encoding));
1403cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1404cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1405cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void addLogicalImm64NotOperands(MCInst &Inst, unsigned N) const {
1406cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    assert(N == 1 && "Invalid number of operands!");
1407cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1408cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    uint64_t encoding =
1409cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64);
1410cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Inst.addOperand(MCOperand::CreateImm(encoding));
1411cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1412cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const {
1414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid immediate operand!");
1417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
1418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(encoding));
141972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
142072062f5744557e270a38192554c3126ea5f97434Tim Northover
1421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addBranchTarget26Operands(MCInst &Inst, unsigned N) const {
1422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Branch operands don't encode the low bits, so shift them off
1423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // here. If it's a label, however, just put it on directly as there's
1424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // not enough information now to do anything.
142587773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
1426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
1428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      addExpr(Inst, getImm());
1429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
1430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue() >> 2));
1433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
143487773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const {
1436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Branch operands don't encode the low bits, so shift them off
1437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // here. If it's a label, however, just put it on directly as there's
1438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // not enough information now to do anything.
1439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
1442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      addExpr(Inst, getImm());
1443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
1444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue() >> 2));
1447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
144887773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
1450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Branch operands don't encode the low bits, so shift them off
1451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // here. If it's a label, however, just put it on directly as there's
1452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // not enough information now to do anything.
1453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
1456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      addExpr(Inst, getImm());
1457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
1458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(MCE && "Invalid constant immediate operand!");
1460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(MCE->getValue() >> 2));
146187773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
146287773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addFPImmOperands(MCInst &Inst, unsigned N) const {
146487773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
1465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getFPImm()));
1466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
146787773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addBarrierOperands(MCInst &Inst, unsigned N) const {
1469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getBarrier()));
1471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
147287773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool Valid;
1477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    auto Mapper = AArch64SysReg::MRSMapper(getSysRegFeatureBits());
1478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
1479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(Bits));
148187773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
148287773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
148487773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
148587773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool Valid;
1487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    auto Mapper = AArch64SysReg::MSRMapper(getSysRegFeatureBits());
1488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
148987773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(Bits));
149187773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
149287773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addSystemPStateFieldOperands(MCInst &Inst, unsigned N) const {
1494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool Valid;
1497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint32_t Bits =
1498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64PState::PStateMapper().fromString(getSysReg(), Valid);
1499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(Bits));
150172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
150272062f5744557e270a38192554c3126ea5f97434Tim Northover
1503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addSysCROperands(MCInst &Inst, unsigned N) const {
150472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getSysCR()));
1506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
150772062f5744557e270a38192554c3126ea5f97434Tim Northover
1508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addPrefetchOperands(MCInst &Inst, unsigned N) const {
1509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getPrefetch()));
1511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
151272062f5744557e270a38192554c3126ea5f97434Tim Northover
1513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addShifterOperands(MCInst &Inst, unsigned N) const {
1514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Imm =
1516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
1517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(Imm));
1518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
151972062f5744557e270a38192554c3126ea5f97434Tim Northover
1520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addExtendOperands(MCInst &Inst, unsigned N) const {
1521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
1522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW;
1524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(Imm));
152672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addExtend64Operands(MCInst &Inst, unsigned N) const {
152972062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
1530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX;
1532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(Imm));
1534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
153572062f5744557e270a38192554c3126ea5f97434Tim Northover
1536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addMemExtendOperands(MCInst &Inst, unsigned N) const {
1537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 2 && "Invalid number of operands!");
1538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(IsSigned));
1541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(getShiftExtendAmount() != 0));
154272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
154387773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // For 8-bit load/store instructions with a register offset, both the
1545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // "DoShift" and "NoShift" variants have a shift of 0. Because of this,
1546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // they're disambiguated by whether the shift was explicit or implicit rather
1547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // than its size.
1548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addMemExtend8Operands(MCInst &Inst, unsigned N) const {
1549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 2 && "Invalid number of operands!");
1550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(IsSigned));
1553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm(hasShiftExtendAmount()));
1554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int Shift>
1557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const {
155887773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
155987773c318fcee853fb34a80a10c4347d523bdafbTim Northover
1560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
156187773c318fcee853fb34a80a10c4347d523bdafbTim Northover    uint64_t Value = CE->getValue();
1562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm((Value >> Shift) & 0xffff));
156387773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
15646a5a667517160ca1b557002a29d08868ae029451Hao Liu
1565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  template<int Shift>
1566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const {
15676a5a667517160ca1b557002a29d08868ae029451Hao Liu    assert(N == 1 && "Invalid number of operands!");
1568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t Value = CE->getValue();
1571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateImm((~Value >> Shift) & 0xffff));
15726a5a667517160ca1b557002a29d08868ae029451Hao Liu  }
157372062f5744557e270a38192554c3126ea5f97434Tim Northover
1574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void print(raw_ostream &OS) const override;
157572062f5744557e270a38192554c3126ea5f97434Tim Northover
1576cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand>
1577cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) {
1578cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
1579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Tok.Data = Str.data();
1580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Tok.Length = Str.size();
1581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Tok.IsSuffix = IsSuffix;
1582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = S;
1584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
158672062f5744557e270a38192554c3126ea5f97434Tim Northover
1587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand>
1588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateReg(unsigned RegNum, bool isVector, SMLoc S, SMLoc E, MCContext &Ctx) {
1589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Reg.RegNum = RegNum;
1591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Reg.isVector = isVector;
1592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
159672062f5744557e270a38192554c3126ea5f97434Tim Northover
1597cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand>
1598cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements,
1599cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                   char ElementKind, SMLoc S, SMLoc E, MCContext &Ctx) {
1600cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
1601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->VectorList.RegNum = RegNum;
1602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->VectorList.Count = Count;
1603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->VectorList.NumElements = NumElements;
1604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->VectorList.ElementKind = ElementKind;
1605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
160972062f5744557e270a38192554c3126ea5f97434Tim Northover
1610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand>
1611cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
1612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
1613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->VectorIndex.Val = Idx;
1614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
161872062f5744557e270a38192554c3126ea5f97434Tim Northover
1619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S,
1620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                   SMLoc E, MCContext &Ctx) {
1621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
1622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Imm.Val = Val;
1623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
162772062f5744557e270a38192554c3126ea5f97434Tim Northover
1628cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val,
1629cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                          unsigned ShiftAmount,
1630cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                          SMLoc S, SMLoc E,
1631cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                          MCContext &Ctx) {
1632cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
1633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->ShiftedImm .Val = Val;
1634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->ShiftedImm.ShiftAmount = ShiftAmount;
1635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
163972062f5744557e270a38192554c3126ea5f97434Tim Northover
1640cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand>
1641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
1642cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
1643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->CondCode.Code = Code;
1644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
164772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
164872062f5744557e270a38192554c3126ea5f97434Tim Northover
1649cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand> CreateFPImm(unsigned Val, SMLoc S,
1650cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                     MCContext &Ctx) {
1651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
1652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->FPImm.Val = Val;
1653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = S;
1655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
165772062f5744557e270a38192554c3126ea5f97434Tim Northover
1658cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val, SMLoc S,
1659cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                       MCContext &Ctx) {
1660cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
1661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Barrier.Val = Val;
1662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = S;
1664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
166572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
166672062f5744557e270a38192554c3126ea5f97434Tim Northover
1667cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand>
1668cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateSysReg(StringRef Str, SMLoc S, uint64_t FeatureBits, MCContext &Ctx) {
1669cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
1670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->SysReg.Data = Str.data();
1671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->SysReg.Length = Str.size();
1672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->SysReg.FeatureBits = FeatureBits;
1673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = S;
1675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
167672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1678cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
1679cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                     SMLoc E, MCContext &Ctx) {
1680cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
1681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->SysCRImm.Val = Val;
1682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
168572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
168672062f5744557e270a38192554c3126ea5f97434Tim Northover
1687cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val, SMLoc S,
1688cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                        MCContext &Ctx) {
1689cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
1690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Prefetch.Val = Val;
1691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = S;
1693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
169572062f5744557e270a38192554c3126ea5f97434Tim Northover
1696cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<AArch64Operand>
1697cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
1698cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                    bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
1699cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
1700dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->ShiftExtend.Type = ShOp;
1701dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->ShiftExtend.Amount = Val;
1702dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1703dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->StartLoc = S;
1704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->EndLoc = E;
1705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Op;
1706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
170872062f5744557e270a38192554c3126ea5f97434Tim Northover
1709dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} // end anonymous namespace.
171072062f5744557e270a38192554c3126ea5f97434Tim Northover
1711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64Operand::print(raw_ostream &OS) const {
1712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Kind) {
1713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_FPImm:
1714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<fpimm " << getFPImm() << "("
1715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       << AArch64_AM::getFPImmFloat(getFPImm()) << ") >";
1716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_Barrier: {
1718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool Valid;
1719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef Name = AArch64DB::DBarrierMapper().toString(getBarrier(), Valid);
1720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Valid)
1721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << "<barrier " << Name << ">";
1722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
1723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << "<barrier invalid #" << getBarrier() << ">";
1724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_Immediate:
1727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getImm()->print(OS);
1728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_ShiftedImm: {
1730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Shift = getShiftedImmShift();
1731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<shiftedimm ";
1732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getShiftedImmVal()->print(OS);
1733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
1734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_CondCode:
1737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<condcode " << getCondCode() << ">";
1738dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_Register:
1740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<register " << getReg() << ">";
1741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_VectorList: {
1743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<vectorlist ";
1744dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Reg = getVectorListStart();
1745dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned i = 0, e = getVectorListCount(); i != e; ++i)
1746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << Reg + i << " ";
1747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << ">";
1748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_VectorIndex:
1751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<vectorindex " << getVectorIndex() << ">";
1752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_SysReg:
1754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<sysreg: " << getSysReg() << '>';
1755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_Token:
1757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "'" << getToken() << "'";
1758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_SysCR:
1760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "c" << getSysCR();
1761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_Prefetch: {
1763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool Valid;
1764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef Name = AArch64PRFM::PRFMMapper().toString(getPrefetch(), Valid);
1765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Valid)
1766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << "<prfop " << Name << ">";
1767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
1768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << "<prfop invalid #" << getPrefetch() << ">";
1769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case k_ShiftExtend: {
1772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
1773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       << getShiftExtendAmount();
1774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!hasShiftExtendAmount())
1775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << "<imp>";
1776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << '>';
1777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
1778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
177972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// @name Auto-generated Match Functions
1783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// {
1784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned MatchRegisterName(StringRef Name);
178672062f5744557e270a38192554c3126ea5f97434Tim Northover
1787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// }
1788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned matchVectorRegName(StringRef Name) {
1790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return StringSwitch<unsigned>(Name)
1791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v0", AArch64::Q0)
1792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v1", AArch64::Q1)
1793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v2", AArch64::Q2)
1794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v3", AArch64::Q3)
1795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v4", AArch64::Q4)
1796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v5", AArch64::Q5)
1797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v6", AArch64::Q6)
1798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v7", AArch64::Q7)
1799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v8", AArch64::Q8)
1800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v9", AArch64::Q9)
1801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v10", AArch64::Q10)
1802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v11", AArch64::Q11)
1803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v12", AArch64::Q12)
1804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v13", AArch64::Q13)
1805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v14", AArch64::Q14)
1806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v15", AArch64::Q15)
1807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v16", AArch64::Q16)
1808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v17", AArch64::Q17)
1809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v18", AArch64::Q18)
1810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v19", AArch64::Q19)
1811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v20", AArch64::Q20)
1812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v21", AArch64::Q21)
1813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v22", AArch64::Q22)
1814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v23", AArch64::Q23)
1815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v24", AArch64::Q24)
1816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v25", AArch64::Q25)
1817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v26", AArch64::Q26)
1818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v27", AArch64::Q27)
1819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v28", AArch64::Q28)
1820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v29", AArch64::Q29)
1821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v30", AArch64::Q30)
1822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case("v31", AArch64::Q31)
1823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Default(0);
182472062f5744557e270a38192554c3126ea5f97434Tim Northover}
182572062f5744557e270a38192554c3126ea5f97434Tim Northover
1826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool isValidVectorKind(StringRef Name) {
1827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return StringSwitch<bool>(Name.lower())
1828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".8b", true)
1829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".16b", true)
1830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".4h", true)
1831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".8h", true)
1832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".2s", true)
1833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".4s", true)
1834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".1d", true)
1835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".2d", true)
1836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".1q", true)
1837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Accept the width neutral ones, too, for verbose syntax. If those
1838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // aren't used in the right places, the token operand won't match so
1839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // all will work out.
1840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".b", true)
1841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".h", true)
1842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".s", true)
1843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Case(".d", true)
1844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .Default(false);
1845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
184672062f5744557e270a38192554c3126ea5f97434Tim Northover
1847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void parseValidVectorKind(StringRef Name, unsigned &NumElements,
1848dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 char &ElementKind) {
1849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(isValidVectorKind(Name));
185072062f5744557e270a38192554c3126ea5f97434Tim Northover
1851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ElementKind = Name.lower()[Name.size() - 1];
1852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  NumElements = 0;
185372062f5744557e270a38192554c3126ea5f97434Tim Northover
1854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Name.size() == 2)
1855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Parse the lane count
1858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Name = Name.drop_front();
1859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (isdigit(Name.front())) {
1860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    NumElements = 10 * NumElements + (Name.front() - '0');
1861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Name = Name.drop_front();
186272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
186472062f5744557e270a38192554c3126ea5f97434Tim Northover
1865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     SMLoc &EndLoc) {
1867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StartLoc = getLoc();
1868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RegNo = tryParseRegister();
1869dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
1870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return (RegNo == (unsigned)-1);
1871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
187272062f5744557e270a38192554c3126ea5f97434Tim Northover
1873cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// Matches a register name or register alias previously defined by '.req'
1874cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesunsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
1875cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                  bool isVector) {
1876cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned RegNum = isVector ? matchVectorRegName(Name)
1877cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                             : MatchRegisterName(Name);
1878cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1879cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (RegNum == 0) {
1880cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // Check for aliases registered via .req. Canonicalize to lower case.
1881cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // That's more consistent since register names are case insensitive, and
1882cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // it's how the original entry was passed in from MC/MCParser/AsmParser.
1883cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Entry = RegisterReqs.find(Name.lower());
1884cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Entry == RegisterReqs.end())
1885cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return 0;
1886cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // set RegNum if the match is the right kind of register
1887cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (isVector == Entry->getValue().first)
1888cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      RegNum = Entry->getValue().second;
1889cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1890cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return RegNum;
1891cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1892cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseRegister - Try to parse a register name. The token must be an
1894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Identifier when called, and if it is a register name the token is eaten and
1895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// the register is added to the operand list.
1896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesint AArch64AsmParser::tryParseRegister() {
1897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AsmToken &Tok = Parser.getTok();
1898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  std::string lowerCase = Tok.getString().lower();
1901cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned RegNum = matchRegisterNameAlias(lowerCase, false);
1902dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Also handle a few aliases of registers.
1903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (RegNum == 0)
1904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RegNum = StringSwitch<unsigned>(lowerCase)
1905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 .Case("fp",  AArch64::FP)
1906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 .Case("lr",  AArch64::LR)
1907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 .Case("x31", AArch64::XZR)
1908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 .Case("w31", AArch64::WZR)
1909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 .Default(0);
1910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (RegNum == 0)
1912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return -1;
1913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat identifier token.
1915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return RegNum;
1916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
191772062f5744557e270a38192554c3126ea5f97434Tim Northover
1918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryMatchVectorRegister - Try to parse a vector register name with optional
1919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// kind specifier. If it is a register specifier, eat the token and return it.
1920dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesint AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) {
1921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().isNot(AsmToken::Identifier)) {
1922dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("vector register expected");
1923dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return -1;
1924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Name = Parser.getTok().getString();
1927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If there is a kind specifier, it's separated from the register name by
1928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // a '.'.
1929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  size_t Start = 0, Next = Name.find('.');
1930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Head = Name.slice(Start, Next);
1931cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned RegNum = matchRegisterNameAlias(Head, true);
1932cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1933dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (RegNum) {
1934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Next != StringRef::npos) {
1935dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Kind = Name.slice(Next, StringRef::npos);
1936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!isValidVectorKind(Kind)) {
1937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        TokError("invalid vector kind qualifier");
1938dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return -1;
1939dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
1940dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1941dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat the register token.
1942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return RegNum;
194372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
194472062f5744557e270a38192554c3126ea5f97434Tim Northover
1945dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (expected)
1946dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("vector register expected");
1947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return -1;
194872062f5744557e270a38192554c3126ea5f97434Tim Northover}
194972062f5744557e270a38192554c3126ea5f97434Tim Northover
1950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseSysCROperand - Try to parse a system instruction CR operand name.
195172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
1952dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
1953dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
195472062f5744557e270a38192554c3126ea5f97434Tim Northover
1955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().isNot(AsmToken::Identifier)) {
1956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(S, "Expected cN operand where 0 <= N <= 15");
195772062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
195872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
195972062f5744557e270a38192554c3126ea5f97434Tim Northover
1960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Tok = Parser.getTok().getIdentifier();
1961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Tok[0] != 'c' && Tok[0] != 'C') {
1962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(S, "Expected cN operand where 0 <= N <= 15");
196372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
196472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
196572062f5744557e270a38192554c3126ea5f97434Tim Northover
1966dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t CRNum;
1967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
1968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (BadNum || CRNum > 15) {
1969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(S, "Expected cN operand where 0 <= N <= 15");
197072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
197172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
1972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat identifier token.
1974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
1975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
197672062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
197772062f5744557e270a38192554c3126ea5f97434Tim Northover}
197872062f5744557e270a38192554c3126ea5f97434Tim Northover
1979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParsePrefetch - Try to parse a prefetch operand.
198072062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
1981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
1982dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
1983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AsmToken &Tok = Parser.getTok();
1984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Either an identifier for named values or a 5-bit immediate.
1985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Hash = Tok.is(AsmToken::Hash);
1986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Hash || Tok.is(AsmToken::Integer)) {
1987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Hash)
1988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex(); // Eat hash token.
1989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *ImmVal;
1990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getParser().parseExpression(ImmVal))
1991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
199272062f5744557e270a38192554c3126ea5f97434Tim Northover
1993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
1994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
1995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TokError("immediate value expected for prefetch operand");
1996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
1997dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned prfop = MCE->getValue();
1999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (prfop > 31) {
2000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TokError("prefetch operand out of range, [0,31] expected");
2001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
2002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
200336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2004dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreatePrefetch(prfop, S, getContext()));
2005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_Success;
2006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
200772062f5744557e270a38192554c3126ea5f97434Tim Northover
2008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Tok.isNot(AsmToken::Identifier)) {
2009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("pre-fetch hint expected");
201072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
201172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
201272062f5744557e270a38192554c3126ea5f97434Tim Northover
2013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Valid;
2014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned prfop = AArch64PRFM::PRFMMapper().fromString(Tok.getString(), Valid);
2015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Valid) {
2016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("pre-fetch hint expected");
2017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
201972062f5744557e270a38192554c3126ea5f97434Tim Northover
2020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat identifier token.
2021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(AArch64Operand::CreatePrefetch(prfop, S, getContext()));
2022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return MatchOperand_Success;
2023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
202472062f5744557e270a38192554c3126ea5f97434Tim Northover
2025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// instruction.
2027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::OperandMatchResultTy
2028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *Expr;
203172062f5744557e270a38192554c3126ea5f97434Tim Northover
2032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::Hash)) {
2033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat hash token.
203472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
203572062f5744557e270a38192554c3126ea5f97434Tim Northover
2036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (parseSymbolicImmVal(Expr))
203772062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
2038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64MCExpr::VariantKind ELFRefKind;
2040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCSymbolRefExpr::VariantKind DarwinRefKind;
2041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t Addend;
2042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ELFRefKind == AArch64MCExpr::VK_INVALID) {
2045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // No modifier was specified at all; this is the syntax for an ELF basic
2046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // ADRP relocation (unfortunately).
2047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Expr =
2048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64MCExpr::Create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
2049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               Addend != 0) {
2052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(S, "gotpage label reference not allowed an addend");
2053dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
2054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
2058dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
2059dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
2060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The operand must be an @page or @gotpage qualified symbolref.
2061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(S, "page or gotpage label reference expected");
2062dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
2063dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
206472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
206572062f5744557e270a38192554c3126ea5f97434Tim Northover
2066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We have either a label reference possibly with addend or an immediate. The
2067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // addend is a raw value here. The linker will adjust it to only reference the
2068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // page.
2069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2071dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
207272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
207372062f5744557e270a38192554c3126ea5f97434Tim Northover}
207472062f5744557e270a38192554c3126ea5f97434Tim Northover
2075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseAdrLabel - Parse and validate a source label for the ADR
2076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// instruction.
207772062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
2078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *Expr;
208172062f5744557e270a38192554c3126ea5f97434Tim Northover
2082dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::Hash)) {
2083dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat hash token.
2084dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
208572062f5744557e270a38192554c3126ea5f97434Tim Northover
2086dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getParser().parseExpression(Expr))
2087dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
208872062f5744557e270a38192554c3126ea5f97434Tim Northover
2089dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2090dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
209172062f5744557e270a38192554c3126ea5f97434Tim Northover
209272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
209372062f5744557e270a38192554c3126ea5f97434Tim Northover}
209472062f5744557e270a38192554c3126ea5f97434Tim Northover
2095dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseFPImm - A floating point immediate expression operand.
209672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
2097dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
2098dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
209972062f5744557e270a38192554c3126ea5f97434Tim Northover
2100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Hash = false;
2101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::Hash)) {
2102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat '#'
2103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Hash = true;
210472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
210572062f5744557e270a38192554c3126ea5f97434Tim Northover
2106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Handle negation, as that still comes through as a separate token.
2107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isNegative = false;
2108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::Minus)) {
2109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    isNegative = true;
2110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex();
2111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AsmToken &Tok = Parser.getTok();
2113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Tok.is(AsmToken::Real)) {
2114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
2115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If we had a '-' in front, toggle the sign bit.
2117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IntVal ^= (uint64_t)isNegative << 63;
2118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat the token.
2120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check for out of range values. As an exception, we let Zero through,
2121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // as we handle that special case in post-processing before matching in
2122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // order to use the zero register for it.
2123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Val == -1 && !RealVal.isZero()) {
2124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TokError("expected compatible register or floating-point constant");
2125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
2126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_Success;
2129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Tok.is(AsmToken::Integer)) {
2131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Val;
2132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isNegative && Tok.getString().startswith("0x")) {
2133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Val = Tok.getIntVal();
2134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Val > 255 || Val < 0) {
2135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        TokError("encoded floating point value out of range");
2136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return MatchOperand_ParseFail;
2137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
2138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
2139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
2140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // If we had a '-' in front, toggle the sign bit.
2142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      IntVal ^= (uint64_t)isNegative << 63;
2143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat the token.
2146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_Success;
214872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
214972062f5744557e270a38192554c3126ea5f97434Tim Northover
2150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Hash)
2151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_NoMatch;
215272062f5744557e270a38192554c3126ea5f97434Tim Northover
2153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TokError("invalid floating point immediate");
2154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return MatchOperand_ParseFail;
215572062f5744557e270a38192554c3126ea5f97434Tim Northover}
215672062f5744557e270a38192554c3126ea5f97434Tim Northover
2157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand
215872062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
2159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
2160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::Hash))
2163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat '#'
2164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else if (Parser.getTok().isNot(AsmToken::Integer))
2165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Operand should start from # or should be integer, emit error otherwise.
2166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_NoMatch;
2167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *Imm;
2169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (parseSymbolicImmVal(Imm))
2170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else if (Parser.getTok().isNot(AsmToken::Comma)) {
2172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t ShiftAmount = 0;
2173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm);
2174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MCE) {
2175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Val = MCE->getValue();
2176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Val > 0xfff && (Val & 0xfff) == 0) {
2177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Imm = MCConstantExpr::Create(Val >> 12, getContext());
2178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ShiftAmount = 12;
2179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
2180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc E = Parser.getTok().getLoc();
2182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
2183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                        getContext()));
2184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_Success;
2185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Eat ','
2188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex();
2189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The optional operand must be "lsl #N" where N is non-negative.
2191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Parser.getTok().is(AsmToken::Identifier) ||
2192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      !Parser.getTok().getIdentifier().equals_lower("lsl")) {
2193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
219672062f5744557e270a38192554c3126ea5f97434Tim Northover
2197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Eat 'lsl'
2198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex();
219936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
220036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.getTok().is(AsmToken::Hash)) {
2201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex();
220236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
220372062f5744557e270a38192554c3126ea5f97434Tim Northover
2204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().isNot(AsmToken::Integer)) {
2205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
220772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
220872062f5744557e270a38192554c3126ea5f97434Tim Northover
2209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t ShiftAmount = Parser.getTok().getIntVal();
2210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (ShiftAmount < 0) {
2212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(Parser.getTok().getLoc(), "positive shift amount required");
221372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
221472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
2215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat the number
221672062f5744557e270a38192554c3126ea5f97434Tim Northover
221772062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc E = Parser.getTok().getLoc();
2218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                      S, E, getContext()));
222072062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
222172062f5744557e270a38192554c3126ea5f97434Tim Northover}
222272062f5744557e270a38192554c3126ea5f97434Tim Northover
2223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// parseCondCodeString - Parse a Condition Code string.
2224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
2225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
2226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("eq", AArch64CC::EQ)
2227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("ne", AArch64CC::NE)
2228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("cs", AArch64CC::HS)
2229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("hs", AArch64CC::HS)
2230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("cc", AArch64CC::LO)
2231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("lo", AArch64CC::LO)
2232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("mi", AArch64CC::MI)
2233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("pl", AArch64CC::PL)
2234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("vs", AArch64CC::VS)
2235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("vc", AArch64CC::VC)
2236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("hi", AArch64CC::HI)
2237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("ls", AArch64CC::LS)
2238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("ge", AArch64CC::GE)
2239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("lt", AArch64CC::LT)
2240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("gt", AArch64CC::GT)
2241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("le", AArch64CC::LE)
2242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("al", AArch64CC::AL)
2243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Case("nv", AArch64CC::NV)
2244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    .Default(AArch64CC::Invalid);
2245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return CC;
2246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
224736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// parseCondCode - Parse a Condition Code operand.
2249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseCondCode(OperandVector &Operands,
2250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     bool invertCondCode) {
2251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AsmToken &Tok = Parser.getTok();
2253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
225436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Cond = Tok.getString();
2256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode CC = parseCondCodeString(Cond);
2257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (CC == AArch64CC::Invalid)
2258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return TokError("invalid condition code");
2259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat identifier token.
226036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (invertCondCode) {
2262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (CC == AArch64CC::AL || CC == AArch64CC::NV)
2263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return TokError("condition codes AL and NV are invalid for this instruction");
2264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
2265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
2268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
2270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseOptionalShift - Some operands take an optional shift argument. Parse
2273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// them if present.
2274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::OperandMatchResultTy
2275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
2276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AsmToken &Tok = Parser.getTok();
2277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  std::string LowerID = Tok.getString().lower();
2278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64_AM::ShiftExtendType ShOp =
2279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
2280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("lsl", AArch64_AM::LSL)
2281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("lsr", AArch64_AM::LSR)
2282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("asr", AArch64_AM::ASR)
2283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("ror", AArch64_AM::ROR)
2284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("msl", AArch64_AM::MSL)
2285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("uxtb", AArch64_AM::UXTB)
2286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("uxth", AArch64_AM::UXTH)
2287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("uxtw", AArch64_AM::UXTW)
2288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("uxtx", AArch64_AM::UXTX)
2289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("sxtb", AArch64_AM::SXTB)
2290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("sxth", AArch64_AM::SXTH)
2291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("sxtw", AArch64_AM::SXTW)
2292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("sxtx", AArch64_AM::SXTX)
2293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Default(AArch64_AM::InvalidShiftExtend);
2294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (ShOp == AArch64_AM::InvalidShiftExtend)
2296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_NoMatch;
2297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = Tok.getLoc();
2299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex();
2300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Hash = getLexer().is(AsmToken::Hash);
2302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Hash && getLexer().isNot(AsmToken::Integer)) {
2303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
2304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
2305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ShOp == AArch64_AM::MSL) {
2306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // We expect a number here.
2307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TokError("expected #imm after shift specifier");
230836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return MatchOperand_ParseFail;
230936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
2310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // "extend" type operatoins don't need an immediate, #0 is implicit.
2312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(
2314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
2315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_Success;
231636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
2317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Hash)
2319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat the '#'.
2320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Make sure we do actually have a number
2322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Parser.getTok().is(AsmToken::Integer)) {
2323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(Parser.getTok().getLoc(),
2324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          "expected integer shift amount");
232536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_ParseFail;
232636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
232736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *ImmVal;
2329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getParser().parseExpression(ImmVal))
2330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!MCE) {
2334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("expected #imm after shift specifier");
2335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
233736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(AArch64Operand::CreateShiftExtend(
2340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ShOp, MCE->getValue(), true, S, E, getContext()));
234136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_Success;
234236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
234372062f5744557e270a38192554c3126ea5f97434Tim Northover
2344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
2345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// the SYS instruction. Parse them specially so that we create a SYS MCInst.
2346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
2347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   OperandVector &Operands) {
2348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Name.find('.') != StringRef::npos)
2349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return TokError("invalid operand");
235072062f5744557e270a38192554c3126ea5f97434Tim Northover
2351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Mnemonic = Name;
2352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
2353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateToken("sys", false, NameLoc, getContext()));
235472062f5744557e270a38192554c3126ea5f97434Tim Northover
2355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AsmToken &Tok = Parser.getTok();
2356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Op = Tok.getString();
235772062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Tok.getLoc();
235872062f5744557e270a38192554c3126ea5f97434Tim Northover
2359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *Expr = nullptr;
2360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define SYS_ALIAS(op1, Cn, Cm, op2)                                            \
2362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  do {                                                                         \
2363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Expr = MCConstantExpr::Create(op1, getContext());                          \
2364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(                                                        \
2365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));           \
2366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(                                                        \
2367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));           \
2368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(                                                        \
2369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));           \
2370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Expr = MCConstantExpr::Create(op2, getContext());                          \
2371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(                                                        \
2372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));           \
2373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } while (0)
2374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Mnemonic == "ic") {
2376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Op.compare_lower("ialluis")) {
2377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C1, #0
2378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 1, 0);
2379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("iallu")) {
2380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C5, #0
2381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 5, 0);
2382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("ivau")) {
2383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #3, C7, C5, #1
2384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(3, 7, 5, 1);
2385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
2386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("invalid operand for IC instruction");
2387630c5e06d633fad142af4b145ee684e90754700eTim Northover    }
2388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (Mnemonic == "dc") {
2389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Op.compare_lower("zva")) {
2390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #3, C7, C4, #1
2391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(3, 7, 4, 1);
2392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("ivac")) {
2393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #3, C7, C6, #1
2394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 6, 1);
2395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("isw")) {
2396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C6, #2
2397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 6, 2);
2398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("cvac")) {
2399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #3, C7, C10, #1
2400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(3, 7, 10, 1);
2401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("csw")) {
2402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C10, #2
2403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 10, 2);
2404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("cvau")) {
2405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #3, C7, C11, #1
2406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(3, 7, 11, 1);
2407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("civac")) {
2408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #3, C7, C14, #1
2409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(3, 7, 14, 1);
2410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("cisw")) {
2411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C14, #2
2412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 14, 2);
2413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
2414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("invalid operand for DC instruction");
2415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (Mnemonic == "at") {
2417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Op.compare_lower("s1e1r")) {
2418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C8, #0
2419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 8, 0);
2420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s1e2r")) {
2421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C7, C8, #0
2422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 7, 8, 0);
2423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s1e3r")) {
2424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C7, C8, #0
2425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 7, 8, 0);
2426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s1e1w")) {
2427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C8, #1
2428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 8, 1);
2429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s1e2w")) {
2430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C7, C8, #1
2431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 7, 8, 1);
2432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s1e3w")) {
2433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C7, C8, #1
2434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 7, 8, 1);
2435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s1e0r")) {
2436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C8, #3
2437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 8, 2);
2438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s1e0w")) {
2439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C7, C8, #3
2440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 7, 8, 3);
2441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s12e1r")) {
2442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C7, C8, #4
2443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 7, 8, 4);
2444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s12e1w")) {
2445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C7, C8, #5
2446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 7, 8, 5);
2447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s12e0r")) {
2448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C7, C8, #6
2449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 7, 8, 6);
2450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("s12e0w")) {
2451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C7, C8, #7
2452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 7, 8, 7);
2453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
2454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("invalid operand for AT instruction");
2455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (Mnemonic == "tlbi") {
2457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Op.compare_lower("vmalle1is")) {
2458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C3, #0
2459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 3, 0);
2460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("alle2is")) {
2461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C3, #0
2462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 3, 0);
2463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("alle3is")) {
2464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C8, C3, #0
2465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 8, 3, 0);
2466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vae1is")) {
2467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C3, #1
2468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 3, 1);
2469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vae2is")) {
2470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C3, #1
2471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 3, 1);
2472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vae3is")) {
2473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C8, C3, #1
2474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 8, 3, 1);
2475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("aside1is")) {
2476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C3, #2
2477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 3, 2);
2478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vaae1is")) {
2479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C3, #3
2480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 3, 3);
2481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("alle1is")) {
2482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C3, #4
2483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 3, 4);
2484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vale1is")) {
2485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C3, #5
2486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 3, 5);
2487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vaale1is")) {
2488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C3, #7
2489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 3, 7);
2490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vmalle1")) {
2491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C7, #0
2492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 7, 0);
2493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("alle2")) {
2494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C7, #0
2495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 7, 0);
2496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vale2is")) {
2497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C3, #5
2498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 3, 5);
2499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vale3is")) {
2500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C8, C3, #5
2501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 8, 3, 5);
2502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("alle3")) {
2503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C8, C7, #0
2504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 8, 7, 0);
2505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vae1")) {
2506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C7, #1
2507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 7, 1);
2508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vae2")) {
2509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C7, #1
2510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 7, 1);
2511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vae3")) {
2512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C8, C7, #1
2513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 8, 7, 1);
2514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("aside1")) {
2515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C7, #2
2516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 7, 2);
2517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vaae1")) {
2518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C7, #3
2519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 7, 3);
2520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("alle1")) {
2521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C7, #4
2522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 7, 4);
2523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vale1")) {
2524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C7, #5
2525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 7, 5);
2526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vale2")) {
2527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C7, #5
2528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 7, 5);
2529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vale3")) {
2530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #6, C8, C7, #5
2531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(6, 8, 7, 5);
2532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vaale1")) {
2533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #0, C8, C7, #7
2534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(0, 8, 7, 7);
2535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("ipas2e1")) {
2536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C4, #1
2537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 4, 1);
2538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("ipas2le1")) {
2539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C4, #5
2540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 4, 5);
2541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("ipas2e1is")) {
2542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C4, #1
2543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 0, 1);
2544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("ipas2le1is")) {
2545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C4, #5
2546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 0, 5);
2547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vmalls12e1")) {
2548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C7, #6
2549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 7, 6);
2550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (!Op.compare_lower("vmalls12e1is")) {
2551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // SYS #4, C8, C3, #6
2552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SYS_ALIAS(4, 8, 3, 6);
2553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
2554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("invalid operand for TLBI instruction");
255572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
255672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
255772062f5744557e270a38192554c3126ea5f97434Tim Northover
2558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#undef SYS_ALIAS
2559630c5e06d633fad142af4b145ee684e90754700eTim Northover
2560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat operand.
256172062f5744557e270a38192554c3126ea5f97434Tim Northover
2562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
2563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool HasRegister = false;
256472062f5744557e270a38192554c3126ea5f97434Tim Northover
2565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check for the optional register operand.
2566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getLexer().is(AsmToken::Comma)) {
2567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat comma.
256872062f5744557e270a38192554c3126ea5f97434Tim Northover
2569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
2570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("expected register operand");
257172062f5744557e270a38192554c3126ea5f97434Tim Northover
2572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    HasRegister = true;
257372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
257472062f5744557e270a38192554c3126ea5f97434Tim Northover
2575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.eatToEndOfStatement();
2577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return TokError("unexpected token in argument list");
2578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
257972062f5744557e270a38192554c3126ea5f97434Tim Northover
2580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (ExpectRegister && !HasRegister) {
2581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return TokError("specified " + Mnemonic + " op requires a register");
2582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else if (!ExpectRegister && HasRegister) {
2584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return TokError("specified " + Mnemonic + " op does not use a register");
2585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
258672062f5744557e270a38192554c3126ea5f97434Tim Northover
2587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Consume the EndOfStatement
258872062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
258972062f5744557e270a38192554c3126ea5f97434Tim Northover}
259072062f5744557e270a38192554c3126ea5f97434Tim Northover
259172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
2592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
259372062f5744557e270a38192554c3126ea5f97434Tim Northover  const AsmToken &Tok = Parser.getTok();
259472062f5744557e270a38192554c3126ea5f97434Tim Northover
2595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Can be either a #imm style literal or an option name
2596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Hash = Tok.is(AsmToken::Hash);
2597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Hash || Tok.is(AsmToken::Integer)) {
2598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Immediate operand.
2599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Hash)
2600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex(); // Eat the '#'
2601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *ImmVal;
2602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc ExprLoc = getLoc();
2603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getParser().parseExpression(ImmVal))
2604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
2605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
2607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(ExprLoc, "immediate value expected for barrier operand");
260872062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_ParseFail;
260972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
2610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (MCE->getValue() < 0 || MCE->getValue() > 15) {
2611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(ExprLoc, "barrier operand out of range");
2612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return MatchOperand_ParseFail;
2613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(
2615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateBarrier(MCE->getValue(), ExprLoc, getContext()));
261672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
2617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
261872062f5744557e270a38192554c3126ea5f97434Tim Northover
2619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Tok.isNot(AsmToken::Identifier)) {
2620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("invalid operand for instruction");
2621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
262372062f5744557e270a38192554c3126ea5f97434Tim Northover
2624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool Valid;
2625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opt = AArch64DB::DBarrierMapper().fromString(Tok.getString(), Valid);
2626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Valid) {
2627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("invalid barrier option name");
2628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
263072062f5744557e270a38192554c3126ea5f97434Tim Northover
2631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The only valid named option for ISB is 'sy'
2632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Mnemonic == "isb" && Opt != AArch64DB::SY) {
2633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TokError("'sy' or #imm operand expected");
2634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
263572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
263672062f5744557e270a38192554c3126ea5f97434Tim Northover
2637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
2638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateBarrier(Opt, getLoc(), getContext()));
2639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Consume the option
2640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return MatchOperand_Success;
264272062f5744557e270a38192554c3126ea5f97434Tim Northover}
264372062f5744557e270a38192554c3126ea5f97434Tim Northover
264472062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
2645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
264672062f5744557e270a38192554c3126ea5f97434Tim Northover  const AsmToken &Tok = Parser.getTok();
264772062f5744557e270a38192554c3126ea5f97434Tim Northover
2648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Tok.isNot(AsmToken::Identifier))
264972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_NoMatch;
265072062f5744557e270a38192554c3126ea5f97434Tim Northover
2651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(AArch64Operand::CreateSysReg(Tok.getString(), getLoc(),
2652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     STI.getFeatureBits(), getContext()));
265372062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat identifier
265472062f5744557e270a38192554c3126ea5f97434Tim Northover
265572062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
265672062f5744557e270a38192554c3126ea5f97434Tim Northover}
265772062f5744557e270a38192554c3126ea5f97434Tim Northover
2658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// tryParseVectorRegister - Parse a vector register operand.
2659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
2660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().isNot(AsmToken::Identifier))
2661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
266272062f5744557e270a38192554c3126ea5f97434Tim Northover
2663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check for a vector register specifier first.
2665dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Kind;
2666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t Reg = tryMatchVectorRegister(Kind, false);
2667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Reg == -1)
2668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
2669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
2670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
2671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If there was an explicit qualifier, that goes on as a literal text
2672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // operand.
2673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Kind.empty())
2674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(
2675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateToken(Kind, false, S, getContext()));
2676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If there is an index specifier following the register, parse that too.
2678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::LBrac)) {
2679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc SIdx = getLoc();
2680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat left bracket token.
268172062f5744557e270a38192554c3126ea5f97434Tim Northover
2682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *ImmVal;
2683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getParser().parseExpression(ImmVal))
2684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
2685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
2687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TokError("immediate value expected for vector index");
2688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
2689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
269072062f5744557e270a38192554c3126ea5f97434Tim Northover
2691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc E = getLoc();
2692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(E, "']' expected");
2694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
2695dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
269672062f5744557e270a38192554c3126ea5f97434Tim Northover
2697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat right bracket token.
269872062f5744557e270a38192554c3126ea5f97434Tim Northover
2699dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2700dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         E, getContext()));
270172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
270272062f5744557e270a38192554c3126ea5f97434Tim Northover
2703dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
270472062f5744557e270a38192554c3126ea5f97434Tim Northover}
270572062f5744557e270a38192554c3126ea5f97434Tim Northover
2706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// parseRegister - Parse a non-vector register operand.
2707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseRegister(OperandVector &Operands) {
2708dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2709dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Try for a vector register.
2710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!tryParseVectorRegister(Operands))
2711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
271272062f5744557e270a38192554c3126ea5f97434Tim Northover
2713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Try for a scalar register.
2714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t Reg = tryParseRegister();
2715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Reg == -1)
2716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
2717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
2718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
271972062f5744557e270a38192554c3126ea5f97434Tim Northover
2720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // A small number of instructions (FMOVXDhighr, for example) have "[1]"
2721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // as a string token in the instruction itself.
2722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getLexer().getKind() == AsmToken::LBrac) {
2723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc LBracS = getLoc();
2724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex();
2725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const AsmToken &Tok = Parser.getTok();
2726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Tok.is(AsmToken::Integer)) {
2727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SMLoc IntS = getLoc();
2728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Val = Tok.getIntVal();
2729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Val == 1) {
2730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Parser.Lex();
2731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (getLexer().getKind() == AsmToken::RBrac) {
2732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          SMLoc RBracS = getLoc();
2733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Parser.Lex();
2734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Operands.push_back(
2735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              AArch64Operand::CreateToken("[", false, LBracS, getContext()));
2736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Operands.push_back(
2737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              AArch64Operand::CreateToken("1", false, IntS, getContext()));
2738dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Operands.push_back(
2739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              AArch64Operand::CreateToken("]", false, RBracS, getContext()));
2740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          return false;
2741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
2742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
274372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
274472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
274572062f5744557e270a38192554c3126ea5f97434Tim Northover
2746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
2747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
274872062f5744557e270a38192554c3126ea5f97434Tim Northover
2749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
2750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool HasELFModifier = false;
2751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64MCExpr::VariantKind RefKind;
275272062f5744557e270a38192554c3126ea5f97434Tim Northover
2753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::Colon)) {
2754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat ':"
2755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    HasELFModifier = true;
275672062f5744557e270a38192554c3126ea5f97434Tim Northover
2757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Parser.getTok().isNot(AsmToken::Identifier)) {
2758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(Parser.getTok().getLoc(),
2759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            "expect relocation specifier in operand after ':'");
2760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
2761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
276272062f5744557e270a38192554c3126ea5f97434Tim Northover
2763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::string LowerCase = Parser.getTok().getIdentifier().lower();
2764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
2765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("lo12", AArch64MCExpr::VK_LO12)
2766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
2767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
2768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
2769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
2770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
2771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
2772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
2773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
2774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
2775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
2776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
2777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
2778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
2779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
2780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
2781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
2782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
2783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
2784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
2785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
2786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
2787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
2788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
2789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
2790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
2791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
2792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
2793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("got", AArch64MCExpr::VK_GOT_PAGE)
2794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
2795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
2796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
2797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
2798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
2799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
2800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  .Default(AArch64MCExpr::VK_INVALID);
2801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RefKind == AArch64MCExpr::VK_INVALID) {
2803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(Parser.getTok().getLoc(),
2804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            "expect relocation specifier in operand after ':'");
2805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
2806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
28076a5a667517160ca1b557002a29d08868ae029451Hao Liu
2808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat identifier
28096a5a667517160ca1b557002a29d08868ae029451Hao Liu
2810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Parser.getTok().isNot(AsmToken::Colon)) {
2811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(Parser.getTok().getLoc(), "expect ':' after relocation specifier");
2812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
2813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat ':'
28156a5a667517160ca1b557002a29d08868ae029451Hao Liu  }
28166a5a667517160ca1b557002a29d08868ae029451Hao Liu
2817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getParser().parseExpression(ImmVal))
2818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
2819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (HasELFModifier)
2821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ImmVal = AArch64MCExpr::Create(ImmVal, RefKind, getContext());
2822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
2824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
2827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
2828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
2829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat left bracket token.
2831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Kind;
2832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t FirstReg = tryMatchVectorRegister(Kind, true);
2833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (FirstReg == -1)
2834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
2835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t PrevReg = FirstReg;
2836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Count = 1;
28376a5a667517160ca1b557002a29d08868ae029451Hao Liu
28386a5a667517160ca1b557002a29d08868ae029451Hao Liu  if (Parser.getTok().is(AsmToken::Minus)) {
28396a5a667517160ca1b557002a29d08868ae029451Hao Liu    Parser.Lex(); // Eat the minus.
28406a5a667517160ca1b557002a29d08868ae029451Hao Liu
2841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc Loc = getLoc();
2842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef NextKind;
2843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Reg = tryMatchVectorRegister(NextKind, true);
2844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Reg == -1)
2845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
2846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Any Kind suffices must match on all regs in the list.
2847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Kind != NextKind)
2848dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc, "mismatched register size suffix");
28496a5a667517160ca1b557002a29d08868ae029451Hao Liu
2850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
28516a5a667517160ca1b557002a29d08868ae029451Hao Liu
28526a5a667517160ca1b557002a29d08868ae029451Hao Liu    if (Space == 0 || Space > 3) {
2853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc, "invalid number of vectors");
28546a5a667517160ca1b557002a29d08868ae029451Hao Liu    }
28556a5a667517160ca1b557002a29d08868ae029451Hao Liu
28566a5a667517160ca1b557002a29d08868ae029451Hao Liu    Count += Space;
2857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else {
28596a5a667517160ca1b557002a29d08868ae029451Hao Liu    while (Parser.getTok().is(AsmToken::Comma)) {
2860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex(); // Eat the comma token.
28616a5a667517160ca1b557002a29d08868ae029451Hao Liu
2862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SMLoc Loc = getLoc();
2863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      StringRef NextKind;
2864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Reg = tryMatchVectorRegister(NextKind, true);
2865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Reg == -1)
2866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return true;
2867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Any Kind suffices must match on all regs in the list.
2868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Kind != NextKind)
2869dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return Error(Loc, "mismatched register size suffix");
2870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Registers must be incremental (with wraparound at 31)
2872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2873dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2874dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       return Error(Loc, "registers must be sequential");
28756a5a667517160ca1b557002a29d08868ae029451Hao Liu
2876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      PrevReg = Reg;
2877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ++Count;
28786a5a667517160ca1b557002a29d08868ae029451Hao Liu    }
28796a5a667517160ca1b557002a29d08868ae029451Hao Liu  }
28806a5a667517160ca1b557002a29d08868ae029451Hao Liu
2881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().isNot(AsmToken::RCurly))
2882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(getLoc(), "'}' expected");
2883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat the '}' token.
28846a5a667517160ca1b557002a29d08868ae029451Hao Liu
2885dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Count > 4)
2886dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(S, "invalid number of vectors");
2887dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumElements = 0;
2889dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  char ElementKind = 0;
2890dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Kind.empty())
2891dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    parseValidVectorKind(Kind, NumElements, ElementKind);
28926a5a667517160ca1b557002a29d08868ae029451Hao Liu
2893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(AArch64Operand::CreateVectorList(
2894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If there is an index specifier following the list, parse that too.
289736c7806f4eacd676932ba630246f88e0e37b1cd4Hao Liu  if (Parser.getTok().is(AsmToken::LBrac)) {
2898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc SIdx = getLoc();
2899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat left bracket token.
2900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *ImmVal;
2902dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getParser().parseExpression(ImmVal))
2903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
2904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MCE) {
2906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      TokError("immediate value expected for vector index");
2907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
290836c7806f4eacd676932ba630246f88e0e37b1cd4Hao Liu    }
2909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc E = getLoc();
2911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Error(E, "']' expected");
2913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
2914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat right bracket token.
2917dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                         E, getContext()));
292036c7806f4eacd676932ba630246f88e0e37b1cd4Hao Liu  }
2921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
29226a5a667517160ca1b557002a29d08868ae029451Hao Liu}
29236a5a667517160ca1b557002a29d08868ae029451Hao Liu
2924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::OperandMatchResultTy
2925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
2926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AsmToken &Tok = Parser.getTok();
2927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Tok.is(AsmToken::Identifier))
2928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_NoMatch;
2929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2930cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false);
2931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCContext &Ctx = getContext();
2933dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
2935dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_NoMatch;
2936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S = getLoc();
2938dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat register
2939dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2940dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().isNot(AsmToken::Comma)) {
2941dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(
2942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_Success;
294472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
2945dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat comma.
2946dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().is(AsmToken::Hash))
2948dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat hash
2949dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.getTok().isNot(AsmToken::Integer)) {
2951dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(getLoc(), "index must be absent or #0");
2952dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2953dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2954dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *ImmVal;
2956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
2957dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
2958dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error(getLoc(), "index must be absent or #0");
2959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return MatchOperand_ParseFail;
2960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
2963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return MatchOperand_Success;
2965dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
296672062f5744557e270a38192554c3126ea5f97434Tim Northover
2967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// parseOperand - Parse a arm instruction operand.  For now this parses the
2968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// operand regardless of the mnemonic.
2969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
2970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                  bool invertCondCode) {
2971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check if the current operand has a custom associated parser, if so, try to
2972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // custom parse the operand, or fallback to the general approach.
2973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (ResTy == MatchOperand_Success)
297572062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
2976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If there wasn't a custom match, try the generic matcher below. Otherwise,
2977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // there was a match, but an error occurred, in which case, just return that
2978dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // the operand parsing failed.
2979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (ResTy == MatchOperand_ParseFail)
2980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
2981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2982dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Nothing custom, so do general case parsing.
2983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc S, E;
2984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (getLexer().getKind()) {
2985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default: {
2986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc S = getLoc();
2987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *Expr;
2988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (parseSymbolicImmVal(Expr))
2989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(S, "invalid operand");
2990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2992dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
299372062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
299472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
2995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AsmToken::LBrac: {
2996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc Loc = Parser.getTok().getLoc();
2997dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
2998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                   getContext()));
2999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Parser.Lex(); // Eat '['
3000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // There's no comma after a '[', so we can parse the next operand
3002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // immediately.
3003dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseOperand(Operands, false, false);
300472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
3005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AsmToken::LCurly:
3006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseVectorList(Operands);
3007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AsmToken::Identifier: {
3008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If we're expecting a Condition Code operand, then just parse that.
3009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isCondCode)
3010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return parseCondCode(Operands, invertCondCode);
3011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If it's a register name, parse it.
3013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!parseRegister(Operands))
3014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
3015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // This could be an optional "shift" or "extend" operand.
3017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We can only continue if no tokens were eaten.
3019dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (GotShift != MatchOperand_NoMatch)
3020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return GotShift;
3021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // This was not a register so parse other operands that start with an
3023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // identifier (like labels) as expressions and create them as immediates.
3024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *IdVal;
3025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    S = getLoc();
3026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getParser().parseExpression(IdVal))
3027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
3028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
303172062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
303272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
3033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AsmToken::Integer:
3034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AsmToken::Real:
3035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AsmToken::Hash: {
3036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // #42 -> immediate.
3037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    S = getLoc();
3038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getLexer().is(AsmToken::Hash))
3039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex();
3040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Parse a negative sign
3042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isNegative = false;
3043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Parser.getTok().is(AsmToken::Minus)) {
3044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      isNegative = true;
3045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // We need to consume this token only when we have a Real, otherwise
3046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // we let parseSymbolicImmVal take care of it
3047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Parser.getLexer().peekTok().is(AsmToken::Real))
3048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Parser.Lex();
3049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // The only Real that should come through here is a literal #0.0 for
3052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3053dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // so convert the value.
3054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const AsmToken &Tok = Parser.getTok();
3055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Tok.is(AsmToken::Real)) {
3056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
3057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3058dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3059dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Mnemonic != "fcmlt")
3061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return TokError("unexpected floating point literal");
3062dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      else if (IntVal != 0 || isNegative)
3063dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return TokError("expected floating-point constant #0.0");
3064dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex(); // Eat the token.
3065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Operands.push_back(
3067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64Operand::CreateToken("#0", false, S, getContext()));
3068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Operands.push_back(
3069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64Operand::CreateToken(".0", false, S, getContext()));
3070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
307172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
3072dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3073dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCExpr *ImmVal;
3074dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (parseSymbolicImmVal(ImmVal))
3075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
3076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
307972062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
308072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
3081cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case AsmToken::Equal: {
3082cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SMLoc Loc = Parser.getTok().getLoc();
3083cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3084cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return Error(Loc, "unexpected token in operand");
3085cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.Lex(); // Eat '='
3086cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const MCExpr *SubExprVal;
3087cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (getParser().parseExpression(SubExprVal))
3088cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return true;
3089cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
3090cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MCContext& Ctx = getContext();
3091cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3092cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // If the op is an imm and can be fit into a mov, then replace ldr with mov.
3093cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (isa<MCConstantExpr>(SubExprVal) && Operands.size() >= 2 &&
3094cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        static_cast<AArch64Operand &>(*Operands[1]).isReg()) {
3095cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      bool IsXReg =  AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3096cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            Operands[1]->getReg());
3097cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3098cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3099cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        ShiftAmt += 16;
3101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Imm >>= 16;
3102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
3103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          Operands.push_back(AArch64Operand::CreateImm(
3106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                     MCConstantExpr::Create(Imm, Ctx), S, E, Ctx));
3107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        if (ShiftAmt)
3108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                     ShiftAmt, true, S, E, Ctx));
3110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return false;
3111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
3112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
3113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // If it is a label or an imm that cannot fit in a movz, put it into CP.
3114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal);
3115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
3117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
311872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
311972062f5744557e270a38192554c3126ea5f97434Tim Northover}
312072062f5744557e270a38192554c3126ea5f97434Tim Northover
3121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// operands.
312372062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
312472062f5744557e270a38192554c3126ea5f97434Tim Northover                                        StringRef Name, SMLoc NameLoc,
3125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        OperandVector &Operands) {
3126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Name = StringSwitch<StringRef>(Name.lower())
3127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("beq", "b.eq")
3128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bne", "b.ne")
3129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bhs", "b.hs")
3130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bcs", "b.cs")
3131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("blo", "b.lo")
3132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bcc", "b.cc")
3133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bmi", "b.mi")
3134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bpl", "b.pl")
3135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bvs", "b.vs")
3136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bvc", "b.vc")
3137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bhi", "b.hi")
3138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bls", "b.ls")
3139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bge", "b.ge")
3140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("blt", "b.lt")
3141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bgt", "b.gt")
3142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("ble", "b.le")
3143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bal", "b.al")
3144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Case("bnv", "b.nv")
3145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             .Default(Name);
3146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // First check for the AArch64-specific .req directive.
3148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Parser.getTok().is(AsmToken::Identifier) &&
3149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Parser.getTok().getIdentifier() == ".req") {
3150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    parseDirectiveReq(Name, NameLoc);
3151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // We always return 'error' for this, as we're done with this
3152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // statement and don't need to match the 'instruction."
3153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return true;
3154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
3155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
3156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Create the leading tokens for the mnemonic, split by '.' characters.
3157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  size_t Start = 0, Next = Name.find('.');
3158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StringRef Head = Name.slice(Start, Next);
3159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi") {
3162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool IsError = parseSysAlias(Head, NameLoc, Operands);
3163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (IsError && getLexer().isNot(AsmToken::EndOfStatement))
3164cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
3165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return IsError;
316672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
316772062f5744557e270a38192554c3126ea5f97434Tim Northover
3168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Operands.push_back(
3169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Mnemonic = Head;
3171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Handle condition codes for a branch mnemonic
3173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Head == "b" && Next != StringRef::npos) {
3174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Start = Next;
3175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Next = Name.find('.', Start + 1);
3176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Head = Name.slice(Start + 1, Next);
3177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            (Head.data() - Name.data()));
3180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    AArch64CC::CondCode CC = parseCondCodeString(Head);
3181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (CC == AArch64CC::Invalid)
3182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(SuffixLoc, "invalid condition code");
3183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(
3184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(
3186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Add the remaining tokens in the mnemonic.
3190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (Next != StringRef::npos) {
3191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Start = Next;
3192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Next = Name.find('.', Start + 1);
3193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Head = Name.slice(Start, Next);
3194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            (Head.data() - Name.data()) + 1);
3196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(
3197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Conditional compare instructions have a Condition Code operand, which needs
3201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // to be parsed and an immediate operand created.
3202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool condCodeFourthOperand =
3203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       Head == "csinc" || Head == "csinv" || Head == "csneg");
3206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // These instructions are aliases to some of the conditional select
3208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // instructions. However, the condition code is inverted in the aliased
3209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // instruction.
3210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
3211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Is this the correct way to handle these? Or should the parser
3212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        generate the aliased instructions directly?
3213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool condCodeThirdOperand =
3215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      (Head == "cinc" || Head == "cinv" || Head == "cneg");
3216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Read the remaining operands.
321872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::EndOfStatement)) {
321972062f5744557e270a38192554c3126ea5f97434Tim Northover    // Read the first operand.
3220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (parseOperand(Operands, false, false)) {
3221cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
322272062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
322372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
322472062f5744557e270a38192554c3126ea5f97434Tim Northover
3225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned N = 2;
322672062f5744557e270a38192554c3126ea5f97434Tim Northover    while (getLexer().is(AsmToken::Comma)) {
3227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex(); // Eat the comma.
322872062f5744557e270a38192554c3126ea5f97434Tim Northover
322972062f5744557e270a38192554c3126ea5f97434Tim Northover      // Parse and remember the operand.
3230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     (N == 3 && condCodeThirdOperand) ||
3232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     (N == 2 && condCodeSecondOperand),
3233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                       condCodeSecondOperand || condCodeThirdOperand)) {
3234cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
323572062f5744557e270a38192554c3126ea5f97434Tim Northover        return true;
323672062f5744557e270a38192554c3126ea5f97434Tim Northover      }
323772062f5744557e270a38192554c3126ea5f97434Tim Northover
323872062f5744557e270a38192554c3126ea5f97434Tim Northover      // After successfully parsing some operands there are two special cases to
323972062f5744557e270a38192554c3126ea5f97434Tim Northover      // consider (i.e. notional operands not separated by commas). Both are due
324072062f5744557e270a38192554c3126ea5f97434Tim Northover      // to memory specifiers:
324172062f5744557e270a38192554c3126ea5f97434Tim Northover      //  + An RBrac will end an address for load/store/prefetch
324272062f5744557e270a38192554c3126ea5f97434Tim Northover      //  + An '!' will indicate a pre-indexed operation.
324372062f5744557e270a38192554c3126ea5f97434Tim Northover      //
324472062f5744557e270a38192554c3126ea5f97434Tim Northover      // It's someone else's responsibility to make sure these tokens are sane
324572062f5744557e270a38192554c3126ea5f97434Tim Northover      // in the given context!
324672062f5744557e270a38192554c3126ea5f97434Tim Northover      if (Parser.getTok().is(AsmToken::RBrac)) {
324772062f5744557e270a38192554c3126ea5f97434Tim Northover        SMLoc Loc = Parser.getTok().getLoc();
3248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Operands.push_back(AArch64Operand::CreateToken("]", false, Loc,
3249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                       getContext()));
325072062f5744557e270a38192554c3126ea5f97434Tim Northover        Parser.Lex();
325172062f5744557e270a38192554c3126ea5f97434Tim Northover      }
325272062f5744557e270a38192554c3126ea5f97434Tim Northover
325372062f5744557e270a38192554c3126ea5f97434Tim Northover      if (Parser.getTok().is(AsmToken::Exclaim)) {
325472062f5744557e270a38192554c3126ea5f97434Tim Northover        SMLoc Loc = Parser.getTok().getLoc();
3255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Operands.push_back(AArch64Operand::CreateToken("!", false, Loc,
3256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                       getContext()));
325772062f5744557e270a38192554c3126ea5f97434Tim Northover        Parser.Lex();
325872062f5744557e270a38192554c3126ea5f97434Tim Northover      }
3259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ++N;
326172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
326272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
326372062f5744557e270a38192554c3126ea5f97434Tim Northover
326472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc Loc = Parser.getTok().getLoc();
3266cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
3267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "unexpected token in argument list");
326872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
326972062f5744557e270a38192554c3126ea5f97434Tim Northover
3270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Consume the EndOfStatement
327172062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
327272062f5744557e270a38192554c3126ea5f97434Tim Northover}
327372062f5744557e270a38192554c3126ea5f97434Tim Northover
3274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// FIXME: This entire function is a giant hack to provide us with decent
3275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// operand range validation/diagnostics until TableGen/MC can be extended
3276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// to support autogeneration of this kind of validation.
3277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::validateInstruction(MCInst &Inst,
3278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         SmallVectorImpl<SMLoc> &Loc) {
3279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCRegisterInfo *RI = getContext().getRegisterInfo();
3280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check for indexed addressing modes w/ the base register being the
3281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // same as a destination/source register or pair load where
3282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // the Rt == Rt2. All of those are undefined behaviour.
3283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Inst.getOpcode()) {
3284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSWpre:
3285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPWpost:
3286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPWpre:
3287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPXpost:
3288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPXpre: {
3289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt = Inst.getOperand(1).getReg();
3290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt2 = Inst.getOperand(2).getReg();
3291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rn = Inst.getOperand(3).getReg();
3292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RI->isSubRegisterEq(Rn, Rt))
3293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           "is also a destination");
3295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RI->isSubRegisterEq(Rn, Rt2))
3296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           "is also a destination");
3298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // FALLTHROUGH
3299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPDi:
3301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPQi:
3302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSi:
3303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSWi:
3304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPWi:
3305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPXi: {
3306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt = Inst.getOperand(0).getReg();
3307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt2 = Inst.getOperand(1).getReg();
3308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Rt == Rt2)
3309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPDpost:
3313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPDpre:
3314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPQpost:
3315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPQpre:
3316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSpost:
3317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSpre:
3318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDPSWpost: {
3319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt = Inst.getOperand(1).getReg();
3320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt2 = Inst.getOperand(2).getReg();
3321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Rt == Rt2)
3322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPDpost:
3326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPDpre:
3327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPQpost:
3328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPQpre:
3329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPSpost:
3330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPSpre:
3331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPWpost:
3332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPWpre:
3333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPXpost:
3334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STPXpre: {
3335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt = Inst.getOperand(1).getReg();
3336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt2 = Inst.getOperand(2).getReg();
3337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rn = Inst.getOperand(3).getReg();
3338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RI->isSubRegisterEq(Rn, Rt))
3339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[0], "unpredictable STP instruction, writeback base "
3340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           "is also a source");
3341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RI->isSubRegisterEq(Rn, Rt2))
3342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[1], "unpredictable STP instruction, writeback base "
3343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           "is also a source");
3344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBpre:
3347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBpre:
3348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHpre:
3349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHpre:
3350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWpre:
3351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXpre:
3352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWpre:
3353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXpre:
3354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWpre:
3355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWpre:
3356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXpre:
3357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBBpost:
3358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRBpost:
3359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHHpost:
3360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRHpost:
3361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBWpost:
3362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSBXpost:
3363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHWpost:
3364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSHXpost:
3365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRSWpost:
3366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRWpost:
3367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::LDRXpost: {
3368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt = Inst.getOperand(1).getReg();
3369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rn = Inst.getOperand(2).getReg();
3370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RI->isSubRegisterEq(Rn, Rt))
3371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           "is also a source");
3373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBpost:
3376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBpost:
3377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHpost:
3378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHpost:
3379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWpost:
3380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXpost:
3381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBBpre:
3382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRBpre:
3383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHHpre:
3384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRHpre:
3385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRWpre:
3386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::STRXpre: {
3387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rt = Inst.getOperand(1).getReg();
3388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Rn = Inst.getOperand(2).getReg();
3389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RI->isSubRegisterEq(Rn, Rt))
3390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[0], "unpredictable STR instruction, writeback base "
3391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           "is also a source");
3392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Now check immediate ranges. Separate from the above as there is overlap
3397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // in the instructions being checked and this keeps the nested conditionals
3398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // to a minimum.
3399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Inst.getOpcode()) {
3400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSWri:
3401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDSXri:
3402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDWri:
3403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::ADDXri:
3404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSWri:
3405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBSXri:
3406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBWri:
3407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::SUBXri: {
3408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Annoyingly we can't do this in the isAddSubImm predicate, so there is
3409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // some slight duplication here.
3410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Inst.getOperand(2).isExpr()) {
3411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const MCExpr *Expr = Inst.getOperand(2).getExpr();
3412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64MCExpr::VariantKind ELFRefKind;
3413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MCSymbolRefExpr::VariantKind DarwinRefKind;
3414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Addend;
3415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return Error(Loc[2], "invalid immediate expression");
3417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
3418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Only allow these with ADDXri.
3420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
3422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Inst.getOpcode() == AArch64::ADDXri)
3423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
3424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Only allow these with ADDXri/ADDWri
3426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
3427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
3428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
3429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
3430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
3431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
3432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
3433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
3434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          (Inst.getOpcode() == AArch64::ADDXri ||
3435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Inst.getOpcode() == AArch64::ADDWri))
3436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return false;
3437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Don't allow expressions in the immediate field otherwise
3439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error(Loc[2], "invalid immediate expression");
3440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
3442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
3444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
3445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
3447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
3449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (ErrCode) {
3450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MissingFeature:
3451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "instruction requires a CPU feature not currently enabled");
3453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidOperand:
3454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "invalid operand for instruction");
3455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidSuffix:
3456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "invalid type suffix for instruction");
3457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidCondCode:
3458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected AArch64 condition code");
3459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegExtendSmall:
3460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegExtendLarge:
3463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubSecondSource:
3466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      "expected compatible register, symbol or integer in range [0, 4095]");
3468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_LogicalSecondSource:
3469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected compatible register or logical immediate");
3470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMovImm32Shift:
3471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
3472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMovImm64Shift:
3473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
3474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegShift32:
3475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegShift64:
3478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidFPImm:
3481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected compatible register or floating-point constant");
3483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexedSImm9:
3484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be an integer in range [-256, 255].");
3485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed4SImm7:
3486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
3487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed8SImm7:
3488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
3489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed16SImm7:
3490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
3491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend8:
3492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'uxtw' or 'sxtw' with optional shift of #0");
3494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend16:
3495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend32:
3498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend64:
3501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend128:
3504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend8:
3507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'lsl' or 'sxtx' with optional shift of #0");
3509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend16:
3510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend32:
3513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend64:
3516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend128:
3519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc,
3520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed1:
3522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be an integer in range [0, 4095].");
3523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed2:
3524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
3525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed4:
3526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
3527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed8:
3528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
3529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed16:
3530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
3531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_7:
3532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [0, 7].");
3533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_15:
3534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [0, 15].");
3535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_31:
3536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [0, 31].");
3537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_63:
3538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [0, 63].");
3539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_127:
3540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [0, 127].");
3541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_65535:
3542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [0, 65535].");
3543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_8:
3544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [1, 8].");
3545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_16:
3546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [1, 16].");
3547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_32:
3548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [1, 32].");
3549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_64:
3550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "immediate must be an integer in range [1, 64].");
3551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndex1:
3552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected lane specifier '[1]'");
3553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexB:
3554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "vector lane must be an integer in range [0, 15].");
3555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexH:
3556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "vector lane must be an integer in range [0, 7].");
3557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexS:
3558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "vector lane must be an integer in range [0, 3].");
3559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexD:
3560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "vector lane must be an integer in range [0, 1].");
3561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidLabel:
3562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected label or encodable integer pc offset");
3563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MRS:
3564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected readable system register");
3565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MSR:
3566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "expected writable system register or pstate");
3567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MnemonicFail:
3568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(Loc, "unrecognized instruction mnemonic");
3569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
3570cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    llvm_unreachable("unexpected error code!");
3571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
3573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const char *getSubtargetFeatureName(unsigned Val);
3575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               OperandVector &Operands,
3578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               MCStreamer &Out,
3579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               unsigned &ErrorInfo,
3580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               bool MatchingInlineAsm) {
3581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(!Operands.empty() && "Unexpect empty operand list!");
3582cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
3583cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  assert(Op.isToken() && "Leading operand should always be a mnemonic!");
3584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3585cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  StringRef Tok = Op.getToken();
3586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumOperands = Operands.size();
3587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (NumOperands == 4 && Tok == "lsl") {
3589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
3590cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3591cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Op2.isReg() && Op3.isImm()) {
3592cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Op3CE) {
3594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        uint64_t Op3Val = Op3CE->getValue();
3595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        uint64_t NewOp3Val = 0;
3596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        uint64_t NewOp4Val = 0;
3597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
3598cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                Op2.getReg())) {
3599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          NewOp3Val = (32 - Op3Val) & 0x1f;
3600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          NewOp4Val = 31 - Op3Val;
3601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        } else {
3602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          NewOp3Val = (64 - Op3Val) & 0x3f;
3603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          NewOp4Val = 63 - Op3Val;
3604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
3605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        const MCExpr *NewOp3 = MCConstantExpr::Create(NewOp3Val, getContext());
3607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        const MCExpr *NewOp4 = MCConstantExpr::Create(NewOp4Val, getContext());
3608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Operands[0] = AArch64Operand::CreateToken(
3610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            "ubfm", false, Op.getStartLoc(), getContext());
3611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Operands.push_back(AArch64Operand::CreateImm(
3612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3614cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                Op3.getEndLoc(), getContext());
3615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
3616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else if (NumOperands == 5) {
3618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
3619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // UBFIZ -> UBFM aliases.
3620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
3621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3625cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3626cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3627cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (Op3CE && Op4CE) {
3630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t Op3Val = Op3CE->getValue();
3631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t Op4Val = Op4CE->getValue();
3632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t RegWidth = 0;
3634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3635cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  Op1.getReg()))
3636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            RegWidth = 64;
3637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else
3638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            RegWidth = 32;
3639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (Op3Val >= RegWidth)
3641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return Error(Op3.getStartLoc(),
3642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         "expected integer in range [0, 31]");
3643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (Op4Val < 1 || Op4Val > RegWidth)
3644cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return Error(Op4.getStartLoc(),
3645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         "expected integer in range [1, 32]");
3646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t NewOp3Val = 0;
3648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
3649cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  Op1.getReg()))
3650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            NewOp3Val = (32 - Op3Val) & 0x1f;
3651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else
3652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            NewOp3Val = (64 - Op3Val) & 0x3f;
3653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t NewOp4Val = Op4Val - 1;
3655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
3657cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return Error(Op4.getStartLoc(),
3658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         "requested insert overflows register");
3659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          const MCExpr *NewOp3 =
3661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              MCConstantExpr::Create(NewOp3Val, getContext());
3662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          const MCExpr *NewOp4 =
3663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              MCConstantExpr::Create(NewOp4Val, getContext());
3664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Operands[3] = AArch64Operand::CreateImm(
3665cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines              NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
3666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Operands[4] = AArch64Operand::CreateImm(
3667cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines              NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (Tok == "bfi")
3669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Operands[0] = AArch64Operand::CreateToken(
3670cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                "bfm", false, Op.getStartLoc(), getContext());
3671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else if (Tok == "sbfiz")
3672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Operands[0] = AArch64Operand::CreateToken(
3673cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                "sbfm", false, Op.getStartLoc(), getContext());
3674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else if (Tok == "ubfiz")
3675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Operands[0] = AArch64Operand::CreateToken(
3676cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                "ubfm", false, Op.getStartLoc(), getContext());
3677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else
3678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            llvm_unreachable("No valid mnemonic for alias?");
3679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
3680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
3681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
3683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // UBFX -> UBFM aliases.
3684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (NumOperands == 5 &&
3685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
3686cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3687cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3688cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3690cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3691cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3692cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (Op3CE && Op4CE) {
3695dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t Op3Val = Op3CE->getValue();
3696dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t Op4Val = Op4CE->getValue();
3697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3698dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t RegWidth = 0;
3699dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3700cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  Op1.getReg()))
3701dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            RegWidth = 64;
3702dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else
3703dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            RegWidth = 32;
3704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (Op3Val >= RegWidth)
3706cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return Error(Op3.getStartLoc(),
3707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         "expected integer in range [0, 31]");
3708dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (Op4Val < 1 || Op4Val > RegWidth)
3709cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return Error(Op4.getStartLoc(),
3710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         "expected integer in range [1, 32]");
3711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
3715cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            return Error(Op4.getStartLoc(),
3716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         "requested extract overflows register");
3717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          const MCExpr *NewOp4 =
3719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              MCConstantExpr::Create(NewOp4Val, getContext());
3720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Operands[4] = AArch64Operand::CreateImm(
3721cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines              NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (Tok == "bfxil")
3723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Operands[0] = AArch64Operand::CreateToken(
3724cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                "bfm", false, Op.getStartLoc(), getContext());
3725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else if (Tok == "sbfx")
3726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Operands[0] = AArch64Operand::CreateToken(
3727cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                "sbfm", false, Op.getStartLoc(), getContext());
3728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else if (Tok == "ubfx")
3729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Operands[0] = AArch64Operand::CreateToken(
3730cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                "ubfm", false, Op.getStartLoc(), getContext());
3731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else
3732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            llvm_unreachable("No valid mnemonic for alias?");
3733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
3734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
3735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
3738dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        InstAlias can't quite handle this since the reg classes aren't
3739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        subclasses.
3740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
3741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // The source register can be Wn here, but the matcher expects a
3742dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // GPR64. Twiddle it here if necessary.
3743cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3744cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Op.isReg()) {
3745cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      unsigned Reg = getXRegFromWReg(Op.getReg());
3746cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3747cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                              Op.getEndLoc(), getContext());
3748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Likewise for sxt[bh] with a Xd dst operand
3751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
3752cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3753cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Op.isReg() &&
3754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3755cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            Op.getReg())) {
3756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The source register can be Wn here, but the matcher expects a
3757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // GPR64. Twiddle it here if necessary.
3758cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3759cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (Op.isReg()) {
3760cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        unsigned Reg = getXRegFromWReg(Op.getReg());
3761cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3762cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                Op.getEndLoc(), getContext());
3763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
3764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Likewise for uxt[bh] with a Xd dst operand
3767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
3768cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3769cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Op.isReg() &&
3770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3771cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            Op.getReg())) {
3772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // The source register can be Wn here, but the matcher expects a
3773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // GPR32. Twiddle it here if necessary.
3774cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3775cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (Op.isReg()) {
3776cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        unsigned Reg = getWRegFromXReg(Op.getReg());
3777cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3778cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                Op.getEndLoc(), getContext());
3779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
3780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
3784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (NumOperands == 3 && Tok == "fmov") {
3785cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
3786cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
3787cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
3788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned zreg =
3789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64MCRegisterClasses[AArch64::FPR32RegClassID].contains(
3790cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines              RegOp.getReg())
3791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              ? AArch64::WZR
3792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              : AArch64::XZR;
3793cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
3794cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                              Op.getEndLoc(), getContext());
3795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCInst Inst;
3799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // First try to match against the secondary set of tables containing the
3800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
3801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned MatchResult =
3802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If that fails, try against the alternate table containing long-form NEON:
3805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // "fadd v0.2s, v1.2s, v2.2s"
3806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MatchResult != Match_Success)
3807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MatchResult =
3808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (MatchResult) {
3811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_Success: {
3812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Perform range checking and other semantic validations
3813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SmallVector<SMLoc, 8> OperandLocs;
3814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    NumOperands = Operands.size();
3815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned i = 1; i < NumOperands; ++i)
3816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OperandLocs.push_back(Operands[i]->getStartLoc());
3817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (validateInstruction(Inst, OperandLocs))
3818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return true;
3819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.setLoc(IDLoc);
3821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Out.EmitInstruction(Inst, STI);
3822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
3823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MissingFeature: {
3825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(ErrorInfo && "Unknown missing feature!");
3826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Special case the error message for the very common case where only
3827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // a single subtarget feature is missing (neon, e.g.).
3828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::string Msg = "instruction requires:";
3829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Mask = 1;
3830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
3831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (ErrorInfo & Mask) {
3832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Msg += " ";
3833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Msg += getSubtargetFeatureName(ErrorInfo & Mask);
3834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
3835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Mask <<= 1;
3836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(IDLoc, Msg);
3838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MnemonicFail:
3840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return showMatchError(IDLoc, MatchResult);
3841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidOperand: {
3842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SMLoc ErrorLoc = IDLoc;
3843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ErrorInfo != ~0U) {
3844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (ErrorInfo >= Operands.size())
3845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return Error(IDLoc, "too few operands for instruction");
3846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3847cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3848dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (ErrorLoc == SMLoc())
3849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        ErrorLoc = IDLoc;
3850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If the match failed on a suffix token operand, tweak the diagnostic
3852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // accordingly.
3853cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3854cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
3855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MatchResult = Match_InvalidSuffix;
3856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return showMatchError(ErrorLoc, MatchResult);
3858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed1:
3860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed2:
3861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed4:
3862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed8:
3863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed16:
3864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidCondCode:
3865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegExtendSmall:
3866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegExtendLarge:
3867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubSecondSource:
3868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_LogicalSecondSource:
3869dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegShift32:
3870dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_AddSubRegShift64:
3871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMovImm32Shift:
3872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMovImm64Shift:
3873dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidFPImm:
3874dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend8:
3875dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend16:
3876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend32:
3877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend64:
3878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryWExtend128:
3879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend8:
3880dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend16:
3881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend32:
3882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend64:
3883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryXExtend128:
3884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed4SImm7:
3885dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed8SImm7:
3886dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexed16SImm7:
3887dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidMemoryIndexedSImm9:
3888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_7:
3889dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_15:
3890dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_31:
3891dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_63:
3892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_127:
3893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm0_65535:
3894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_8:
3895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_16:
3896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_32:
3897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidImm1_64:
3898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndex1:
3899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexB:
3900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexH:
3901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexS:
3902dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidIndexD:
3903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_InvalidLabel:
3904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MSR:
3905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Match_MRS: {
3906cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (ErrorInfo >= Operands.size())
3907cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return Error(IDLoc, "too few operands for instruction");
3908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Any time we get here, there's nothing fancy to do. Just get the
3909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // operand SMLoc and display the diagnostic.
3910cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (ErrorLoc == SMLoc())
3912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ErrorLoc = IDLoc;
3913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return showMatchError(ErrorLoc, MatchResult);
3914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3917dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  llvm_unreachable("Implement any new match types added!");
3918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
3919dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
3920dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3921dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// ParseDirective parses the arm specific directives
392272062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
392372062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef IDVal = DirectiveID.getIdentifier();
3924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc Loc = DirectiveID.getLoc();
392572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (IDVal == ".hword")
3926dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseDirectiveWord(2, Loc);
3927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IDVal == ".word")
3928dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseDirectiveWord(4, Loc);
3929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IDVal == ".xword")
3930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseDirectiveWord(8, Loc);
3931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IDVal == ".tlsdesccall")
3932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseDirectiveTLSDescCall(Loc);
3933cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (IDVal == ".ltorg" || IDVal == ".pool")
3934cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return parseDirectiveLtorg(Loc);
3935cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (IDVal == ".unreq")
3936cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return parseDirectiveUnreq(DirectiveID.getLoc());
3937dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3938dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return parseDirectiveLOH(IDVal, Loc);
393972062f5744557e270a38192554c3126ea5f97434Tim Northover}
394072062f5744557e270a38192554c3126ea5f97434Tim Northover
394172062f5744557e270a38192554c3126ea5f97434Tim Northover/// parseDirectiveWord
394272062f5744557e270a38192554c3126ea5f97434Tim Northover///  ::= .word [ expression (, expression)* ]
3943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
394472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::EndOfStatement)) {
394572062f5744557e270a38192554c3126ea5f97434Tim Northover    for (;;) {
394672062f5744557e270a38192554c3126ea5f97434Tim Northover      const MCExpr *Value;
3947cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
3948dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return true;
394972062f5744557e270a38192554c3126ea5f97434Tim Northover
3950a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola      getParser().getStreamer().EmitValue(Value, Size);
395172062f5744557e270a38192554c3126ea5f97434Tim Northover
395272062f5744557e270a38192554c3126ea5f97434Tim Northover      if (getLexer().is(AsmToken::EndOfStatement))
395372062f5744557e270a38192554c3126ea5f97434Tim Northover        break;
395472062f5744557e270a38192554c3126ea5f97434Tim Northover
395572062f5744557e270a38192554c3126ea5f97434Tim Northover      // FIXME: Improve diagnostic.
3956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (getLexer().isNot(AsmToken::Comma))
3957dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return Error(L, "unexpected token in directive");
395872062f5744557e270a38192554c3126ea5f97434Tim Northover      Parser.Lex();
395972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
396072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
396172062f5744557e270a38192554c3126ea5f97434Tim Northover
396272062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
396372062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
396472062f5744557e270a38192554c3126ea5f97434Tim Northover}
396572062f5744557e270a38192554c3126ea5f97434Tim Northover
396672062f5744557e270a38192554c3126ea5f97434Tim Northover// parseDirectiveTLSDescCall:
396772062f5744557e270a38192554c3126ea5f97434Tim Northover//   ::= .tlsdesccall symbol
3968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
396972062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef Name;
3970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getParser().parseIdentifier(Name))
3971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Error(L, "expected symbol after directive");
397272062f5744557e270a38192554c3126ea5f97434Tim Northover
397372062f5744557e270a38192554c3126ea5f97434Tim Northover  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, getContext());
3975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Expr = AArch64MCExpr::Create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
397672062f5744557e270a38192554c3126ea5f97434Tim Northover
397772062f5744557e270a38192554c3126ea5f97434Tim Northover  MCInst Inst;
397872062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.setOpcode(AArch64::TLSDESCCALL);
397972062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateExpr(Expr));
398072062f5744557e270a38192554c3126ea5f97434Tim Northover
398136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getParser().getStreamer().EmitInstruction(Inst, STI);
398272062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
398372062f5744557e270a38192554c3126ea5f97434Tim Northover}
398472062f5744557e270a38192554c3126ea5f97434Tim Northover
3985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// ::= .loh <lohName | lohId> label1, ..., labelN
3986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// The number of arguments depends on the loh identifier.
3987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
3988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IDVal != MCLOHDirectiveName())
3989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
3990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCLOHType Kind;
3991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getParser().getTok().isNot(AsmToken::Identifier)) {
3992dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getParser().getTok().isNot(AsmToken::Integer))
3993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("expected an identifier or a number in directive");
3994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We successfully get a numeric value for the identifier.
3995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check if it is valid.
3996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t Id = getParser().getTok().getIntVal();
3997dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Kind = (MCLOHType)Id;
3998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check that Id does not overflow MCLOHType.
3999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!isValidMCLOHType(Kind) || Id != Kind)
4000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("invalid numeric identifier in directive");
4001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
4002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef Name = getTok().getIdentifier();
4003dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We successfully parse an identifier.
4004dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check if it is a recognized one.
4005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int Id = MCLOHNameToId(Name);
4006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Id == -1)
4008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("invalid identifier in directive");
4009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Kind = (MCLOHType)Id;
4010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
4011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Consume the identifier.
4012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Lex();
4013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Get the number of arguments of this LOH.
4014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int NbArgs = MCLOHIdToNbArgs(Kind);
4015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(NbArgs != -1 && "Invalid number of arguments");
4017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SmallVector<MCSymbol *, 3> Args;
4019dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (int Idx = 0; Idx < NbArgs; ++Idx) {
4020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef Name;
4021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getParser().parseIdentifier(Name))
4022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("expected identifier in directive");
4023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Args.push_back(getContext().GetOrCreateSymbol(Name));
4024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Idx + 1 == NbArgs)
4026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
4027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (getLexer().isNot(AsmToken::Comma))
4028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
4029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Lex();
4030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
4031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
4032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
403372062f5744557e270a38192554c3126ea5f97434Tim Northover
4034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
4036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
4037b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover
4038cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// parseDirectiveLtorg
4039cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= .ltorg | .pool
4040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
4041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  getTargetStreamer().emitCurrentConstantPool();
4042cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
4043cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
4044cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4045cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// parseDirectiveReq
4046cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= name .req registername
4047cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
4048cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Eat the '.req' token.
4049cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  SMLoc SRegLoc = getLoc();
4050cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned RegNum = tryParseRegister();
4051cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool IsVector = false;
4052cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4053cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (RegNum == static_cast<unsigned>(-1)) {
4054cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    StringRef Kind;
4055cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    RegNum = tryMatchVectorRegister(Kind, false);
4056cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!Kind.empty()) {
4057cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Error(SRegLoc, "vector register without type specifier expected");
4058cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
4059cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
4060cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    IsVector = true;
4061cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
4062cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4063cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (RegNum == static_cast<unsigned>(-1)) {
4064cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.eatToEndOfStatement();
4065cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Error(SRegLoc, "register name or alias expected");
4066cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
4067cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
4068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4069cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Shouldn't be anything else.
4070cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4071cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Error(Parser.getTok().getLoc(), "unexpected input in .req directive");
4072cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.eatToEndOfStatement();
4073cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
4074cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
4075cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Consume the EndOfStatement
4077cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4078cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  auto pair = std::make_pair(IsVector, RegNum);
4079cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (RegisterReqs.GetOrCreateValue(Name, pair).getValue() != pair)
4080cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Warning(L, "ignoring redefinition of register alias '" + Name + "'");
4081cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4082cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return true;
4083cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
4084cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4085cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// parseDirectiveUneq
4086cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= .unreq registername
4087cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
4088cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Parser.getTok().isNot(AsmToken::Identifier)) {
4089cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive.");
4090cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.eatToEndOfStatement();
4091cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
4092cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
4093cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
4094cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Eat the identifier.
4095cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
4096cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
4097cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
4098dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool
4099dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
4100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    AArch64MCExpr::VariantKind &ELFRefKind,
4101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    MCSymbolRefExpr::VariantKind &DarwinRefKind,
4102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    int64_t &Addend) {
4103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ELFRefKind = AArch64MCExpr::VK_INVALID;
4104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DarwinRefKind = MCSymbolRefExpr::VK_None;
4105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Addend = 0;
4106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ELFRefKind = AE->getKind();
4109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Expr = AE->getSubExpr();
4110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
4111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (SE) {
4114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // It's a simple symbol reference with no addend.
4115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DarwinRefKind = SE->getKind();
4116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
4117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
4118b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover
4119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!BE)
4121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
412272062f5744557e270a38192554c3126ea5f97434Tim Northover
4123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!SE)
412572062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
4126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DarwinRefKind = SE->getKind();
412772062f5744557e270a38192554c3126ea5f97434Tim Northover
4128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (BE->getOpcode() != MCBinaryExpr::Add &&
4129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BE->getOpcode() != MCBinaryExpr::Sub)
4130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
4131b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover
4132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // See if the addend is is a constant, otherwise there's more going
4133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // on here than we can deal with.
4134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
4135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!AddendExpr)
4136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
413772062f5744557e270a38192554c3126ea5f97434Tim Northover
4138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Addend = AddendExpr->getValue();
4139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (BE->getOpcode() == MCBinaryExpr::Sub)
4140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Addend = -Addend;
4141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // It's some symbol reference + a constant addend, but really
4143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // shouldn't use both Darwin and ELF syntax.
4144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return ELFRefKind == AArch64MCExpr::VK_INVALID ||
4145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         DarwinRefKind == MCSymbolRefExpr::VK_None;
414672062f5744557e270a38192554c3126ea5f97434Tim Northover}
414772062f5744557e270a38192554c3126ea5f97434Tim Northover
4148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Force static initialization.
4149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesextern "C" void LLVMInitializeAArch64AsmParser() {
4150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64leTarget);
4151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RegisterMCAsmParser<AArch64AsmParser> Y(TheAArch64beTarget);
4152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64leTarget);
4154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RegisterMCAsmParser<AArch64AsmParser> W(TheARM64beTarget);
4155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
4156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define GET_REGISTER_MATCHER
4158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define GET_SUBTARGET_FEATURE_NAME
4159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define GET_MATCHER_IMPLEMENTATION
4160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64GenAsmMatcher.inc"
4161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Define this matcher function after the auto-generated include so we
4163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// have the match class enum definitions.
4164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesunsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
4165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                      unsigned Kind) {
4166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
4167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If the kind is a token for a literal immediate, check if our asm
4168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // operand matches. This is for InstAliases which have a fixed-value
4169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // immediate in the syntax.
4170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t ExpectedVal;
417172062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Kind) {
4172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
4173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Match_InvalidOperand;
4174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_0:
4175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 0;
417672062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_1:
4178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 1;
417972062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_12:
4181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 12;
418272062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_16:
4184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 16;
418572062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_2:
4187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 2;
418872062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_24:
4190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 24;
419172062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_3:
4193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 3;
419472062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_32:
4196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 32;
419772062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
4198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_4:
4199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 4;
4200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
4201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_48:
4202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 48;
4203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
4204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_6:
4205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 6;
4206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
4207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_64:
4208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 64;
4209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
4210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MCK__35_8:
4211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ExpectedVal = 8;
421272062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
421372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
4214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!Op.isImm())
4215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Match_InvalidOperand;
4216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
4217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!CE)
4218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Match_InvalidOperand;
4219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (CE->getValue() == ExpectedVal)
4220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Match_Success;
4221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Match_InvalidOperand;
422272062f5744557e270a38192554c3126ea5f97434Tim Northover}
4223