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//===----------------------------------------------------------------------===//
95bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
105bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// This file contains the (GNU-style) assembly parser for the AArch64
115bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// architecture.
125bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
135bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//===----------------------------------------------------------------------===//
1472062f5744557e270a38192554c3126ea5f97434Tim Northover
1572062f5744557e270a38192554c3126ea5f97434Tim Northover
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64MCTargetDesc.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64MCExpr.h"
1819254c49a8752fe8c6fa648a6eb29f20a1f62c8bTim Northover#include "Utils/AArch64BaseInfo.h"
1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/APFloat.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/APInt.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/StringSwitch.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/STLExtras.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCContext.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCInst.h"
2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCSubtargetInfo.h"
2672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCTargetAsmParser.h"
2772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCExpr.h"
2872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCRegisterInfo.h"
2972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCStreamer.h"
3072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCParser/MCAsmLexer.h"
3172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCParser/MCAsmParser.h"
3272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
3372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h"
3472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/raw_ostream.h"
3572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/TargetRegistry.h"
3672062f5744557e270a38192554c3126ea5f97434Tim Northover
3772062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
3872062f5744557e270a38192554c3126ea5f97434Tim Northover
3972062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
4072062f5744557e270a38192554c3126ea5f97434Tim Northover
4172062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64Operand;
4272062f5744557e270a38192554c3126ea5f97434Tim Northover
4372062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64AsmParser : public MCTargetAsmParser {
4472062f5744557e270a38192554c3126ea5f97434Tim Northover  MCSubtargetInfo &STI;
4572062f5744557e270a38192554c3126ea5f97434Tim Northover  MCAsmParser &Parser;
4672062f5744557e270a38192554c3126ea5f97434Tim Northover
4772062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_ASSEMBLER_HEADER
4872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenAsmMatcher.inc"
4972062f5744557e270a38192554c3126ea5f97434Tim Northover
5072062f5744557e270a38192554c3126ea5f97434Tim Northoverpublic:
51b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  enum AArch64MatchResultTy {
52b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    Match_FirstAArch64 = FIRST_TARGET_MATCH_RESULT_TY,
53b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover#define GET_OPERAND_DIAGNOSTIC_TYPES
54b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover#include "AArch64GenAsmMatcher.inc"
55b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  };
56b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover
5772062f5744557e270a38192554c3126ea5f97434Tim Northover  AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
5872062f5744557e270a38192554c3126ea5f97434Tim Northover    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
5972062f5744557e270a38192554c3126ea5f97434Tim Northover    MCAsmParserExtension::Initialize(_Parser);
6072062f5744557e270a38192554c3126ea5f97434Tim Northover
6172062f5744557e270a38192554c3126ea5f97434Tim Northover    // Initialize the set of available features.
6272062f5744557e270a38192554c3126ea5f97434Tim Northover    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
6372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
6472062f5744557e270a38192554c3126ea5f97434Tim Northover
6572062f5744557e270a38192554c3126ea5f97434Tim Northover  // These are the public interface of the MCTargetAsmParser
6672062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
67dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6872062f5744557e270a38192554c3126ea5f97434Tim Northover                        SMLoc NameLoc,
6972062f5744557e270a38192554c3126ea5f97434Tim Northover                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
7072062f5744557e270a38192554c3126ea5f97434Tim Northover
7172062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ParseDirective(AsmToken DirectiveID);
7272062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ParseDirectiveTLSDescCall(SMLoc L);
7372062f5744557e270a38192554c3126ea5f97434Tim Northover  bool ParseDirectiveWord(unsigned Size, SMLoc L);
7472062f5744557e270a38192554c3126ea5f97434Tim Northover
7572062f5744557e270a38192554c3126ea5f97434Tim Northover  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
7672062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7772062f5744557e270a38192554c3126ea5f97434Tim Northover                               MCStreamer&Out, unsigned &ErrorInfo,
7872062f5744557e270a38192554c3126ea5f97434Tim Northover                               bool MatchingInlineAsm);
7972062f5744557e270a38192554c3126ea5f97434Tim Northover
8072062f5744557e270a38192554c3126ea5f97434Tim Northover  // The rest of the sub-parsers have more freedom over interface: they return
8172062f5744557e270a38192554c3126ea5f97434Tim Northover  // an OperandMatchResultTy because it's less ambiguous than true/false or
8272062f5744557e270a38192554c3126ea5f97434Tim Northover  // -1/0/1 even if it is more verbose
8372062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
8472062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
8572062f5744557e270a38192554c3126ea5f97434Tim Northover               StringRef Mnemonic);
8672062f5744557e270a38192554c3126ea5f97434Tim Northover
8772062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy ParseImmediate(const MCExpr *&ExprVal);
8872062f5744557e270a38192554c3126ea5f97434Tim Northover
8972062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy ParseRelocPrefix(AArch64MCExpr::VariantKind &RefKind);
9072062f5744557e270a38192554c3126ea5f97434Tim Northover
9172062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
9272062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseNEONLane(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
9372062f5744557e270a38192554c3126ea5f97434Tim Northover                uint32_t NumLanes);
9472062f5744557e270a38192554c3126ea5f97434Tim Northover
9572062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
9672062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
9772062f5744557e270a38192554c3126ea5f97434Tim Northover                uint32_t &NumLanes);
9872062f5744557e270a38192554c3126ea5f97434Tim Northover
9972062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
10072062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseImmWithLSLOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
10172062f5744557e270a38192554c3126ea5f97434Tim Northover
10272062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
10372062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseCondCodeOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
10472062f5744557e270a38192554c3126ea5f97434Tim Northover
10572062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
10672062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseCRxOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
10772062f5744557e270a38192554c3126ea5f97434Tim Northover
10872062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
10972062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseFPImmOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
11072062f5744557e270a38192554c3126ea5f97434Tim Northover
11172062f5744557e270a38192554c3126ea5f97434Tim Northover  template<typename SomeNamedImmMapper> OperandMatchResultTy
11272062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseNamedImmOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
11372062f5744557e270a38192554c3126ea5f97434Tim Northover    return ParseNamedImmOperand(SomeNamedImmMapper(), Operands);
11472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
11572062f5744557e270a38192554c3126ea5f97434Tim Northover
11672062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
11772062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseNamedImmOperand(const NamedImmMapper &Mapper,
11872062f5744557e270a38192554c3126ea5f97434Tim Northover                       SmallVectorImpl<MCParsedAsmOperand*> &Operands);
11972062f5744557e270a38192554c3126ea5f97434Tim Northover
12072062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
12172062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseLSXAddressOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
12272062f5744557e270a38192554c3126ea5f97434Tim Northover
12372062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
12472062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseShiftExtend(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
12572062f5744557e270a38192554c3126ea5f97434Tim Northover
12672062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy
12772062f5744557e270a38192554c3126ea5f97434Tim Northover  ParseSysRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
12872062f5744557e270a38192554c3126ea5f97434Tim Northover
12972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool validateInstruction(MCInst &Inst,
130dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                          const SmallVectorImpl<MCParsedAsmOperand*> &Operands);
13172062f5744557e270a38192554c3126ea5f97434Tim Northover
13272062f5744557e270a38192554c3126ea5f97434Tim Northover  /// Scan the next token (which had better be an identifier) and determine
13372062f5744557e270a38192554c3126ea5f97434Tim Northover  /// whether it represents a general-purpose or vector register. It returns
13472062f5744557e270a38192554c3126ea5f97434Tim Northover  /// true if an identifier was found and populates its reference arguments. It
13572062f5744557e270a38192554c3126ea5f97434Tim Northover  /// does not consume the token.
13672062f5744557e270a38192554c3126ea5f97434Tim Northover  bool
13772062f5744557e270a38192554c3126ea5f97434Tim Northover  IdentifyRegister(unsigned &RegNum, SMLoc &RegEndLoc, StringRef &LayoutSpec,
13872062f5744557e270a38192554c3126ea5f97434Tim Northover                   SMLoc &LayoutLoc) const;
13972062f5744557e270a38192554c3126ea5f97434Tim Northover
14072062f5744557e270a38192554c3126ea5f97434Tim Northover};
14172062f5744557e270a38192554c3126ea5f97434Tim Northover
14272062f5744557e270a38192554c3126ea5f97434Tim Northover}
14372062f5744557e270a38192554c3126ea5f97434Tim Northover
14472062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
14572062f5744557e270a38192554c3126ea5f97434Tim Northover
14672062f5744557e270a38192554c3126ea5f97434Tim Northover/// Instances of this class represent a parsed AArch64 machine instruction.
14772062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64Operand : public MCParsedAsmOperand {
14872062f5744557e270a38192554c3126ea5f97434Tim Northoverprivate:
14972062f5744557e270a38192554c3126ea5f97434Tim Northover  enum KindTy {
15072062f5744557e270a38192554c3126ea5f97434Tim Northover    k_ImmWithLSL,     // #uimm {, LSL #amt }
15172062f5744557e270a38192554c3126ea5f97434Tim Northover    k_CondCode,       // eq/ne/...
15272062f5744557e270a38192554c3126ea5f97434Tim Northover    k_FPImmediate,    // Limited-precision floating-point imm
15372062f5744557e270a38192554c3126ea5f97434Tim Northover    k_Immediate,      // Including expressions referencing symbols
15472062f5744557e270a38192554c3126ea5f97434Tim Northover    k_Register,
15572062f5744557e270a38192554c3126ea5f97434Tim Northover    k_ShiftExtend,
15672062f5744557e270a38192554c3126ea5f97434Tim Northover    k_SysReg,         // The register operand of MRS and MSR instructions
15772062f5744557e270a38192554c3126ea5f97434Tim Northover    k_Token,          // The mnemonic; other raw tokens the auto-generated
15872062f5744557e270a38192554c3126ea5f97434Tim Northover    k_WrappedRegister // Load/store exclusive permit a wrapped register.
15972062f5744557e270a38192554c3126ea5f97434Tim Northover  } Kind;
16072062f5744557e270a38192554c3126ea5f97434Tim Northover
16172062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc StartLoc, EndLoc;
16272062f5744557e270a38192554c3126ea5f97434Tim Northover
163a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmWithLSLOp {
164a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
165a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned ShiftAmount;
166a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    bool ImplicitAmount;
167a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
168a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
169a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct CondCodeOp {
170a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    A64CC::CondCodes Code;
171a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
172a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
173a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct FPImmOp {
174a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    double Val;
175a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
176a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
177a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
178a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
179a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
180a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
181a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct RegOp {
182a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned RegNum;
183a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
184a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
185a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ShiftExtendOp {
186a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    A64SE::ShiftExtSpecifiers ShiftType;
187a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Amount;
188a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    bool ImplicitAmount;
189a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
190a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
191a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct SysRegOp {
192a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
193a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
194a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
195a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
196a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct TokOp {
197a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
198a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
199a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
200a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
20172062f5744557e270a38192554c3126ea5f97434Tim Northover  union {
202a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmWithLSLOp ImmWithLSL;
203a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct CondCodeOp CondCode;
204a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct FPImmOp FPImm;
205a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
206a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct RegOp Reg;
207a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ShiftExtendOp ShiftExtend;
208a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct SysRegOp SysReg;
209a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct TokOp Tok;
21072062f5744557e270a38192554c3126ea5f97434Tim Northover  };
21172062f5744557e270a38192554c3126ea5f97434Tim Northover
21272062f5744557e270a38192554c3126ea5f97434Tim Northover  AArch64Operand(KindTy K, SMLoc S, SMLoc E)
21372062f5744557e270a38192554c3126ea5f97434Tim Northover    : MCParsedAsmOperand(), Kind(K), StartLoc(S), EndLoc(E) {}
21472062f5744557e270a38192554c3126ea5f97434Tim Northover
21572062f5744557e270a38192554c3126ea5f97434Tim Northoverpublic:
21672062f5744557e270a38192554c3126ea5f97434Tim Northover  AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand() {
21772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
21872062f5744557e270a38192554c3126ea5f97434Tim Northover
21972062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc getStartLoc() const { return StartLoc; }
22072062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc getEndLoc() const { return EndLoc; }
22172062f5744557e270a38192554c3126ea5f97434Tim Northover  void print(raw_ostream&) const;
22272062f5744557e270a38192554c3126ea5f97434Tim Northover  void dump() const;
22372062f5744557e270a38192554c3126ea5f97434Tim Northover
22472062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef getToken() const {
22572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(Kind == k_Token && "Invalid access!");
22672062f5744557e270a38192554c3126ea5f97434Tim Northover    return StringRef(Tok.Data, Tok.Length);
22772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
22872062f5744557e270a38192554c3126ea5f97434Tim Northover
22972062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned getReg() const {
23072062f5744557e270a38192554c3126ea5f97434Tim Northover    assert((Kind == k_Register || Kind == k_WrappedRegister)
23172062f5744557e270a38192554c3126ea5f97434Tim Northover           && "Invalid access!");
23272062f5744557e270a38192554c3126ea5f97434Tim Northover    return Reg.RegNum;
23372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
23472062f5744557e270a38192554c3126ea5f97434Tim Northover
23572062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCExpr *getImm() const {
23672062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(Kind == k_Immediate && "Invalid access!");
23772062f5744557e270a38192554c3126ea5f97434Tim Northover    return Imm.Val;
23872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
23972062f5744557e270a38192554c3126ea5f97434Tim Northover
24072062f5744557e270a38192554c3126ea5f97434Tim Northover  A64CC::CondCodes getCondCode() const {
24172062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(Kind == k_CondCode && "Invalid access!");
24272062f5744557e270a38192554c3126ea5f97434Tim Northover    return CondCode.Code;
24372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
24472062f5744557e270a38192554c3126ea5f97434Tim Northover
24572062f5744557e270a38192554c3126ea5f97434Tim Northover  static bool isNonConstantExpr(const MCExpr *E,
24672062f5744557e270a38192554c3126ea5f97434Tim Northover                                AArch64MCExpr::VariantKind &Variant) {
24772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) {
24872062f5744557e270a38192554c3126ea5f97434Tim Northover      Variant = A64E->getKind();
24972062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
25072062f5744557e270a38192554c3126ea5f97434Tim Northover    } else if (!isa<MCConstantExpr>(E)) {
25172062f5744557e270a38192554c3126ea5f97434Tim Northover      Variant = AArch64MCExpr::VK_AARCH64_None;
25272062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
25372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
25472062f5744557e270a38192554c3126ea5f97434Tim Northover
25572062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
25672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
25772062f5744557e270a38192554c3126ea5f97434Tim Northover
25872062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isCondCode() const { return Kind == k_CondCode; }
25972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isToken() const { return Kind == k_Token; }
26072062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isReg() const { return Kind == k_Register; }
26172062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isImm() const { return Kind == k_Immediate; }
26272062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMem() const { return false; }
26372062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isFPImm() const { return Kind == k_FPImmediate; }
26472062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isShiftOrExtend() const { return Kind == k_ShiftExtend; }
26572062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isSysReg() const { return Kind == k_SysReg; }
26672062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isImmWithLSL() const { return Kind == k_ImmWithLSL; }
26772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isWrappedReg() const { return Kind == k_WrappedRegister; }
26872062f5744557e270a38192554c3126ea5f97434Tim Northover
26972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isAddSubImmLSL0() const {
27072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImmWithLSL()) return false;
27172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ImmWithLSL.ShiftAmount != 0) return false;
27272062f5744557e270a38192554c3126ea5f97434Tim Northover
27372062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64MCExpr::VariantKind Variant;
27472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (isNonConstantExpr(ImmWithLSL.Val, Variant)) {
27572062f5744557e270a38192554c3126ea5f97434Tim Northover      return Variant == AArch64MCExpr::VK_AARCH64_LO12
27672062f5744557e270a38192554c3126ea5f97434Tim Northover          || Variant == AArch64MCExpr::VK_AARCH64_DTPREL_LO12
27772062f5744557e270a38192554c3126ea5f97434Tim Northover          || Variant == AArch64MCExpr::VK_AARCH64_DTPREL_LO12_NC
27872062f5744557e270a38192554c3126ea5f97434Tim Northover          || Variant == AArch64MCExpr::VK_AARCH64_TPREL_LO12
27972062f5744557e270a38192554c3126ea5f97434Tim Northover          || Variant == AArch64MCExpr::VK_AARCH64_TPREL_LO12_NC
28072062f5744557e270a38192554c3126ea5f97434Tim Northover          || Variant == AArch64MCExpr::VK_AARCH64_TLSDESC_LO12;
28172062f5744557e270a38192554c3126ea5f97434Tim Northover    }
28272062f5744557e270a38192554c3126ea5f97434Tim Northover
28372062f5744557e270a38192554c3126ea5f97434Tim Northover    // Otherwise it should be a real immediate in range:
28472062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(ImmWithLSL.Val);
28572062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE->getValue() >= 0 && CE->getValue() <= 0xfff;
28672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
28772062f5744557e270a38192554c3126ea5f97434Tim Northover
28872062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isAddSubImmLSL12() const {
28972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImmWithLSL()) return false;
29072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ImmWithLSL.ShiftAmount != 12) return false;
29172062f5744557e270a38192554c3126ea5f97434Tim Northover
29272062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64MCExpr::VariantKind Variant;
29372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (isNonConstantExpr(ImmWithLSL.Val, Variant)) {
29472062f5744557e270a38192554c3126ea5f97434Tim Northover      return Variant == AArch64MCExpr::VK_AARCH64_DTPREL_HI12
29572062f5744557e270a38192554c3126ea5f97434Tim Northover          || Variant == AArch64MCExpr::VK_AARCH64_TPREL_HI12;
29672062f5744557e270a38192554c3126ea5f97434Tim Northover    }
29772062f5744557e270a38192554c3126ea5f97434Tim Northover
29872062f5744557e270a38192554c3126ea5f97434Tim Northover    // Otherwise it should be a real immediate in range:
29972062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(ImmWithLSL.Val);
30072062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE->getValue() >= 0 && CE->getValue() <= 0xfff;
30172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
30272062f5744557e270a38192554c3126ea5f97434Tim Northover
30372062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned MemSize, unsigned RmSize> bool isAddrRegExtend() const {
30472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isShiftOrExtend()) return false;
30572062f5744557e270a38192554c3126ea5f97434Tim Northover
30672062f5744557e270a38192554c3126ea5f97434Tim Northover    A64SE::ShiftExtSpecifiers Ext = ShiftExtend.ShiftType;
30772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (RmSize == 32 && !(Ext == A64SE::UXTW || Ext == A64SE::SXTW))
30872062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
30972062f5744557e270a38192554c3126ea5f97434Tim Northover
31072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (RmSize == 64 && !(Ext == A64SE::LSL || Ext == A64SE::SXTX))
31172062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
31272062f5744557e270a38192554c3126ea5f97434Tim Northover
31372062f5744557e270a38192554c3126ea5f97434Tim Northover    return ShiftExtend.Amount == Log2_32(MemSize) || ShiftExtend.Amount == 0;
31472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
31572062f5744557e270a38192554c3126ea5f97434Tim Northover
31672062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isAdrpLabel() const {
31772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
31872062f5744557e270a38192554c3126ea5f97434Tim Northover
31972062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64MCExpr::VariantKind Variant;
32072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (isNonConstantExpr(getImm(), Variant)) {
32172062f5744557e270a38192554c3126ea5f97434Tim Northover      return Variant == AArch64MCExpr::VK_AARCH64_None
32272062f5744557e270a38192554c3126ea5f97434Tim Northover        || Variant == AArch64MCExpr::VK_AARCH64_GOT
32372062f5744557e270a38192554c3126ea5f97434Tim Northover        || Variant == AArch64MCExpr::VK_AARCH64_GOTTPREL
32472062f5744557e270a38192554c3126ea5f97434Tim Northover        || Variant == AArch64MCExpr::VK_AARCH64_TLSDESC;
32572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
32672062f5744557e270a38192554c3126ea5f97434Tim Northover
32772062f5744557e270a38192554c3126ea5f97434Tim Northover    return isLabel<21, 4096>();
32872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
32972062f5744557e270a38192554c3126ea5f97434Tim Northover
33072062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned RegWidth>  bool isBitfieldWidth() const {
33172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
33272062f5744557e270a38192554c3126ea5f97434Tim Northover
33372062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
33472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
33572062f5744557e270a38192554c3126ea5f97434Tim Northover
33672062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE->getValue() >= 1 && CE->getValue() <= RegWidth;
33772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
33872062f5744557e270a38192554c3126ea5f97434Tim Northover
33972062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int RegWidth>
34072062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isCVTFixedPos() const {
34172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
34272062f5744557e270a38192554c3126ea5f97434Tim Northover
34372062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
34472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
34572062f5744557e270a38192554c3126ea5f97434Tim Northover
34672062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE->getValue() >= 1 && CE->getValue() <= RegWidth;
34772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
34872062f5744557e270a38192554c3126ea5f97434Tim Northover
34972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isFMOVImm() const {
35072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isFPImm()) return false;
35172062f5744557e270a38192554c3126ea5f97434Tim Northover
35272062f5744557e270a38192554c3126ea5f97434Tim Northover    APFloat RealVal(FPImm.Val);
35372062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t ImmVal;
35472062f5744557e270a38192554c3126ea5f97434Tim Northover    return A64Imms::isFPImm(RealVal, ImmVal);
35572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
35672062f5744557e270a38192554c3126ea5f97434Tim Northover
35772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isFPZero() const {
35872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isFPImm()) return false;
35972062f5744557e270a38192554c3126ea5f97434Tim Northover
36072062f5744557e270a38192554c3126ea5f97434Tim Northover    APFloat RealVal(FPImm.Val);
36172062f5744557e270a38192554c3126ea5f97434Tim Northover    return RealVal.isPosZero();
36272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
36372062f5744557e270a38192554c3126ea5f97434Tim Northover
36472062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned field_width, unsigned scale>
36572062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isLabel() const {
36672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
36772062f5744557e270a38192554c3126ea5f97434Tim Northover
36872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (dyn_cast<MCSymbolRefExpr>(Imm.Val)) {
36972062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
37072062f5744557e270a38192554c3126ea5f97434Tim Northover    } else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
37172062f5744557e270a38192554c3126ea5f97434Tim Northover      int64_t Val = CE->getValue();
37272062f5744557e270a38192554c3126ea5f97434Tim Northover      int64_t Min = - (scale * (1LL << (field_width - 1)));
37372062f5744557e270a38192554c3126ea5f97434Tim Northover      int64_t Max = scale * ((1LL << (field_width - 1)) - 1);
37472062f5744557e270a38192554c3126ea5f97434Tim Northover      return (Val % scale) == 0 && Val >= Min && Val <= Max;
37572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
37672062f5744557e270a38192554c3126ea5f97434Tim Northover
37772062f5744557e270a38192554c3126ea5f97434Tim Northover    // N.b. this disallows explicit relocation specifications via an
37872062f5744557e270a38192554c3126ea5f97434Tim Northover    // AArch64MCExpr. Users needing that behaviour
37972062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
38072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
38172062f5744557e270a38192554c3126ea5f97434Tim Northover
38272062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isLane1() const {
38372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
38472062f5744557e270a38192554c3126ea5f97434Tim Northover
38572062f5744557e270a38192554c3126ea5f97434Tim Northover    // Because it's come through custom assembly parsing, it must always be a
38672062f5744557e270a38192554c3126ea5f97434Tim Northover    // constant expression.
38772062f5744557e270a38192554c3126ea5f97434Tim Northover    return cast<MCConstantExpr>(getImm())->getValue() == 1;
38872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
38972062f5744557e270a38192554c3126ea5f97434Tim Northover
39072062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isLoadLitLabel() const {
39172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
39272062f5744557e270a38192554c3126ea5f97434Tim Northover
39372062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64MCExpr::VariantKind Variant;
39472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (isNonConstantExpr(getImm(), Variant)) {
39572062f5744557e270a38192554c3126ea5f97434Tim Northover      return Variant == AArch64MCExpr::VK_AARCH64_None
39672062f5744557e270a38192554c3126ea5f97434Tim Northover          || Variant == AArch64MCExpr::VK_AARCH64_GOTTPREL;
39772062f5744557e270a38192554c3126ea5f97434Tim Northover    }
39872062f5744557e270a38192554c3126ea5f97434Tim Northover
39972062f5744557e270a38192554c3126ea5f97434Tim Northover    return isLabel<19, 4>();
40072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
40172062f5744557e270a38192554c3126ea5f97434Tim Northover
40272062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned RegWidth> bool isLogicalImm() const {
40372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
40472062f5744557e270a38192554c3126ea5f97434Tim Northover
40572062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
40672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
40772062f5744557e270a38192554c3126ea5f97434Tim Northover
40872062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t Bits;
40972062f5744557e270a38192554c3126ea5f97434Tim Northover    return A64Imms::isLogicalImm(RegWidth, CE->getValue(), Bits);
41072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
41172062f5744557e270a38192554c3126ea5f97434Tim Northover
41272062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned RegWidth> bool isLogicalImmMOV() const {
41372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isLogicalImm<RegWidth>()) return false;
41472062f5744557e270a38192554c3126ea5f97434Tim Northover
41572062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(Imm.Val);
41672062f5744557e270a38192554c3126ea5f97434Tim Northover
41772062f5744557e270a38192554c3126ea5f97434Tim Northover    // The move alias for ORR is only valid if the immediate cannot be
41872062f5744557e270a38192554c3126ea5f97434Tim Northover    // represented with a move (immediate) instruction; they take priority.
41972062f5744557e270a38192554c3126ea5f97434Tim Northover    int UImm16, Shift;
42072062f5744557e270a38192554c3126ea5f97434Tim Northover    return !A64Imms::isMOVZImm(RegWidth, CE->getValue(), UImm16, Shift)
42172062f5744557e270a38192554c3126ea5f97434Tim Northover      && !A64Imms::isMOVNImm(RegWidth, CE->getValue(), UImm16, Shift);
42272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
42372062f5744557e270a38192554c3126ea5f97434Tim Northover
42472062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int MemSize>
42572062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isOffsetUImm12() const {
42672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
42772062f5744557e270a38192554c3126ea5f97434Tim Northover
42872062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
42972062f5744557e270a38192554c3126ea5f97434Tim Northover
43072062f5744557e270a38192554c3126ea5f97434Tim Northover    // Assume they know what they're doing for now if they've given us a
43172062f5744557e270a38192554c3126ea5f97434Tim Northover    // non-constant expression. In principle we could check for ridiculous
43272062f5744557e270a38192554c3126ea5f97434Tim Northover    // things that can't possibly work or relocations that would almost
43372062f5744557e270a38192554c3126ea5f97434Tim Northover    // certainly break resulting code.
43472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE)
43572062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
43672062f5744557e270a38192554c3126ea5f97434Tim Northover
43772062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t Val = CE->getValue();
43872062f5744557e270a38192554c3126ea5f97434Tim Northover
43972062f5744557e270a38192554c3126ea5f97434Tim Northover    // Must be a multiple of the access size in bytes.
44072062f5744557e270a38192554c3126ea5f97434Tim Northover    if ((Val & (MemSize - 1)) != 0) return false;
44172062f5744557e270a38192554c3126ea5f97434Tim Northover
44272062f5744557e270a38192554c3126ea5f97434Tim Northover    // Must be 12-bit unsigned
44372062f5744557e270a38192554c3126ea5f97434Tim Northover    return Val >= 0 && Val <= 0xfff * MemSize;
44472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
44572062f5744557e270a38192554c3126ea5f97434Tim Northover
44672062f5744557e270a38192554c3126ea5f97434Tim Northover  template<A64SE::ShiftExtSpecifiers SHKind, bool is64Bit>
44772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isShift() const {
44872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isShiftOrExtend()) return false;
44972062f5744557e270a38192554c3126ea5f97434Tim Northover
45072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ShiftExtend.ShiftType != SHKind)
45172062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
45272062f5744557e270a38192554c3126ea5f97434Tim Northover
45372062f5744557e270a38192554c3126ea5f97434Tim Northover    return is64Bit ? ShiftExtend.Amount <= 63 : ShiftExtend.Amount <= 31;
45472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
45572062f5744557e270a38192554c3126ea5f97434Tim Northover
45672062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMOVN32Imm() const {
457f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    static const AArch64MCExpr::VariantKind PermittedModifiers[] = {
45872062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G0,
45972062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G1,
46072062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G1,
46172062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G0,
46272062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_GOTTPREL_G1,
46372062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G1,
46472062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G0,
46572062f5744557e270a38192554c3126ea5f97434Tim Northover    };
466f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    const unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers);
46772062f5744557e270a38192554c3126ea5f97434Tim Northover
46872062f5744557e270a38192554c3126ea5f97434Tim Northover    return isMoveWideImm(32, PermittedModifiers, NumModifiers);
46972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
47072062f5744557e270a38192554c3126ea5f97434Tim Northover
47172062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMOVN64Imm() const {
472f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    static const AArch64MCExpr::VariantKind PermittedModifiers[] = {
47372062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G0,
47472062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G1,
47572062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G2,
47672062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G2,
47772062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G1,
47872062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G0,
47972062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_GOTTPREL_G1,
48072062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G2,
48172062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G1,
48272062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G0,
48372062f5744557e270a38192554c3126ea5f97434Tim Northover    };
484f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    const unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers);
48572062f5744557e270a38192554c3126ea5f97434Tim Northover
48672062f5744557e270a38192554c3126ea5f97434Tim Northover    return isMoveWideImm(64, PermittedModifiers, NumModifiers);
48772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
48872062f5744557e270a38192554c3126ea5f97434Tim Northover
48972062f5744557e270a38192554c3126ea5f97434Tim Northover
49072062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMOVZ32Imm() const {
491f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    static const AArch64MCExpr::VariantKind PermittedModifiers[] = {
49272062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G0,
49372062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G1,
49472062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G0,
49572062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G1,
49672062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G1,
49772062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G0,
49872062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_GOTTPREL_G1,
49972062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G1,
50072062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G0,
50172062f5744557e270a38192554c3126ea5f97434Tim Northover    };
502f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    const unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers);
50372062f5744557e270a38192554c3126ea5f97434Tim Northover
50472062f5744557e270a38192554c3126ea5f97434Tim Northover    return isMoveWideImm(32, PermittedModifiers, NumModifiers);
50572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
50672062f5744557e270a38192554c3126ea5f97434Tim Northover
50772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMOVZ64Imm() const {
508f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    static const AArch64MCExpr::VariantKind PermittedModifiers[] = {
50972062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G0,
51072062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G1,
51172062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G2,
51272062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G3,
51372062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G0,
51472062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G1,
51572062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_SABS_G2,
51672062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G2,
51772062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G1,
51872062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G0,
51972062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_GOTTPREL_G1,
52072062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G2,
52172062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G1,
52272062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G0,
52372062f5744557e270a38192554c3126ea5f97434Tim Northover    };
524f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    const unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers);
52572062f5744557e270a38192554c3126ea5f97434Tim Northover
52672062f5744557e270a38192554c3126ea5f97434Tim Northover    return isMoveWideImm(64, PermittedModifiers, NumModifiers);
52772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
52872062f5744557e270a38192554c3126ea5f97434Tim Northover
52972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMOVK32Imm() const {
530f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    static const AArch64MCExpr::VariantKind PermittedModifiers[] = {
53172062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G0_NC,
53272062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G1_NC,
53372062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC,
53472062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC,
53572062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC,
53672062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G1_NC,
53772062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G0_NC,
53872062f5744557e270a38192554c3126ea5f97434Tim Northover    };
539f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    const unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers);
54072062f5744557e270a38192554c3126ea5f97434Tim Northover
54172062f5744557e270a38192554c3126ea5f97434Tim Northover    return isMoveWideImm(32, PermittedModifiers, NumModifiers);
54272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
54372062f5744557e270a38192554c3126ea5f97434Tim Northover
54472062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMOVK64Imm() const {
545f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    static const AArch64MCExpr::VariantKind PermittedModifiers[] = {
54672062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G0_NC,
54772062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G1_NC,
54872062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G2_NC,
54972062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_ABS_G3,
55072062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC,
55172062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC,
55272062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC,
55372062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G1_NC,
55472062f5744557e270a38192554c3126ea5f97434Tim Northover      AArch64MCExpr::VK_AARCH64_TPREL_G0_NC,
55572062f5744557e270a38192554c3126ea5f97434Tim Northover    };
556f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper    const unsigned NumModifiers = llvm::array_lengthof(PermittedModifiers);
55772062f5744557e270a38192554c3126ea5f97434Tim Northover
55872062f5744557e270a38192554c3126ea5f97434Tim Northover    return isMoveWideImm(64, PermittedModifiers, NumModifiers);
55972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
56072062f5744557e270a38192554c3126ea5f97434Tim Northover
56172062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMoveWideImm(unsigned RegWidth,
562f67c7d7e8c5949037e85dd233876989c1fea7099Craig Topper                     const AArch64MCExpr::VariantKind *PermittedModifiers,
56372062f5744557e270a38192554c3126ea5f97434Tim Northover                     unsigned NumModifiers) const {
56472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImmWithLSL()) return false;
56572062f5744557e270a38192554c3126ea5f97434Tim Northover
56672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ImmWithLSL.ShiftAmount % 16 != 0) return false;
56772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ImmWithLSL.ShiftAmount >= RegWidth) return false;
56872062f5744557e270a38192554c3126ea5f97434Tim Northover
56972062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64MCExpr::VariantKind Modifier;
57072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (isNonConstantExpr(ImmWithLSL.Val, Modifier)) {
57172062f5744557e270a38192554c3126ea5f97434Tim Northover      // E.g. "#:abs_g0:sym, lsl #16" makes no sense.
57272062f5744557e270a38192554c3126ea5f97434Tim Northover      if (!ImmWithLSL.ImplicitAmount) return false;
57372062f5744557e270a38192554c3126ea5f97434Tim Northover
57472062f5744557e270a38192554c3126ea5f97434Tim Northover      for (unsigned i = 0; i < NumModifiers; ++i)
57572062f5744557e270a38192554c3126ea5f97434Tim Northover        if (PermittedModifiers[i] == Modifier) return true;
57672062f5744557e270a38192554c3126ea5f97434Tim Northover
57772062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
57872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
57972062f5744557e270a38192554c3126ea5f97434Tim Northover
58072062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmWithLSL.Val);
58172062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE && CE->getValue() >= 0  && CE->getValue() <= 0xffff;
58272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
58372062f5744557e270a38192554c3126ea5f97434Tim Northover
58472062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int RegWidth, bool (*isValidImm)(int, uint64_t, int&, int&)>
58572062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMoveWideMovAlias() const {
58672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
58772062f5744557e270a38192554c3126ea5f97434Tim Northover
58872062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
58972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
59072062f5744557e270a38192554c3126ea5f97434Tim Northover
59172062f5744557e270a38192554c3126ea5f97434Tim Northover    int UImm16, Shift;
59272062f5744557e270a38192554c3126ea5f97434Tim Northover    uint64_t Value = CE->getValue();
59372062f5744557e270a38192554c3126ea5f97434Tim Northover
59472062f5744557e270a38192554c3126ea5f97434Tim Northover    // If this is a 32-bit instruction then all bits above 32 should be the
59572062f5744557e270a38192554c3126ea5f97434Tim Northover    // same: either of these is fine because signed/unsigned values should be
59672062f5744557e270a38192554c3126ea5f97434Tim Northover    // permitted.
59772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (RegWidth == 32) {
59872062f5744557e270a38192554c3126ea5f97434Tim Northover      if ((Value >> 32) != 0 && (Value >> 32) != 0xffffffff)
59972062f5744557e270a38192554c3126ea5f97434Tim Northover        return false;
60072062f5744557e270a38192554c3126ea5f97434Tim Northover
60172062f5744557e270a38192554c3126ea5f97434Tim Northover      Value &= 0xffffffffULL;
60272062f5744557e270a38192554c3126ea5f97434Tim Northover    }
60372062f5744557e270a38192554c3126ea5f97434Tim Northover
60472062f5744557e270a38192554c3126ea5f97434Tim Northover    return isValidImm(RegWidth, Value, UImm16, Shift);
60572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
60672062f5744557e270a38192554c3126ea5f97434Tim Northover
60772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMSRWithReg() const {
60872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isSysReg()) return false;
60972062f5744557e270a38192554c3126ea5f97434Tim Northover
61072062f5744557e270a38192554c3126ea5f97434Tim Northover    bool IsKnownRegister;
61172062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef Name(SysReg.Data, SysReg.Length);
61272062f5744557e270a38192554c3126ea5f97434Tim Northover    A64SysReg::MSRMapper().fromString(Name, IsKnownRegister);
61372062f5744557e270a38192554c3126ea5f97434Tim Northover
61472062f5744557e270a38192554c3126ea5f97434Tim Northover    return IsKnownRegister;
61572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
61672062f5744557e270a38192554c3126ea5f97434Tim Northover
61772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMSRPState() const {
61872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isSysReg()) return false;
61972062f5744557e270a38192554c3126ea5f97434Tim Northover
62072062f5744557e270a38192554c3126ea5f97434Tim Northover    bool IsKnownRegister;
62172062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef Name(SysReg.Data, SysReg.Length);
62272062f5744557e270a38192554c3126ea5f97434Tim Northover    A64PState::PStateMapper().fromString(Name, IsKnownRegister);
62372062f5744557e270a38192554c3126ea5f97434Tim Northover
62472062f5744557e270a38192554c3126ea5f97434Tim Northover    return IsKnownRegister;
62572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
62672062f5744557e270a38192554c3126ea5f97434Tim Northover
62772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isMRS() const {
62872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isSysReg()) return false;
62972062f5744557e270a38192554c3126ea5f97434Tim Northover
63072062f5744557e270a38192554c3126ea5f97434Tim Northover    // First check against specific MSR-only (write-only) registers
63172062f5744557e270a38192554c3126ea5f97434Tim Northover    bool IsKnownRegister;
63272062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef Name(SysReg.Data, SysReg.Length);
63372062f5744557e270a38192554c3126ea5f97434Tim Northover    A64SysReg::MRSMapper().fromString(Name, IsKnownRegister);
63472062f5744557e270a38192554c3126ea5f97434Tim Northover
63572062f5744557e270a38192554c3126ea5f97434Tim Northover    return IsKnownRegister;
63672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
63772062f5744557e270a38192554c3126ea5f97434Tim Northover
63872062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isPRFM() const {
63972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
64072062f5744557e270a38192554c3126ea5f97434Tim Northover
64172062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
64272062f5744557e270a38192554c3126ea5f97434Tim Northover
64372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE)
64472062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
64572062f5744557e270a38192554c3126ea5f97434Tim Northover
64672062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE->getValue() >= 0 && CE->getValue() <= 31;
64772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
64872062f5744557e270a38192554c3126ea5f97434Tim Northover
64972062f5744557e270a38192554c3126ea5f97434Tim Northover  template<A64SE::ShiftExtSpecifiers SHKind> bool isRegExtend() const {
65072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isShiftOrExtend()) return false;
65172062f5744557e270a38192554c3126ea5f97434Tim Northover
65272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ShiftExtend.ShiftType != SHKind)
65372062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
65472062f5744557e270a38192554c3126ea5f97434Tim Northover
65572062f5744557e270a38192554c3126ea5f97434Tim Northover    return ShiftExtend.Amount <= 4;
65672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
65772062f5744557e270a38192554c3126ea5f97434Tim Northover
65872062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isRegExtendLSL() const {
65972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isShiftOrExtend()) return false;
66072062f5744557e270a38192554c3126ea5f97434Tim Northover
66172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ShiftExtend.ShiftType != A64SE::LSL)
66272062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
66372062f5744557e270a38192554c3126ea5f97434Tim Northover
66472062f5744557e270a38192554c3126ea5f97434Tim Northover    return !ShiftExtend.ImplicitAmount && ShiftExtend.Amount <= 4;
66572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
66672062f5744557e270a38192554c3126ea5f97434Tim Northover
66787773c318fcee853fb34a80a10c4347d523bdafbTim Northover  bool isNeonMovImmShiftLSL() const {
66887773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (!isShiftOrExtend())
66987773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
67087773c318fcee853fb34a80a10c4347d523bdafbTim Northover
67187773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (ShiftExtend.ShiftType != A64SE::LSL)
67287773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
67387773c318fcee853fb34a80a10c4347d523bdafbTim Northover
67487773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // Valid shift amount is 0, 8, 16 and 24.
67587773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return ShiftExtend.Amount % 8 == 0 && ShiftExtend.Amount <= 24;
67687773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
67787773c318fcee853fb34a80a10c4347d523bdafbTim Northover
67887773c318fcee853fb34a80a10c4347d523bdafbTim Northover  bool isNeonMovImmShiftLSLH() const {
67987773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (!isShiftOrExtend())
68087773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
68187773c318fcee853fb34a80a10c4347d523bdafbTim Northover
68287773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (ShiftExtend.ShiftType != A64SE::LSL)
68387773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
68487773c318fcee853fb34a80a10c4347d523bdafbTim Northover
68587773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // Valid shift amount is 0 and 8.
68687773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return ShiftExtend.Amount == 0 || ShiftExtend.Amount == 8;
68787773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
68887773c318fcee853fb34a80a10c4347d523bdafbTim Northover
68987773c318fcee853fb34a80a10c4347d523bdafbTim Northover  bool isNeonMovImmShiftMSL() const {
69087773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (!isShiftOrExtend())
69187773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
69287773c318fcee853fb34a80a10c4347d523bdafbTim Northover
69387773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (ShiftExtend.ShiftType != A64SE::MSL)
69487773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
69587773c318fcee853fb34a80a10c4347d523bdafbTim Northover
69687773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // Valid shift amount is 8 and 16.
69787773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return ShiftExtend.Amount == 8 || ShiftExtend.Amount == 16;
69887773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
69987773c318fcee853fb34a80a10c4347d523bdafbTim Northover
70087773c318fcee853fb34a80a10c4347d523bdafbTim Northover  template <int MemSize> bool isSImm7Scaled() const {
70187773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (!isImm())
70287773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
70372062f5744557e270a38192554c3126ea5f97434Tim Northover
70472062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
70572062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
70672062f5744557e270a38192554c3126ea5f97434Tim Northover
70772062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t Val = CE->getValue();
70872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Val % MemSize != 0) return false;
70972062f5744557e270a38192554c3126ea5f97434Tim Northover
71072062f5744557e270a38192554c3126ea5f97434Tim Northover    Val /= MemSize;
71172062f5744557e270a38192554c3126ea5f97434Tim Northover
71272062f5744557e270a38192554c3126ea5f97434Tim Northover    return Val >= -64 && Val < 64;
71372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
71472062f5744557e270a38192554c3126ea5f97434Tim Northover
71572062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int BitWidth>
71672062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isSImm() const {
71772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
71872062f5744557e270a38192554c3126ea5f97434Tim Northover
71972062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
72072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
72172062f5744557e270a38192554c3126ea5f97434Tim Northover
72272062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE->getValue() >= -(1LL << (BitWidth - 1))
72372062f5744557e270a38192554c3126ea5f97434Tim Northover      && CE->getValue() < (1LL << (BitWidth - 1));
72472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
72572062f5744557e270a38192554c3126ea5f97434Tim Northover
72672062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int bitWidth>
72772062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isUImm() const {
72872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
72972062f5744557e270a38192554c3126ea5f97434Tim Northover
73072062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
73172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) return false;
73272062f5744557e270a38192554c3126ea5f97434Tim Northover
73372062f5744557e270a38192554c3126ea5f97434Tim Northover    return CE->getValue() >= 0 && CE->getValue() < (1LL << bitWidth);
73472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
73572062f5744557e270a38192554c3126ea5f97434Tim Northover
73672062f5744557e270a38192554c3126ea5f97434Tim Northover  bool isUImm() const {
73772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isImm()) return false;
73872062f5744557e270a38192554c3126ea5f97434Tim Northover
73972062f5744557e270a38192554c3126ea5f97434Tim Northover    return isa<MCConstantExpr>(getImm());
74072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
74172062f5744557e270a38192554c3126ea5f97434Tim Northover
74287773c318fcee853fb34a80a10c4347d523bdafbTim Northover  bool isNeonUImm64Mask() const {
74387773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (!isImm())
74487773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
74587773c318fcee853fb34a80a10c4347d523bdafbTim Northover
74687773c318fcee853fb34a80a10c4347d523bdafbTim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
74787773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (!CE)
74887773c318fcee853fb34a80a10c4347d523bdafbTim Northover      return false;
74987773c318fcee853fb34a80a10c4347d523bdafbTim Northover
75087773c318fcee853fb34a80a10c4347d523bdafbTim Northover    uint64_t Value = CE->getValue();
75187773c318fcee853fb34a80a10c4347d523bdafbTim Northover
75287773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // i64 value with each byte being either 0x00 or 0xff.
75387773c318fcee853fb34a80a10c4347d523bdafbTim Northover    for (unsigned i = 0; i < 8; ++i, Value >>= 8)
75487773c318fcee853fb34a80a10c4347d523bdafbTim Northover      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff)
75587773c318fcee853fb34a80a10c4347d523bdafbTim Northover        return false;
75687773c318fcee853fb34a80a10c4347d523bdafbTim Northover    return true;
75787773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
75887773c318fcee853fb34a80a10c4347d523bdafbTim Northover
75972062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateImmWithLSL(const MCExpr *Val,
76072062f5744557e270a38192554c3126ea5f97434Tim Northover                                          unsigned ShiftAmount,
76172062f5744557e270a38192554c3126ea5f97434Tim Northover                                          bool ImplicitAmount,
76287773c318fcee853fb34a80a10c4347d523bdafbTim Northover										  SMLoc S,SMLoc E) {
76372062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_ImmWithLSL, S, E);
76472062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->ImmWithLSL.Val = Val;
76572062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->ImmWithLSL.ShiftAmount = ShiftAmount;
76672062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->ImmWithLSL.ImplicitAmount = ImplicitAmount;
76772062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
76872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
76972062f5744557e270a38192554c3126ea5f97434Tim Northover
77072062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateCondCode(A64CC::CondCodes Code,
77172062f5744557e270a38192554c3126ea5f97434Tim Northover                                        SMLoc S, SMLoc E) {
77272062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_CondCode, S, E);
77372062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->CondCode.Code = Code;
77472062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
77572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
77672062f5744557e270a38192554c3126ea5f97434Tim Northover
77772062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateFPImm(double Val,
77872062f5744557e270a38192554c3126ea5f97434Tim Northover                                     SMLoc S, SMLoc E) {
77972062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_FPImmediate, S, E);
78072062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->FPImm.Val = Val;
78172062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
78272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
78372062f5744557e270a38192554c3126ea5f97434Tim Northover
78472062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
78572062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_Immediate, S, E);
78672062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->Imm.Val = Val;
78772062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
78872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
78972062f5744557e270a38192554c3126ea5f97434Tim Northover
79072062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
79172062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_Register, S, E);
79272062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->Reg.RegNum = RegNum;
79372062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
79472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
79572062f5744557e270a38192554c3126ea5f97434Tim Northover
79672062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateWrappedReg(unsigned RegNum, SMLoc S, SMLoc E) {
79772062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_WrappedRegister, S, E);
79872062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->Reg.RegNum = RegNum;
79972062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
80072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
80172062f5744557e270a38192554c3126ea5f97434Tim Northover
80272062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateShiftExtend(A64SE::ShiftExtSpecifiers ShiftTyp,
80372062f5744557e270a38192554c3126ea5f97434Tim Northover                                           unsigned Amount,
80472062f5744557e270a38192554c3126ea5f97434Tim Northover                                           bool ImplicitAmount,
80572062f5744557e270a38192554c3126ea5f97434Tim Northover                                           SMLoc S, SMLoc E) {
80672062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_ShiftExtend, S, E);
80772062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->ShiftExtend.ShiftType = ShiftTyp;
80872062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->ShiftExtend.Amount = Amount;
80972062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->ShiftExtend.ImplicitAmount = ImplicitAmount;
81072062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
81172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
81272062f5744557e270a38192554c3126ea5f97434Tim Northover
81372062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateSysReg(StringRef Str, SMLoc S) {
81472062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_SysReg, S, S);
81572062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->Tok.Data = Str.data();
81672062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->Tok.Length = Str.size();
81772062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
81872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
81972062f5744557e270a38192554c3126ea5f97434Tim Northover
82072062f5744557e270a38192554c3126ea5f97434Tim Northover  static AArch64Operand *CreateToken(StringRef Str, SMLoc S) {
82172062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64Operand *Op = new AArch64Operand(k_Token, S, S);
82272062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->Tok.Data = Str.data();
82372062f5744557e270a38192554c3126ea5f97434Tim Northover    Op->Tok.Length = Str.size();
82472062f5744557e270a38192554c3126ea5f97434Tim Northover    return Op;
82572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
82672062f5744557e270a38192554c3126ea5f97434Tim Northover
82772062f5744557e270a38192554c3126ea5f97434Tim Northover
82872062f5744557e270a38192554c3126ea5f97434Tim Northover  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
82972062f5744557e270a38192554c3126ea5f97434Tim Northover    // Add as immediates when possible.
83072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
83172062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
83272062f5744557e270a38192554c3126ea5f97434Tim Northover    else
83372062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateExpr(Expr));
83472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
83572062f5744557e270a38192554c3126ea5f97434Tim Northover
83672062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned RegWidth>
83772062f5744557e270a38192554c3126ea5f97434Tim Northover  void addBFILSBOperands(MCInst &Inst, unsigned N) const {
83872062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
83972062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
84072062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned EncodedVal = (RegWidth - CE->getValue()) % RegWidth;
84172062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(EncodedVal));
84272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
84372062f5744557e270a38192554c3126ea5f97434Tim Northover
84472062f5744557e270a38192554c3126ea5f97434Tim Northover  void addBFIWidthOperands(MCInst &Inst, unsigned N) const {
84572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
84672062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
84772062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
84872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
84972062f5744557e270a38192554c3126ea5f97434Tim Northover
85072062f5744557e270a38192554c3126ea5f97434Tim Northover  void addBFXWidthOperands(MCInst &Inst, unsigned N) const {
85172062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
85272062f5744557e270a38192554c3126ea5f97434Tim Northover
85372062f5744557e270a38192554c3126ea5f97434Tim Northover    uint64_t LSB = Inst.getOperand(Inst.getNumOperands()-1).getImm();
85472062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
85572062f5744557e270a38192554c3126ea5f97434Tim Northover
85672062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(LSB + CE->getValue() - 1));
85772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
85872062f5744557e270a38192554c3126ea5f97434Tim Northover
85972062f5744557e270a38192554c3126ea5f97434Tim Northover  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
86072062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
86172062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(getCondCode()));
86272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
86372062f5744557e270a38192554c3126ea5f97434Tim Northover
86472062f5744557e270a38192554c3126ea5f97434Tim Northover  void addCVTFixedPosOperands(MCInst &Inst, unsigned N) const {
86572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
86672062f5744557e270a38192554c3126ea5f97434Tim Northover
86772062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
86872062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(64 - CE->getValue()));
86972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
87072062f5744557e270a38192554c3126ea5f97434Tim Northover
87172062f5744557e270a38192554c3126ea5f97434Tim Northover  void addFMOVImmOperands(MCInst &Inst, unsigned N) const {
87272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
87372062f5744557e270a38192554c3126ea5f97434Tim Northover
87472062f5744557e270a38192554c3126ea5f97434Tim Northover    APFloat RealVal(FPImm.Val);
87572062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t ImmVal;
87672062f5744557e270a38192554c3126ea5f97434Tim Northover    A64Imms::isFPImm(RealVal, ImmVal);
87772062f5744557e270a38192554c3126ea5f97434Tim Northover
87872062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(ImmVal));
87972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
88072062f5744557e270a38192554c3126ea5f97434Tim Northover
88172062f5744557e270a38192554c3126ea5f97434Tim Northover  void addFPZeroOperands(MCInst &Inst, unsigned N) const {
88272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands");
88372062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(0));
88472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
88572062f5744557e270a38192554c3126ea5f97434Tim Northover
88672062f5744557e270a38192554c3126ea5f97434Tim Northover  void addInvCondCodeOperands(MCInst &Inst, unsigned N) const {
88772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
88872062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned Encoded = A64InvertCondCode(getCondCode());
88972062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Encoded));
89072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
89172062f5744557e270a38192554c3126ea5f97434Tim Northover
89272062f5744557e270a38192554c3126ea5f97434Tim Northover  void addRegOperands(MCInst &Inst, unsigned N) const {
89372062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
89472062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateReg(getReg()));
89572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
89672062f5744557e270a38192554c3126ea5f97434Tim Northover
89772062f5744557e270a38192554c3126ea5f97434Tim Northover  void addImmOperands(MCInst &Inst, unsigned N) const {
89872062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
89972062f5744557e270a38192554c3126ea5f97434Tim Northover    addExpr(Inst, getImm());
90072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
90172062f5744557e270a38192554c3126ea5f97434Tim Northover
90272062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int MemSize>
90372062f5744557e270a38192554c3126ea5f97434Tim Northover  void addSImm7ScaledOperands(MCInst &Inst, unsigned N) const {
90472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
90572062f5744557e270a38192554c3126ea5f97434Tim Northover
90672062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
90772062f5744557e270a38192554c3126ea5f97434Tim Northover    uint64_t Val = CE->getValue() / MemSize;
90872062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Val  & 0x7f));
90972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
91072062f5744557e270a38192554c3126ea5f97434Tim Northover
91172062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int BitWidth>
91272062f5744557e270a38192554c3126ea5f97434Tim Northover  void addSImmOperands(MCInst &Inst, unsigned N) const {
91372062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
91472062f5744557e270a38192554c3126ea5f97434Tim Northover
91572062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
91672062f5744557e270a38192554c3126ea5f97434Tim Northover    uint64_t Val = CE->getValue();
91772062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Val  & ((1ULL << BitWidth) - 1)));
91872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
91972062f5744557e270a38192554c3126ea5f97434Tim Northover
92072062f5744557e270a38192554c3126ea5f97434Tim Northover  void addImmWithLSLOperands(MCInst &Inst, unsigned N) const {
92172062f5744557e270a38192554c3126ea5f97434Tim Northover    assert (N == 1 && "Invalid number of operands!");
92272062f5744557e270a38192554c3126ea5f97434Tim Northover
92372062f5744557e270a38192554c3126ea5f97434Tim Northover    addExpr(Inst, ImmWithLSL.Val);
92472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
92572062f5744557e270a38192554c3126ea5f97434Tim Northover
92672062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned field_width, unsigned scale>
92772062f5744557e270a38192554c3126ea5f97434Tim Northover  void addLabelOperands(MCInst &Inst, unsigned N) const {
92872062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
92972062f5744557e270a38192554c3126ea5f97434Tim Northover
93072062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
93172062f5744557e270a38192554c3126ea5f97434Tim Northover
93272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE) {
93372062f5744557e270a38192554c3126ea5f97434Tim Northover      addExpr(Inst, Imm.Val);
93472062f5744557e270a38192554c3126ea5f97434Tim Northover      return;
93572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
93672062f5744557e270a38192554c3126ea5f97434Tim Northover
93772062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t Val = CE->getValue();
93872062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(Val % scale == 0 && "Unaligned immediate in instruction");
93972062f5744557e270a38192554c3126ea5f97434Tim Northover    Val /= scale;
94072062f5744557e270a38192554c3126ea5f97434Tim Northover
94172062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Val & ((1LL << field_width) - 1)));
94272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
94372062f5744557e270a38192554c3126ea5f97434Tim Northover
94472062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int MemSize>
94572062f5744557e270a38192554c3126ea5f97434Tim Northover  void addOffsetUImm12Operands(MCInst &Inst, unsigned N) const {
94672062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
94772062f5744557e270a38192554c3126ea5f97434Tim Northover
94872062f5744557e270a38192554c3126ea5f97434Tim Northover    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
94972062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(CE->getValue() / MemSize));
95072062f5744557e270a38192554c3126ea5f97434Tim Northover    } else {
95172062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateExpr(getImm()));
95272062f5744557e270a38192554c3126ea5f97434Tim Northover    }
95372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
95472062f5744557e270a38192554c3126ea5f97434Tim Northover
95572062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned RegWidth>
95672062f5744557e270a38192554c3126ea5f97434Tim Northover  void addLogicalImmOperands(MCInst &Inst, unsigned N) const {
95772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands");
95872062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(Imm.Val);
95972062f5744557e270a38192554c3126ea5f97434Tim Northover
96072062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t Bits;
96172062f5744557e270a38192554c3126ea5f97434Tim Northover    A64Imms::isLogicalImm(RegWidth, CE->getValue(), Bits);
96272062f5744557e270a38192554c3126ea5f97434Tim Northover
96372062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Bits));
96472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
96572062f5744557e270a38192554c3126ea5f97434Tim Northover
96672062f5744557e270a38192554c3126ea5f97434Tim Northover  void addMRSOperands(MCInst &Inst, unsigned N) const {
96772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
96872062f5744557e270a38192554c3126ea5f97434Tim Northover
96972062f5744557e270a38192554c3126ea5f97434Tim Northover    bool Valid;
97072062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef Name(SysReg.Data, SysReg.Length);
97172062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t Bits = A64SysReg::MRSMapper().fromString(Name, Valid);
97272062f5744557e270a38192554c3126ea5f97434Tim Northover
97372062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Bits));
97472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
97572062f5744557e270a38192554c3126ea5f97434Tim Northover
97672062f5744557e270a38192554c3126ea5f97434Tim Northover  void addMSRWithRegOperands(MCInst &Inst, unsigned N) const {
97772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
97872062f5744557e270a38192554c3126ea5f97434Tim Northover
97972062f5744557e270a38192554c3126ea5f97434Tim Northover    bool Valid;
98072062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef Name(SysReg.Data, SysReg.Length);
98172062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t Bits = A64SysReg::MSRMapper().fromString(Name, Valid);
98272062f5744557e270a38192554c3126ea5f97434Tim Northover
98372062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Bits));
98472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
98572062f5744557e270a38192554c3126ea5f97434Tim Northover
98672062f5744557e270a38192554c3126ea5f97434Tim Northover  void addMSRPStateOperands(MCInst &Inst, unsigned N) const {
98772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
98872062f5744557e270a38192554c3126ea5f97434Tim Northover
98972062f5744557e270a38192554c3126ea5f97434Tim Northover    bool Valid;
99072062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef Name(SysReg.Data, SysReg.Length);
99172062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t Bits = A64PState::PStateMapper().fromString(Name, Valid);
99272062f5744557e270a38192554c3126ea5f97434Tim Northover
99372062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Bits));
99472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
99572062f5744557e270a38192554c3126ea5f97434Tim Northover
99672062f5744557e270a38192554c3126ea5f97434Tim Northover  void addMoveWideImmOperands(MCInst &Inst, unsigned N) const {
99772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 2 && "Invalid number of operands!");
99872062f5744557e270a38192554c3126ea5f97434Tim Northover
99972062f5744557e270a38192554c3126ea5f97434Tim Northover    addExpr(Inst, ImmWithLSL.Val);
100072062f5744557e270a38192554c3126ea5f97434Tim Northover
100172062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64MCExpr::VariantKind Variant;
100272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!isNonConstantExpr(ImmWithLSL.Val, Variant)) {
100372062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(ImmWithLSL.ShiftAmount / 16));
100472062f5744557e270a38192554c3126ea5f97434Tim Northover      return;
100572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
100672062f5744557e270a38192554c3126ea5f97434Tim Northover
100772062f5744557e270a38192554c3126ea5f97434Tim Northover    // We know it's relocated
100872062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Variant) {
100972062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_ABS_G0:
101072062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_ABS_G0_NC:
101172062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_SABS_G0:
101272062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_DTPREL_G0:
101372062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC:
101472062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC:
101572062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_TPREL_G0:
101672062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_TPREL_G0_NC:
101772062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(0));
101872062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
101972062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_ABS_G1:
102072062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_ABS_G1_NC:
102172062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_SABS_G1:
102272062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_DTPREL_G1:
102372062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC:
102472062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_GOTTPREL_G1:
102572062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_TPREL_G1:
102672062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_TPREL_G1_NC:
102772062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(1));
102872062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
102972062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_ABS_G2:
103072062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_ABS_G2_NC:
103172062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_SABS_G2:
103272062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_DTPREL_G2:
103372062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_TPREL_G2:
103472062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(2));
103572062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
103672062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64MCExpr::VK_AARCH64_ABS_G3:
103772062f5744557e270a38192554c3126ea5f97434Tim Northover      Inst.addOperand(MCOperand::CreateImm(3));
103872062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
103972062f5744557e270a38192554c3126ea5f97434Tim Northover    default: llvm_unreachable("Inappropriate move wide relocation");
104072062f5744557e270a38192554c3126ea5f97434Tim Northover    }
104172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
104272062f5744557e270a38192554c3126ea5f97434Tim Northover
104372062f5744557e270a38192554c3126ea5f97434Tim Northover  template<int RegWidth, bool isValidImm(int, uint64_t, int&, int&)>
104472062f5744557e270a38192554c3126ea5f97434Tim Northover  void addMoveWideMovAliasOperands(MCInst &Inst, unsigned N) const {
104572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 2 && "Invalid number of operands!");
104672062f5744557e270a38192554c3126ea5f97434Tim Northover    int UImm16, Shift;
104772062f5744557e270a38192554c3126ea5f97434Tim Northover
104872062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
104972062f5744557e270a38192554c3126ea5f97434Tim Northover    uint64_t Value = CE->getValue();
105072062f5744557e270a38192554c3126ea5f97434Tim Northover
105172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (RegWidth == 32) {
105272062f5744557e270a38192554c3126ea5f97434Tim Northover      Value &= 0xffffffffULL;
105372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
105472062f5744557e270a38192554c3126ea5f97434Tim Northover
105572062f5744557e270a38192554c3126ea5f97434Tim Northover    bool Valid = isValidImm(RegWidth, Value, UImm16, Shift);
105672062f5744557e270a38192554c3126ea5f97434Tim Northover    (void)Valid;
105772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(Valid && "Invalid immediates should have been weeded out by now");
105872062f5744557e270a38192554c3126ea5f97434Tim Northover
105972062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(UImm16));
106072062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(Shift));
106172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
106272062f5744557e270a38192554c3126ea5f97434Tim Northover
106372062f5744557e270a38192554c3126ea5f97434Tim Northover  void addPRFMOperands(MCInst &Inst, unsigned N) const {
106472062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
106572062f5744557e270a38192554c3126ea5f97434Tim Northover
106672062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
106772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(CE->getValue() >= 0 && CE->getValue() <= 31
106872062f5744557e270a38192554c3126ea5f97434Tim Northover           && "PRFM operand should be 5-bits");
106972062f5744557e270a38192554c3126ea5f97434Tim Northover
107072062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
107172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
107272062f5744557e270a38192554c3126ea5f97434Tim Northover
107372062f5744557e270a38192554c3126ea5f97434Tim Northover  // For Add-sub (extended register) operands.
107472062f5744557e270a38192554c3126ea5f97434Tim Northover  void addRegExtendOperands(MCInst &Inst, unsigned N) const {
107572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
107672062f5744557e270a38192554c3126ea5f97434Tim Northover
107772062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(ShiftExtend.Amount));
107872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
107972062f5744557e270a38192554c3126ea5f97434Tim Northover
108087773c318fcee853fb34a80a10c4347d523bdafbTim Northover  // For Vector Immediates shifted imm operands.
108187773c318fcee853fb34a80a10c4347d523bdafbTim Northover  void addNeonMovImmShiftLSLOperands(MCInst &Inst, unsigned N) const {
108287773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
108387773c318fcee853fb34a80a10c4347d523bdafbTim Northover
108487773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (ShiftExtend.Amount % 8 != 0 || ShiftExtend.Amount > 24)
108587773c318fcee853fb34a80a10c4347d523bdafbTim Northover      llvm_unreachable("Invalid shift amount for vector immediate inst.");
108687773c318fcee853fb34a80a10c4347d523bdafbTim Northover
108787773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // Encode LSL shift amount 0, 8, 16, 24 as 0, 1, 2, 3.
108887773c318fcee853fb34a80a10c4347d523bdafbTim Northover    int64_t Imm = ShiftExtend.Amount / 8;
108987773c318fcee853fb34a80a10c4347d523bdafbTim Northover    Inst.addOperand(MCOperand::CreateImm(Imm));
109087773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
109187773c318fcee853fb34a80a10c4347d523bdafbTim Northover
109287773c318fcee853fb34a80a10c4347d523bdafbTim Northover  void addNeonMovImmShiftLSLHOperands(MCInst &Inst, unsigned N) const {
109387773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
109487773c318fcee853fb34a80a10c4347d523bdafbTim Northover
109587773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (ShiftExtend.Amount != 0 && ShiftExtend.Amount != 8)
109687773c318fcee853fb34a80a10c4347d523bdafbTim Northover      llvm_unreachable("Invalid shift amount for vector immediate inst.");
109787773c318fcee853fb34a80a10c4347d523bdafbTim Northover
109887773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // Encode LSLH shift amount 0, 8  as 0, 1.
109987773c318fcee853fb34a80a10c4347d523bdafbTim Northover    int64_t Imm = ShiftExtend.Amount / 8;
110087773c318fcee853fb34a80a10c4347d523bdafbTim Northover    Inst.addOperand(MCOperand::CreateImm(Imm));
110187773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
110287773c318fcee853fb34a80a10c4347d523bdafbTim Northover
110387773c318fcee853fb34a80a10c4347d523bdafbTim Northover  void addNeonMovImmShiftMSLOperands(MCInst &Inst, unsigned N) const {
110487773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
110587773c318fcee853fb34a80a10c4347d523bdafbTim Northover
110687773c318fcee853fb34a80a10c4347d523bdafbTim Northover    if (ShiftExtend.Amount != 8 && ShiftExtend.Amount != 16)
110787773c318fcee853fb34a80a10c4347d523bdafbTim Northover      llvm_unreachable("Invalid shift amount for vector immediate inst.");
110887773c318fcee853fb34a80a10c4347d523bdafbTim Northover
110987773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // Encode MSL shift amount 8, 16  as 0, 1.
111087773c318fcee853fb34a80a10c4347d523bdafbTim Northover    int64_t Imm = ShiftExtend.Amount / 8 - 1;
111187773c318fcee853fb34a80a10c4347d523bdafbTim Northover    Inst.addOperand(MCOperand::CreateImm(Imm));
111287773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
111387773c318fcee853fb34a80a10c4347d523bdafbTim Northover
111472062f5744557e270a38192554c3126ea5f97434Tim Northover  // For the extend in load-store (register offset) instructions.
111572062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned MemSize>
111672062f5744557e270a38192554c3126ea5f97434Tim Northover  void addAddrRegExtendOperands(MCInst &Inst, unsigned N) const {
111772062f5744557e270a38192554c3126ea5f97434Tim Northover    addAddrRegExtendOperands(Inst, N, MemSize);
111872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
111972062f5744557e270a38192554c3126ea5f97434Tim Northover
112072062f5744557e270a38192554c3126ea5f97434Tim Northover  void addAddrRegExtendOperands(MCInst &Inst, unsigned N,
112172062f5744557e270a38192554c3126ea5f97434Tim Northover                                unsigned MemSize) const {
112272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
112372062f5744557e270a38192554c3126ea5f97434Tim Northover
112472062f5744557e270a38192554c3126ea5f97434Tim Northover    // First bit of Option is set in instruction classes, the high two bits are
112572062f5744557e270a38192554c3126ea5f97434Tim Northover    // as follows:
112672062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned OptionHi = 0;
112772062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (ShiftExtend.ShiftType) {
112872062f5744557e270a38192554c3126ea5f97434Tim Northover    case A64SE::UXTW:
112972062f5744557e270a38192554c3126ea5f97434Tim Northover    case A64SE::LSL:
113072062f5744557e270a38192554c3126ea5f97434Tim Northover      OptionHi = 1;
113172062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
113272062f5744557e270a38192554c3126ea5f97434Tim Northover    case A64SE::SXTW:
113372062f5744557e270a38192554c3126ea5f97434Tim Northover    case A64SE::SXTX:
113472062f5744557e270a38192554c3126ea5f97434Tim Northover      OptionHi = 3;
113572062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
113672062f5744557e270a38192554c3126ea5f97434Tim Northover    default:
113772062f5744557e270a38192554c3126ea5f97434Tim Northover      llvm_unreachable("Invalid extend type for register offset");
113872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
113972062f5744557e270a38192554c3126ea5f97434Tim Northover
114072062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned S = 0;
114172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (MemSize == 1 && !ShiftExtend.ImplicitAmount)
114272062f5744557e270a38192554c3126ea5f97434Tim Northover      S = 1;
114372062f5744557e270a38192554c3126ea5f97434Tim Northover    else if (MemSize != 1 && ShiftExtend.Amount != 0)
114472062f5744557e270a38192554c3126ea5f97434Tim Northover      S = 1;
114572062f5744557e270a38192554c3126ea5f97434Tim Northover
114672062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm((OptionHi << 1) | S));
114772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
114872062f5744557e270a38192554c3126ea5f97434Tim Northover  void addShiftOperands(MCInst &Inst, unsigned N) const {
114972062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(N == 1 && "Invalid number of operands!");
115072062f5744557e270a38192554c3126ea5f97434Tim Northover
115172062f5744557e270a38192554c3126ea5f97434Tim Northover    Inst.addOperand(MCOperand::CreateImm(ShiftExtend.Amount));
115272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
115387773c318fcee853fb34a80a10c4347d523bdafbTim Northover
115487773c318fcee853fb34a80a10c4347d523bdafbTim Northover  void addNeonUImm64MaskOperands(MCInst &Inst, unsigned N) const {
115587773c318fcee853fb34a80a10c4347d523bdafbTim Northover    assert(N == 1 && "Invalid number of operands!");
115687773c318fcee853fb34a80a10c4347d523bdafbTim Northover
115787773c318fcee853fb34a80a10c4347d523bdafbTim Northover    // A bit from each byte in the constant forms the encoded immediate
115887773c318fcee853fb34a80a10c4347d523bdafbTim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
115987773c318fcee853fb34a80a10c4347d523bdafbTim Northover    uint64_t Value = CE->getValue();
116087773c318fcee853fb34a80a10c4347d523bdafbTim Northover
116187773c318fcee853fb34a80a10c4347d523bdafbTim Northover    unsigned Imm = 0;
116287773c318fcee853fb34a80a10c4347d523bdafbTim Northover    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
116387773c318fcee853fb34a80a10c4347d523bdafbTim Northover      Imm |= (Value & 1) << i;
116487773c318fcee853fb34a80a10c4347d523bdafbTim Northover    }
116587773c318fcee853fb34a80a10c4347d523bdafbTim Northover    Inst.addOperand(MCOperand::CreateImm(Imm));
116687773c318fcee853fb34a80a10c4347d523bdafbTim Northover  }
116772062f5744557e270a38192554c3126ea5f97434Tim Northover};
116872062f5744557e270a38192554c3126ea5f97434Tim Northover
116972062f5744557e270a38192554c3126ea5f97434Tim Northover} // end anonymous namespace.
117072062f5744557e270a38192554c3126ea5f97434Tim Northover
117172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
117272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
117372062f5744557e270a38192554c3126ea5f97434Tim Northover                               StringRef Mnemonic) {
117472062f5744557e270a38192554c3126ea5f97434Tim Northover
117572062f5744557e270a38192554c3126ea5f97434Tim Northover  // See if the operand has a custom parser
117672062f5744557e270a38192554c3126ea5f97434Tim Northover  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
117772062f5744557e270a38192554c3126ea5f97434Tim Northover
117872062f5744557e270a38192554c3126ea5f97434Tim Northover  // It could either succeed, fail or just not care.
117972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ResTy != MatchOperand_NoMatch)
118072062f5744557e270a38192554c3126ea5f97434Tim Northover    return ResTy;
118172062f5744557e270a38192554c3126ea5f97434Tim Northover
118272062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (getLexer().getKind()) {
118372062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
118472062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "unexpected token in operand");
118572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
118672062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::Identifier: {
118772062f5744557e270a38192554c3126ea5f97434Tim Northover    // It might be in the LSL/UXTB family ...
118872062f5744557e270a38192554c3126ea5f97434Tim Northover    OperandMatchResultTy GotShift = ParseShiftExtend(Operands);
118972062f5744557e270a38192554c3126ea5f97434Tim Northover
119072062f5744557e270a38192554c3126ea5f97434Tim Northover    // We can only continue if no tokens were eaten.
119172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (GotShift != MatchOperand_NoMatch)
119272062f5744557e270a38192554c3126ea5f97434Tim Northover      return GotShift;
119372062f5744557e270a38192554c3126ea5f97434Tim Northover
119472062f5744557e270a38192554c3126ea5f97434Tim Northover    // ... or it might be a register ...
119572062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t NumLanes = 0;
119672062f5744557e270a38192554c3126ea5f97434Tim Northover    OperandMatchResultTy GotReg = ParseRegister(Operands, NumLanes);
119772062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(GotReg != MatchOperand_ParseFail
119872062f5744557e270a38192554c3126ea5f97434Tim Northover           && "register parsing shouldn't partially succeed");
119972062f5744557e270a38192554c3126ea5f97434Tim Northover
120072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (GotReg == MatchOperand_Success) {
120172062f5744557e270a38192554c3126ea5f97434Tim Northover      if (Parser.getTok().is(AsmToken::LBrac))
120272062f5744557e270a38192554c3126ea5f97434Tim Northover        return ParseNEONLane(Operands, NumLanes);
120372062f5744557e270a38192554c3126ea5f97434Tim Northover      else
120472062f5744557e270a38192554c3126ea5f97434Tim Northover        return MatchOperand_Success;
120572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
120672062f5744557e270a38192554c3126ea5f97434Tim Northover
120772062f5744557e270a38192554c3126ea5f97434Tim Northover    // ... or it might be a symbolish thing
120872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
120972062f5744557e270a38192554c3126ea5f97434Tim Northover    // Fall through
121072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::LParen:  // E.g. (strcmp-4)
121172062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::Integer: // 1f, 2b labels
121272062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::String:  // quoted labels
121372062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::Dot:     // . is Current location
121472062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::Dollar:  // $ is PC
121572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::Colon: {
121672062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc StartLoc  = Parser.getTok().getLoc();
121772062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc EndLoc;
121872062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCExpr *ImmVal = 0;
121972062f5744557e270a38192554c3126ea5f97434Tim Northover
122072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ParseImmediate(ImmVal) != MatchOperand_Success)
122172062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_ParseFail;
122272062f5744557e270a38192554c3126ea5f97434Tim Northover
122372062f5744557e270a38192554c3126ea5f97434Tim Northover    EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
122472062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateImm(ImmVal, StartLoc, EndLoc));
122572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
122672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
122772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::Hash: {   // Immediates
122872062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc StartLoc = Parser.getTok().getLoc();
122972062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc EndLoc;
123072062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCExpr *ImmVal = 0;
123172062f5744557e270a38192554c3126ea5f97434Tim Northover    Parser.Lex();
123272062f5744557e270a38192554c3126ea5f97434Tim Northover
123372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ParseImmediate(ImmVal) != MatchOperand_Success)
123472062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_ParseFail;
123572062f5744557e270a38192554c3126ea5f97434Tim Northover
123672062f5744557e270a38192554c3126ea5f97434Tim Northover    EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
123772062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateImm(ImmVal, StartLoc, EndLoc));
123872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
123972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
124072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::LBrac: {
124172062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc Loc = Parser.getTok().getLoc();
124272062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateToken("[", Loc));
124372062f5744557e270a38192554c3126ea5f97434Tim Northover    Parser.Lex(); // Eat '['
124472062f5744557e270a38192554c3126ea5f97434Tim Northover
124572062f5744557e270a38192554c3126ea5f97434Tim Northover    // There's no comma after a '[', so we can parse the next operand
124672062f5744557e270a38192554c3126ea5f97434Tim Northover    // immediately.
124772062f5744557e270a38192554c3126ea5f97434Tim Northover    return ParseOperand(Operands, Mnemonic);
124872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
124972062f5744557e270a38192554c3126ea5f97434Tim Northover  // The following will likely be useful later, but not in very early cases
125072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AsmToken::LCurly:  // Weird SIMD lists
125172062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm_unreachable("Don't know how to deal with '{' in operand");
125272062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
125372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
125472062f5744557e270a38192554c3126ea5f97434Tim Northover}
125572062f5744557e270a38192554c3126ea5f97434Tim Northover
125672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
125772062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseImmediate(const MCExpr *&ExprVal) {
125872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().is(AsmToken::Colon)) {
125972062f5744557e270a38192554c3126ea5f97434Tim Northover    AArch64MCExpr::VariantKind RefKind;
126072062f5744557e270a38192554c3126ea5f97434Tim Northover
126172062f5744557e270a38192554c3126ea5f97434Tim Northover    OperandMatchResultTy ResTy = ParseRelocPrefix(RefKind);
126272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ResTy != MatchOperand_Success)
126372062f5744557e270a38192554c3126ea5f97434Tim Northover      return ResTy;
126472062f5744557e270a38192554c3126ea5f97434Tim Northover
126572062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCExpr *SubExprVal;
1266cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseExpression(SubExprVal))
126772062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_ParseFail;
126872062f5744557e270a38192554c3126ea5f97434Tim Northover
126972062f5744557e270a38192554c3126ea5f97434Tim Northover    ExprVal = AArch64MCExpr::Create(RefKind, SubExprVal, getContext());
127072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
127172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
127272062f5744557e270a38192554c3126ea5f97434Tim Northover
127372062f5744557e270a38192554c3126ea5f97434Tim Northover  // No weird AArch64MCExpr prefix
1274cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach  return getParser().parseExpression(ExprVal)
127572062f5744557e270a38192554c3126ea5f97434Tim Northover    ? MatchOperand_ParseFail : MatchOperand_Success;
127672062f5744557e270a38192554c3126ea5f97434Tim Northover}
127772062f5744557e270a38192554c3126ea5f97434Tim Northover
127872062f5744557e270a38192554c3126ea5f97434Tim Northover// A lane attached to a NEON register. "[N]", which should yield three tokens:
127972062f5744557e270a38192554c3126ea5f97434Tim Northover// '[', N, ']'. A hash is not allowed to precede the immediate here.
128072062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
128172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseNEONLane(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
128272062f5744557e270a38192554c3126ea5f97434Tim Northover                                uint32_t NumLanes) {
128372062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc Loc = Parser.getTok().getLoc();
128472062f5744557e270a38192554c3126ea5f97434Tim Northover
128572062f5744557e270a38192554c3126ea5f97434Tim Northover  assert(Parser.getTok().is(AsmToken::LBrac) && "inappropriate operand");
128672062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateToken("[", Loc));
128772062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat '['
128872062f5744557e270a38192554c3126ea5f97434Tim Northover
128972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Integer)) {
129072062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "expected lane number");
129172062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
129272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
129372062f5744557e270a38192554c3126ea5f97434Tim Northover
129472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().getIntVal() >= NumLanes) {
129572062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "lane number incompatible with layout");
129672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
129772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
129872062f5744557e270a38192554c3126ea5f97434Tim Northover
129972062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCExpr *Lane = MCConstantExpr::Create(Parser.getTok().getIntVal(),
130072062f5744557e270a38192554c3126ea5f97434Tim Northover                                              getContext());
130172062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Parser.getTok().getLoc();
130272062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat actual lane
130372062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc E = Parser.getTok().getLoc();
130472062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateImm(Lane, S, E));
130572062f5744557e270a38192554c3126ea5f97434Tim Northover
130672062f5744557e270a38192554c3126ea5f97434Tim Northover
130772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::RBrac)) {
130872062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "expected ']' after lane");
130972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
131072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
131172062f5744557e270a38192554c3126ea5f97434Tim Northover
131272062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateToken("]", Loc));
131372062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat ']'
131472062f5744557e270a38192554c3126ea5f97434Tim Northover
131572062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
131672062f5744557e270a38192554c3126ea5f97434Tim Northover}
131772062f5744557e270a38192554c3126ea5f97434Tim Northover
131872062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
131972062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseRelocPrefix(AArch64MCExpr::VariantKind &RefKind) {
132072062f5744557e270a38192554c3126ea5f97434Tim Northover  assert(getLexer().is(AsmToken::Colon) && "expected a ':'");
132172062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
132272062f5744557e270a38192554c3126ea5f97434Tim Northover
132372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::Identifier)) {
132472062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(),
132572062f5744557e270a38192554c3126ea5f97434Tim Northover          "expected relocation specifier in operand after ':'");
132672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
132772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
132872062f5744557e270a38192554c3126ea5f97434Tim Northover
132942a68443a15d74ada014ad2c8a2349fe134a44f3Tim Northover  std::string LowerCase = Parser.getTok().getIdentifier().lower();
133042a68443a15d74ada014ad2c8a2349fe134a44f3Tim Northover  RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
133172062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("got",              AArch64MCExpr::VK_AARCH64_GOT)
133272062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("got_lo12",         AArch64MCExpr::VK_AARCH64_GOT_LO12)
133372062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("lo12",             AArch64MCExpr::VK_AARCH64_LO12)
133472062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g0",           AArch64MCExpr::VK_AARCH64_ABS_G0)
133572062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g0_nc",        AArch64MCExpr::VK_AARCH64_ABS_G0_NC)
133672062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g1",           AArch64MCExpr::VK_AARCH64_ABS_G1)
133772062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g1_nc",        AArch64MCExpr::VK_AARCH64_ABS_G1_NC)
133872062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g2",           AArch64MCExpr::VK_AARCH64_ABS_G2)
133972062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g2_nc",        AArch64MCExpr::VK_AARCH64_ABS_G2_NC)
134072062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g3",           AArch64MCExpr::VK_AARCH64_ABS_G3)
134172062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g0_s",         AArch64MCExpr::VK_AARCH64_SABS_G0)
134272062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g1_s",         AArch64MCExpr::VK_AARCH64_SABS_G1)
134372062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("abs_g2_s",         AArch64MCExpr::VK_AARCH64_SABS_G2)
134472062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_g2",        AArch64MCExpr::VK_AARCH64_DTPREL_G2)
134572062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_g1",        AArch64MCExpr::VK_AARCH64_DTPREL_G1)
134672062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_g1_nc",     AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC)
134772062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_g0",        AArch64MCExpr::VK_AARCH64_DTPREL_G0)
134872062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_g0_nc",     AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC)
134972062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_hi12",      AArch64MCExpr::VK_AARCH64_DTPREL_HI12)
135072062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_lo12",      AArch64MCExpr::VK_AARCH64_DTPREL_LO12)
135172062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("dtprel_lo12_nc",   AArch64MCExpr::VK_AARCH64_DTPREL_LO12_NC)
135272062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("gottprel_g1",      AArch64MCExpr::VK_AARCH64_GOTTPREL_G1)
135372062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("gottprel_g0_nc",   AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC)
135472062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("gottprel",         AArch64MCExpr::VK_AARCH64_GOTTPREL)
135572062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("gottprel_lo12",    AArch64MCExpr::VK_AARCH64_GOTTPREL_LO12)
135672062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_g2",         AArch64MCExpr::VK_AARCH64_TPREL_G2)
135772062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_g1",         AArch64MCExpr::VK_AARCH64_TPREL_G1)
135872062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_g1_nc",      AArch64MCExpr::VK_AARCH64_TPREL_G1_NC)
135972062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_g0",         AArch64MCExpr::VK_AARCH64_TPREL_G0)
136072062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_g0_nc",      AArch64MCExpr::VK_AARCH64_TPREL_G0_NC)
136172062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_hi12",       AArch64MCExpr::VK_AARCH64_TPREL_HI12)
136272062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_lo12",       AArch64MCExpr::VK_AARCH64_TPREL_LO12)
136372062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tprel_lo12_nc",    AArch64MCExpr::VK_AARCH64_TPREL_LO12_NC)
136472062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tlsdesc",          AArch64MCExpr::VK_AARCH64_TLSDESC)
136572062f5744557e270a38192554c3126ea5f97434Tim Northover    .Case("tlsdesc_lo12",     AArch64MCExpr::VK_AARCH64_TLSDESC_LO12)
136672062f5744557e270a38192554c3126ea5f97434Tim Northover    .Default(AArch64MCExpr::VK_AARCH64_None);
136772062f5744557e270a38192554c3126ea5f97434Tim Northover
136872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RefKind == AArch64MCExpr::VK_AARCH64_None) {
136972062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(),
137072062f5744557e270a38192554c3126ea5f97434Tim Northover          "expected relocation specifier in operand after ':'");
137172062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
137272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
137372062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat identifier
137472062f5744557e270a38192554c3126ea5f97434Tim Northover
137572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::Colon)) {
137672062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(),
137772062f5744557e270a38192554c3126ea5f97434Tim Northover          "expected ':' after relocation specifier");
137872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
137972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
138072062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
138172062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
138272062f5744557e270a38192554c3126ea5f97434Tim Northover}
138372062f5744557e270a38192554c3126ea5f97434Tim Northover
138472062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
138572062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseImmWithLSLOperand(
138672062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
138772062f5744557e270a38192554c3126ea5f97434Tim Northover  // FIXME?: I want to live in a world where immediates must start with
138872062f5744557e270a38192554c3126ea5f97434Tim Northover  // #. Please don't dash my hopes (well, do if you have a good reason).
138972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Hash)) return MatchOperand_NoMatch;
139072062f5744557e270a38192554c3126ea5f97434Tim Northover
139172062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Parser.getTok().getLoc();
139272062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat '#'
139372062f5744557e270a38192554c3126ea5f97434Tim Northover
139472062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCExpr *Imm;
139572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ParseImmediate(Imm) != MatchOperand_Success)
139672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
139772062f5744557e270a38192554c3126ea5f97434Tim Northover  else if (Parser.getTok().isNot(AsmToken::Comma)) {
139872062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc E = Parser.getTok().getLoc();
139972062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateImmWithLSL(Imm, 0, true, S, E));
140072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
140172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
140272062f5744557e270a38192554c3126ea5f97434Tim Northover
140372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Eat ','
140472062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
140572062f5744557e270a38192554c3126ea5f97434Tim Northover
140672062f5744557e270a38192554c3126ea5f97434Tim Northover  // The optional operand must be "lsl #N" where N is non-negative.
140772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().is(AsmToken::Identifier)
140872062f5744557e270a38192554c3126ea5f97434Tim Northover      && Parser.getTok().getIdentifier().lower() == "lsl") {
140972062f5744557e270a38192554c3126ea5f97434Tim Northover    Parser.Lex();
141072062f5744557e270a38192554c3126ea5f97434Tim Northover
141172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Parser.getTok().is(AsmToken::Hash)) {
141272062f5744557e270a38192554c3126ea5f97434Tim Northover      Parser.Lex();
141372062f5744557e270a38192554c3126ea5f97434Tim Northover
141472062f5744557e270a38192554c3126ea5f97434Tim Northover      if (Parser.getTok().isNot(AsmToken::Integer)) {
141572062f5744557e270a38192554c3126ea5f97434Tim Northover        Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
141672062f5744557e270a38192554c3126ea5f97434Tim Northover        return MatchOperand_ParseFail;
141772062f5744557e270a38192554c3126ea5f97434Tim Northover      }
141872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
141972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
142072062f5744557e270a38192554c3126ea5f97434Tim Northover
142172062f5744557e270a38192554c3126ea5f97434Tim Northover  int64_t ShiftAmount = Parser.getTok().getIntVal();
142272062f5744557e270a38192554c3126ea5f97434Tim Northover
142372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (ShiftAmount < 0) {
142472062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "positive shift amount required");
142572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
142672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
142772062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat the number
142872062f5744557e270a38192554c3126ea5f97434Tim Northover
142972062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc E = Parser.getTok().getLoc();
143072062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateImmWithLSL(Imm, ShiftAmount,
143172062f5744557e270a38192554c3126ea5f97434Tim Northover                                                      false, S, E));
143272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
143372062f5744557e270a38192554c3126ea5f97434Tim Northover}
143472062f5744557e270a38192554c3126ea5f97434Tim Northover
143572062f5744557e270a38192554c3126ea5f97434Tim Northover
143672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
143772062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseCondCodeOperand(
143872062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
143972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Identifier))
144072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_NoMatch;
144172062f5744557e270a38192554c3126ea5f97434Tim Northover
144272062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef Tok = Parser.getTok().getIdentifier();
144372062f5744557e270a38192554c3126ea5f97434Tim Northover  A64CC::CondCodes CondCode = A64StringToCondCode(Tok);
144472062f5744557e270a38192554c3126ea5f97434Tim Northover
144572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (CondCode == A64CC::Invalid)
144672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_NoMatch;
144772062f5744557e270a38192554c3126ea5f97434Tim Northover
144872062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Parser.getTok().getLoc();
144972062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat condition code
145072062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc E = Parser.getTok().getLoc();
145172062f5744557e270a38192554c3126ea5f97434Tim Northover
145272062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateCondCode(CondCode, S, E));
145372062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
145472062f5744557e270a38192554c3126ea5f97434Tim Northover}
145572062f5744557e270a38192554c3126ea5f97434Tim Northover
145672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
145772062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseCRxOperand(
145872062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
145972062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Parser.getTok().getLoc();
146072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Identifier)) {
146172062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(S, "Expected cN operand where 0 <= N <= 15");
146272062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
146372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
146472062f5744557e270a38192554c3126ea5f97434Tim Northover
146542a68443a15d74ada014ad2c8a2349fe134a44f3Tim Northover  std::string LowerTok = Parser.getTok().getIdentifier().lower();
146642a68443a15d74ada014ad2c8a2349fe134a44f3Tim Northover  StringRef Tok(LowerTok);
146772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Tok[0] != 'c') {
146872062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(S, "Expected cN operand where 0 <= N <= 15");
146972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
147072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
147172062f5744557e270a38192554c3126ea5f97434Tim Northover
147272062f5744557e270a38192554c3126ea5f97434Tim Northover  uint32_t CRNum;
147372062f5744557e270a38192554c3126ea5f97434Tim Northover  bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
147472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (BadNum || CRNum > 15) {
147572062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(S, "Expected cN operand where 0 <= N <= 15");
147672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
147772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
147872062f5744557e270a38192554c3126ea5f97434Tim Northover
147972062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCExpr *CRImm = MCConstantExpr::Create(CRNum, getContext());
148072062f5744557e270a38192554c3126ea5f97434Tim Northover
148172062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
148272062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc E = Parser.getTok().getLoc();
148372062f5744557e270a38192554c3126ea5f97434Tim Northover
148472062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateImm(CRImm, S, E));
148572062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
148672062f5744557e270a38192554c3126ea5f97434Tim Northover}
148772062f5744557e270a38192554c3126ea5f97434Tim Northover
148872062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
148972062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseFPImmOperand(
149072062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
149172062f5744557e270a38192554c3126ea5f97434Tim Northover
149272062f5744557e270a38192554c3126ea5f97434Tim Northover  // FIXME?: I want to live in a world where immediates must start with
149372062f5744557e270a38192554c3126ea5f97434Tim Northover  // #. Please don't dash my hopes (well, do if you have a good reason).
149472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Hash)) return MatchOperand_NoMatch;
149572062f5744557e270a38192554c3126ea5f97434Tim Northover
149672062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Parser.getTok().getLoc();
149772062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat '#'
149872062f5744557e270a38192554c3126ea5f97434Tim Northover
149972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool Negative = false;
150072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().is(AsmToken::Minus)) {
150172062f5744557e270a38192554c3126ea5f97434Tim Northover    Negative = true;
150272062f5744557e270a38192554c3126ea5f97434Tim Northover    Parser.Lex(); // Eat '-'
150372062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (Parser.getTok().is(AsmToken::Plus)) {
150472062f5744557e270a38192554c3126ea5f97434Tim Northover    Parser.Lex(); // Eat '+'
150572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
150672062f5744557e270a38192554c3126ea5f97434Tim Northover
150772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Real)) {
150872062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(S, "Expected floating-point immediate");
150972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
151072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
151172062f5744557e270a38192554c3126ea5f97434Tim Northover
151272062f5744557e270a38192554c3126ea5f97434Tim Northover  APFloat RealVal(APFloat::IEEEdouble, Parser.getTok().getString());
151372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Negative) RealVal.changeSign();
151472062f5744557e270a38192554c3126ea5f97434Tim Northover  double DblVal = RealVal.convertToDouble();
151572062f5744557e270a38192554c3126ea5f97434Tim Northover
151672062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat real number
151772062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc E = Parser.getTok().getLoc();
151872062f5744557e270a38192554c3126ea5f97434Tim Northover
151972062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateFPImm(DblVal, S, E));
152072062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
152172062f5744557e270a38192554c3126ea5f97434Tim Northover}
152272062f5744557e270a38192554c3126ea5f97434Tim Northover
152372062f5744557e270a38192554c3126ea5f97434Tim Northover
152472062f5744557e270a38192554c3126ea5f97434Tim Northover// Automatically generated
152572062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic unsigned MatchRegisterName(StringRef Name);
152672062f5744557e270a38192554c3126ea5f97434Tim Northover
152772062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
152872062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::IdentifyRegister(unsigned &RegNum, SMLoc &RegEndLoc,
152972062f5744557e270a38192554c3126ea5f97434Tim Northover                                   StringRef &Layout,
153072062f5744557e270a38192554c3126ea5f97434Tim Northover                                   SMLoc &LayoutLoc) const {
153172062f5744557e270a38192554c3126ea5f97434Tim Northover  const AsmToken &Tok = Parser.getTok();
153272062f5744557e270a38192554c3126ea5f97434Tim Northover
153372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Tok.isNot(AsmToken::Identifier))
153472062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
153572062f5744557e270a38192554c3126ea5f97434Tim Northover
153672062f5744557e270a38192554c3126ea5f97434Tim Northover  std::string LowerReg = Tok.getString().lower();
153772062f5744557e270a38192554c3126ea5f97434Tim Northover  size_t DotPos = LowerReg.find('.');
153872062f5744557e270a38192554c3126ea5f97434Tim Northover
153972062f5744557e270a38192554c3126ea5f97434Tim Northover  RegNum = MatchRegisterName(LowerReg.substr(0, DotPos));
154072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNum == AArch64::NoRegister) {
154172062f5744557e270a38192554c3126ea5f97434Tim Northover    RegNum = StringSwitch<unsigned>(LowerReg.substr(0, DotPos))
154272062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case("ip0", AArch64::X16)
154372062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case("ip1", AArch64::X17)
154472062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case("fp", AArch64::X29)
154572062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case("lr", AArch64::X30)
154672062f5744557e270a38192554c3126ea5f97434Tim Northover      .Default(AArch64::NoRegister);
154772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
154872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RegNum == AArch64::NoRegister)
154972062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
155072062f5744557e270a38192554c3126ea5f97434Tim Northover
155172062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Tok.getLoc();
155272062f5744557e270a38192554c3126ea5f97434Tim Northover  RegEndLoc = SMLoc::getFromPointer(S.getPointer() + DotPos);
155372062f5744557e270a38192554c3126ea5f97434Tim Northover
155472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (DotPos == StringRef::npos) {
155572062f5744557e270a38192554c3126ea5f97434Tim Northover    Layout = StringRef();
155672062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
155772062f5744557e270a38192554c3126ea5f97434Tim Northover    // Everything afterwards needs to be a literal token, expected to be
155872062f5744557e270a38192554c3126ea5f97434Tim Northover    // '.2d','.b' etc for vector registers.
155972062f5744557e270a38192554c3126ea5f97434Tim Northover
156072062f5744557e270a38192554c3126ea5f97434Tim Northover    // This StringSwitch validates the input and (perhaps more importantly)
156172062f5744557e270a38192554c3126ea5f97434Tim Northover    // gives us a permanent string to use in the token (a pointer into LowerReg
156272062f5744557e270a38192554c3126ea5f97434Tim Northover    // would go out of scope when we return).
156372062f5744557e270a38192554c3126ea5f97434Tim Northover    LayoutLoc = SMLoc::getFromPointer(S.getPointer() + DotPos + 1);
1564b9e1a33941d25faf54dc3ddec4be7f8f0750a155Tim Northover    std::string LayoutText = LowerReg.substr(DotPos, StringRef::npos);
1565b9e1a33941d25faf54dc3ddec4be7f8f0750a155Tim Northover    Layout = StringSwitch<const char *>(LayoutText)
156672062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case(".d", ".d").Case(".1d", ".1d").Case(".2d", ".2d")
156772062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case(".s", ".s").Case(".2s", ".2s").Case(".4s", ".4s")
156872062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case(".h", ".h").Case(".4h", ".4h").Case(".8h", ".8h")
156972062f5744557e270a38192554c3126ea5f97434Tim Northover      .Case(".b", ".b").Case(".8b", ".8b").Case(".16b", ".16b")
157072062f5744557e270a38192554c3126ea5f97434Tim Northover      .Default("");
157172062f5744557e270a38192554c3126ea5f97434Tim Northover
157272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Layout.size() == 0) {
157372062f5744557e270a38192554c3126ea5f97434Tim Northover      // Malformed register
157472062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
157572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
157672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
157772062f5744557e270a38192554c3126ea5f97434Tim Northover
157872062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
157972062f5744557e270a38192554c3126ea5f97434Tim Northover}
158072062f5744557e270a38192554c3126ea5f97434Tim Northover
158172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
158272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
158372062f5744557e270a38192554c3126ea5f97434Tim Northover                                uint32_t &NumLanes) {
158472062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned RegNum;
158572062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef Layout;
158672062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc RegEndLoc, LayoutLoc;
158772062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Parser.getTok().getLoc();
158872062f5744557e270a38192554c3126ea5f97434Tim Northover
158972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!IdentifyRegister(RegNum, RegEndLoc, Layout, LayoutLoc))
159072062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_NoMatch;
159172062f5744557e270a38192554c3126ea5f97434Tim Northover
159272062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateReg(RegNum, S, RegEndLoc));
159372062f5744557e270a38192554c3126ea5f97434Tim Northover
159472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Layout.size() != 0) {
159572062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned long long TmpLanes = 0;
159672062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm::getAsUnsignedInteger(Layout.substr(1), 10, TmpLanes);
159772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (TmpLanes != 0) {
159872062f5744557e270a38192554c3126ea5f97434Tim Northover      NumLanes = TmpLanes;
159972062f5744557e270a38192554c3126ea5f97434Tim Northover    } else {
160072062f5744557e270a38192554c3126ea5f97434Tim Northover      // If the number of lanes isn't specified explicitly, a valid instruction
160172062f5744557e270a38192554c3126ea5f97434Tim Northover      // will have an element specifier and be capable of acting on the entire
160272062f5744557e270a38192554c3126ea5f97434Tim Northover      // vector register.
160372062f5744557e270a38192554c3126ea5f97434Tim Northover      switch (Layout.back()) {
160472062f5744557e270a38192554c3126ea5f97434Tim Northover      default: llvm_unreachable("Invalid layout specifier");
160572062f5744557e270a38192554c3126ea5f97434Tim Northover      case 'b': NumLanes = 16; break;
160672062f5744557e270a38192554c3126ea5f97434Tim Northover      case 'h': NumLanes = 8; break;
160772062f5744557e270a38192554c3126ea5f97434Tim Northover      case 's': NumLanes = 4; break;
160872062f5744557e270a38192554c3126ea5f97434Tim Northover      case 'd': NumLanes = 2; break;
160972062f5744557e270a38192554c3126ea5f97434Tim Northover      }
161072062f5744557e270a38192554c3126ea5f97434Tim Northover    }
161172062f5744557e270a38192554c3126ea5f97434Tim Northover
161272062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateToken(Layout, LayoutLoc));
161372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
161472062f5744557e270a38192554c3126ea5f97434Tim Northover
161572062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
161672062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
161772062f5744557e270a38192554c3126ea5f97434Tim Northover}
161872062f5744557e270a38192554c3126ea5f97434Tim Northover
161972062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
162072062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
162172062f5744557e270a38192554c3126ea5f97434Tim Northover                                SMLoc &EndLoc) {
162272062f5744557e270a38192554c3126ea5f97434Tim Northover  // This callback is used for things like DWARF frame directives in
162372062f5744557e270a38192554c3126ea5f97434Tim Northover  // assembly. They don't care about things like NEON layouts or lanes, they
162472062f5744557e270a38192554c3126ea5f97434Tim Northover  // just want to be able to produce the DWARF register number.
162572062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef LayoutSpec;
162672062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc RegEndLoc, LayoutLoc;
162772062f5744557e270a38192554c3126ea5f97434Tim Northover  StartLoc = Parser.getTok().getLoc();
162872062f5744557e270a38192554c3126ea5f97434Tim Northover
162972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!IdentifyRegister(RegNo, RegEndLoc, LayoutSpec, LayoutLoc))
163072062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;
163172062f5744557e270a38192554c3126ea5f97434Tim Northover
163272062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
163372062f5744557e270a38192554c3126ea5f97434Tim Northover  EndLoc = Parser.getTok().getLoc();
163472062f5744557e270a38192554c3126ea5f97434Tim Northover
163572062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
163672062f5744557e270a38192554c3126ea5f97434Tim Northover}
163772062f5744557e270a38192554c3126ea5f97434Tim Northover
163872062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
163972062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseNamedImmOperand(const NamedImmMapper &Mapper,
164072062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
164172062f5744557e270a38192554c3126ea5f97434Tim Northover  // Since these operands occur in very limited circumstances, without
164272062f5744557e270a38192554c3126ea5f97434Tim Northover  // alternatives, we actually signal an error if there is no match. If relaxing
164372062f5744557e270a38192554c3126ea5f97434Tim Northover  // this, beware of unintended consequences: an immediate will be accepted
164472062f5744557e270a38192554c3126ea5f97434Tim Northover  // during matching, no matter how it gets into the AArch64Operand.
164572062f5744557e270a38192554c3126ea5f97434Tim Northover  const AsmToken &Tok = Parser.getTok();
164672062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Tok.getLoc();
164772062f5744557e270a38192554c3126ea5f97434Tim Northover
164872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Tok.is(AsmToken::Identifier)) {
164972062f5744557e270a38192554c3126ea5f97434Tim Northover    bool ValidName;
165072062f5744557e270a38192554c3126ea5f97434Tim Northover    uint32_t Code = Mapper.fromString(Tok.getString().lower(), ValidName);
165172062f5744557e270a38192554c3126ea5f97434Tim Northover
165272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!ValidName) {
165372062f5744557e270a38192554c3126ea5f97434Tim Northover      Error(S, "operand specifier not recognised");
165472062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_ParseFail;
165572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
165672062f5744557e270a38192554c3126ea5f97434Tim Northover
165772062f5744557e270a38192554c3126ea5f97434Tim Northover    Parser.Lex(); // We're done with the identifier. Eat it
165872062f5744557e270a38192554c3126ea5f97434Tim Northover
165972062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc E = Parser.getTok().getLoc();
166072062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCExpr *Imm = MCConstantExpr::Create(Code, getContext());
166172062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateImm(Imm, S, E));
166272062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
166372062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (Tok.is(AsmToken::Hash)) {
166472062f5744557e270a38192554c3126ea5f97434Tim Northover    Parser.Lex();
166572062f5744557e270a38192554c3126ea5f97434Tim Northover
166672062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCExpr *ImmVal;
166772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ParseImmediate(ImmVal) != MatchOperand_Success)
166872062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_ParseFail;
166972062f5744557e270a38192554c3126ea5f97434Tim Northover
167072062f5744557e270a38192554c3126ea5f97434Tim Northover    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
167172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CE || CE->getValue() < 0 || !Mapper.validImm(CE->getValue())) {
167272062f5744557e270a38192554c3126ea5f97434Tim Northover      Error(S, "Invalid immediate for instruction");
167372062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_ParseFail;
167472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
167572062f5744557e270a38192554c3126ea5f97434Tim Northover
167672062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc E = Parser.getTok().getLoc();
167772062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E));
167872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
167972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
168072062f5744557e270a38192554c3126ea5f97434Tim Northover
168172062f5744557e270a38192554c3126ea5f97434Tim Northover  Error(S, "unexpected operand for instruction");
168272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_ParseFail;
168372062f5744557e270a38192554c3126ea5f97434Tim Northover}
168472062f5744557e270a38192554c3126ea5f97434Tim Northover
168572062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
168672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseSysRegOperand(
168772062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
168872062f5744557e270a38192554c3126ea5f97434Tim Northover  const AsmToken &Tok = Parser.getTok();
168972062f5744557e270a38192554c3126ea5f97434Tim Northover
169072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Any MSR/MRS operand will be an identifier, and we want to store it as some
169172062f5744557e270a38192554c3126ea5f97434Tim Northover  // kind of string: SPSel is valid for two different forms of MSR with two
169272062f5744557e270a38192554c3126ea5f97434Tim Northover  // different encodings. There's no collision at the moment, but the potential
169372062f5744557e270a38192554c3126ea5f97434Tim Northover  // is there.
169472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!Tok.is(AsmToken::Identifier)) {
169572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_NoMatch;
169672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
169772062f5744557e270a38192554c3126ea5f97434Tim Northover
169872062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Tok.getLoc();
169972062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateSysReg(Tok.getString(), S));
170072062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat identifier
170172062f5744557e270a38192554c3126ea5f97434Tim Northover
170272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
170372062f5744557e270a38192554c3126ea5f97434Tim Northover}
170472062f5744557e270a38192554c3126ea5f97434Tim Northover
170572062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
170672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseLSXAddressOperand(
170772062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
170872062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S = Parser.getTok().getLoc();
170972062f5744557e270a38192554c3126ea5f97434Tim Northover
171072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned RegNum;
171172062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc RegEndLoc, LayoutLoc;
171272062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef Layout;
171372062f5744557e270a38192554c3126ea5f97434Tim Northover  if(!IdentifyRegister(RegNum, RegEndLoc, Layout, LayoutLoc)
171472062f5744557e270a38192554c3126ea5f97434Tim Northover     || !AArch64MCRegisterClasses[AArch64::GPR64xspRegClassID].contains(RegNum)
171572062f5744557e270a38192554c3126ea5f97434Tim Northover     || Layout.size() != 0) {
171672062f5744557e270a38192554c3126ea5f97434Tim Northover    // Check Layout.size because we don't want to let "x3.4s" or similar
171772062f5744557e270a38192554c3126ea5f97434Tim Northover    // through.
171872062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_NoMatch;
171972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
172072062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat register
172172062f5744557e270a38192554c3126ea5f97434Tim Northover
172272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().is(AsmToken::RBrac)) {
172372062f5744557e270a38192554c3126ea5f97434Tim Northover    // We're done
172472062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc E = Parser.getTok().getLoc();
172572062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateWrappedReg(RegNum, S, E));
172672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_Success;
172772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
172872062f5744557e270a38192554c3126ea5f97434Tim Northover
172972062f5744557e270a38192554c3126ea5f97434Tim Northover  // Otherwise, only ", #0" is valid
173072062f5744557e270a38192554c3126ea5f97434Tim Northover
173172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Comma)) {
173272062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "expected ',' or ']' after register");
173372062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
173472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
173572062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat ','
173672062f5744557e270a38192554c3126ea5f97434Tim Northover
173772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Hash)) {
173872062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "expected '#0'");
173972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
174072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
174172062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat '#'
174272062f5744557e270a38192554c3126ea5f97434Tim Northover
174372062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Parser.getTok().isNot(AsmToken::Integer)
174472062f5744557e270a38192554c3126ea5f97434Tim Northover      || Parser.getTok().getIntVal() != 0 ) {
174572062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(), "expected '#0'");
174672062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
174772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
174872062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex(); // Eat '0'
174972062f5744557e270a38192554c3126ea5f97434Tim Northover
175072062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc E = Parser.getTok().getLoc();
175172062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateWrappedReg(RegNum, S, E));
175272062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
175372062f5744557e270a38192554c3126ea5f97434Tim Northover}
175472062f5744557e270a38192554c3126ea5f97434Tim Northover
175572062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::OperandMatchResultTy
175672062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64AsmParser::ParseShiftExtend(
175772062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
175872062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef IDVal = Parser.getTok().getIdentifier();
175972062f5744557e270a38192554c3126ea5f97434Tim Northover  std::string LowerID = IDVal.lower();
176072062f5744557e270a38192554c3126ea5f97434Tim Northover
176172062f5744557e270a38192554c3126ea5f97434Tim Northover  A64SE::ShiftExtSpecifiers Spec =
176287773c318fcee853fb34a80a10c4347d523bdafbTim Northover      StringSwitch<A64SE::ShiftExtSpecifiers>(LowerID)
176387773c318fcee853fb34a80a10c4347d523bdafbTim Northover        .Case("lsl", A64SE::LSL)
176487773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("msl", A64SE::MSL)
176587773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("lsr", A64SE::LSR)
176687773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("asr", A64SE::ASR)
176787773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("ror", A64SE::ROR)
176887773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("uxtb", A64SE::UXTB)
176987773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("uxth", A64SE::UXTH)
177087773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("uxtw", A64SE::UXTW)
177187773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("uxtx", A64SE::UXTX)
177287773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("sxtb", A64SE::SXTB)
177387773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("sxth", A64SE::SXTH)
177487773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("sxtw", A64SE::SXTW)
177587773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Case("sxtx", A64SE::SXTX)
177687773c318fcee853fb34a80a10c4347d523bdafbTim Northover	.Default(A64SE::Invalid);
177772062f5744557e270a38192554c3126ea5f97434Tim Northover
177872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Spec == A64SE::Invalid)
177972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_NoMatch;
178072062f5744557e270a38192554c3126ea5f97434Tim Northover
178172062f5744557e270a38192554c3126ea5f97434Tim Northover  // Eat the shift
178272062f5744557e270a38192554c3126ea5f97434Tim Northover  SMLoc S, E;
178372062f5744557e270a38192554c3126ea5f97434Tim Northover  S = Parser.getTok().getLoc();
178472062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
178572062f5744557e270a38192554c3126ea5f97434Tim Northover
178687773c318fcee853fb34a80a10c4347d523bdafbTim Northover  if (Spec != A64SE::LSL && Spec != A64SE::LSR && Spec != A64SE::ASR &&
178787773c318fcee853fb34a80a10c4347d523bdafbTim Northover      Spec != A64SE::ROR && Spec != A64SE::MSL) {
178872062f5744557e270a38192554c3126ea5f97434Tim Northover    // The shift amount can be omitted for the extending versions, but not real
178972062f5744557e270a38192554c3126ea5f97434Tim Northover    // shifts:
179072062f5744557e270a38192554c3126ea5f97434Tim Northover    //     add x0, x0, x0, uxtb
179172062f5744557e270a38192554c3126ea5f97434Tim Northover    // is valid, and equivalent to
179272062f5744557e270a38192554c3126ea5f97434Tim Northover    //     add x0, x0, x0, uxtb #0
179372062f5744557e270a38192554c3126ea5f97434Tim Northover
179472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Parser.getTok().is(AsmToken::Comma) ||
179572062f5744557e270a38192554c3126ea5f97434Tim Northover        Parser.getTok().is(AsmToken::EndOfStatement) ||
179672062f5744557e270a38192554c3126ea5f97434Tim Northover        Parser.getTok().is(AsmToken::RBrac)) {
1797dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover      Operands.push_back(AArch64Operand::CreateShiftExtend(Spec, 0, true,
1798dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                                           S, E));
179972062f5744557e270a38192554c3126ea5f97434Tim Northover      return MatchOperand_Success;
180072062f5744557e270a38192554c3126ea5f97434Tim Northover    }
180172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
180272062f5744557e270a38192554c3126ea5f97434Tim Northover
180372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Eat # at beginning of immediate
180472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!Parser.getTok().is(AsmToken::Hash)) {
180572062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(),
180672062f5744557e270a38192554c3126ea5f97434Tim Northover          "expected #imm after shift specifier");
180772062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
180872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
180972062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
181072062f5744557e270a38192554c3126ea5f97434Tim Northover
181172062f5744557e270a38192554c3126ea5f97434Tim Northover  // Make sure we do actually have a number
181272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!Parser.getTok().is(AsmToken::Integer)) {
181372062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(Parser.getTok().getLoc(),
181472062f5744557e270a38192554c3126ea5f97434Tim Northover          "expected integer shift amount");
181572062f5744557e270a38192554c3126ea5f97434Tim Northover    return MatchOperand_ParseFail;
181672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
181772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned Amount = Parser.getTok().getIntVal();
181872062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
181972062f5744557e270a38192554c3126ea5f97434Tim Northover  E = Parser.getTok().getLoc();
182072062f5744557e270a38192554c3126ea5f97434Tim Northover
1821dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  Operands.push_back(AArch64Operand::CreateShiftExtend(Spec, Amount, false,
1822dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                                       S, E));
182372062f5744557e270a38192554c3126ea5f97434Tim Northover
182472062f5744557e270a38192554c3126ea5f97434Tim Northover  return MatchOperand_Success;
182572062f5744557e270a38192554c3126ea5f97434Tim Northover}
182672062f5744557e270a38192554c3126ea5f97434Tim Northover
182772062f5744557e270a38192554c3126ea5f97434Tim Northover// FIXME: We would really like to be able to tablegen'erate this.
182872062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::
182972062f5744557e270a38192554c3126ea5f97434Tim NorthovervalidateInstruction(MCInst &Inst,
183072062f5744557e270a38192554c3126ea5f97434Tim Northover                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
183172062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Inst.getOpcode()) {
183272062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::BFIwwii:
183372062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::BFIxxii:
183472062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::SBFIZwwii:
183572062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::SBFIZxxii:
183672062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::UBFIZwwii:
183772062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::UBFIZxxii:  {
183872062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned ImmOps = Inst.getNumOperands() - 2;
183972062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmR = Inst.getOperand(ImmOps).getImm();
184072062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmS = Inst.getOperand(ImmOps+1).getImm();
184172062f5744557e270a38192554c3126ea5f97434Tim Northover
184277b1c9cf57849b3f9a4e8bae47cd5954d20a7e11Tim Northover    if (ImmR != 0 && ImmS >= ImmR) {
184372062f5744557e270a38192554c3126ea5f97434Tim Northover      return Error(Operands[4]->getStartLoc(),
184472062f5744557e270a38192554c3126ea5f97434Tim Northover                   "requested insert overflows register");
184572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
184672062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
184772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
184872062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::BFXILwwii:
184972062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::BFXILxxii:
185072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::SBFXwwii:
185172062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::SBFXxxii:
185272062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::UBFXwwii:
185372062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::UBFXxxii: {
185472062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned ImmOps = Inst.getNumOperands() - 2;
185572062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmR = Inst.getOperand(ImmOps).getImm();
185672062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmS = Inst.getOperand(ImmOps+1).getImm();
185772062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t RegWidth = 0;
185872062f5744557e270a38192554c3126ea5f97434Tim Northover    switch (Inst.getOpcode()) {
185972062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64::SBFXxxii: case AArch64::UBFXxxii: case AArch64::BFXILxxii:
186072062f5744557e270a38192554c3126ea5f97434Tim Northover      RegWidth = 64;
186172062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
186272062f5744557e270a38192554c3126ea5f97434Tim Northover    case AArch64::SBFXwwii: case AArch64::UBFXwwii: case AArch64::BFXILwwii:
186372062f5744557e270a38192554c3126ea5f97434Tim Northover      RegWidth = 32;
186472062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
186572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
186672062f5744557e270a38192554c3126ea5f97434Tim Northover
186772062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ImmS >= RegWidth || ImmS < ImmR) {
186872062f5744557e270a38192554c3126ea5f97434Tim Northover      return Error(Operands[4]->getStartLoc(),
186972062f5744557e270a38192554c3126ea5f97434Tim Northover                   "requested extract overflows register");
187072062f5744557e270a38192554c3126ea5f97434Tim Northover    }
187172062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
187272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
187372062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::ICix: {
187472062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmVal = Inst.getOperand(0).getImm();
187572062f5744557e270a38192554c3126ea5f97434Tim Northover    A64IC::ICValues ICOp = static_cast<A64IC::ICValues>(ImmVal);
187672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!A64IC::NeedsRegister(ICOp)) {
187772062f5744557e270a38192554c3126ea5f97434Tim Northover      return Error(Operands[1]->getStartLoc(),
187872062f5744557e270a38192554c3126ea5f97434Tim Northover                   "specified IC op does not use a register");
187972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
188072062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
188172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
188272062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::ICi: {
188372062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmVal = Inst.getOperand(0).getImm();
188472062f5744557e270a38192554c3126ea5f97434Tim Northover    A64IC::ICValues ICOp = static_cast<A64IC::ICValues>(ImmVal);
188572062f5744557e270a38192554c3126ea5f97434Tim Northover    if (A64IC::NeedsRegister(ICOp)) {
188672062f5744557e270a38192554c3126ea5f97434Tim Northover      return Error(Operands[1]->getStartLoc(),
188772062f5744557e270a38192554c3126ea5f97434Tim Northover                   "specified IC op requires a register");
188872062f5744557e270a38192554c3126ea5f97434Tim Northover    }
188972062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
189072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
189172062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TLBIix: {
189272062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmVal = Inst.getOperand(0).getImm();
189372062f5744557e270a38192554c3126ea5f97434Tim Northover    A64TLBI::TLBIValues TLBIOp = static_cast<A64TLBI::TLBIValues>(ImmVal);
189472062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!A64TLBI::NeedsRegister(TLBIOp)) {
189572062f5744557e270a38192554c3126ea5f97434Tim Northover      return Error(Operands[1]->getStartLoc(),
189672062f5744557e270a38192554c3126ea5f97434Tim Northover                   "specified TLBI op does not use a register");
189772062f5744557e270a38192554c3126ea5f97434Tim Northover    }
189872062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
189972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
190072062f5744557e270a38192554c3126ea5f97434Tim Northover  case AArch64::TLBIi: {
190172062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t ImmVal = Inst.getOperand(0).getImm();
190272062f5744557e270a38192554c3126ea5f97434Tim Northover    A64TLBI::TLBIValues TLBIOp = static_cast<A64TLBI::TLBIValues>(ImmVal);
190372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (A64TLBI::NeedsRegister(TLBIOp)) {
190472062f5744557e270a38192554c3126ea5f97434Tim Northover      return Error(Operands[1]->getStartLoc(),
190572062f5744557e270a38192554c3126ea5f97434Tim Northover                   "specified TLBI op requires a register");
190672062f5744557e270a38192554c3126ea5f97434Tim Northover    }
190772062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
190872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
190972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
191072062f5744557e270a38192554c3126ea5f97434Tim Northover
191172062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
191272062f5744557e270a38192554c3126ea5f97434Tim Northover}
191372062f5744557e270a38192554c3126ea5f97434Tim Northover
191472062f5744557e270a38192554c3126ea5f97434Tim Northover
191572062f5744557e270a38192554c3126ea5f97434Tim Northover// Parses the instruction *together with* all operands, appending each parsed
191672062f5744557e270a38192554c3126ea5f97434Tim Northover// operand to the "Operands" list
191772062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
191872062f5744557e270a38192554c3126ea5f97434Tim Northover                                        StringRef Name, SMLoc NameLoc,
191972062f5744557e270a38192554c3126ea5f97434Tim Northover                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
192072062f5744557e270a38192554c3126ea5f97434Tim Northover  size_t CondCodePos = Name.find('.');
192172062f5744557e270a38192554c3126ea5f97434Tim Northover
192272062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef Mnemonic = Name.substr(0, CondCodePos);
192372062f5744557e270a38192554c3126ea5f97434Tim Northover  Operands.push_back(AArch64Operand::CreateToken(Mnemonic, NameLoc));
192472062f5744557e270a38192554c3126ea5f97434Tim Northover
192572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (CondCodePos != StringRef::npos) {
192672062f5744557e270a38192554c3126ea5f97434Tim Northover    // We have a condition code
192772062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc S = SMLoc::getFromPointer(NameLoc.getPointer() + CondCodePos + 1);
192872062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef CondStr = Name.substr(CondCodePos + 1, StringRef::npos);
192972062f5744557e270a38192554c3126ea5f97434Tim Northover    A64CC::CondCodes Code;
193072062f5744557e270a38192554c3126ea5f97434Tim Northover
193172062f5744557e270a38192554c3126ea5f97434Tim Northover    Code = A64StringToCondCode(CondStr);
193272062f5744557e270a38192554c3126ea5f97434Tim Northover
193372062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Code == A64CC::Invalid) {
193472062f5744557e270a38192554c3126ea5f97434Tim Northover      Error(S, "invalid condition code");
1935cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
193672062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
193772062f5744557e270a38192554c3126ea5f97434Tim Northover    }
193872062f5744557e270a38192554c3126ea5f97434Tim Northover
193972062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc DotL = SMLoc::getFromPointer(NameLoc.getPointer() + CondCodePos);
194072062f5744557e270a38192554c3126ea5f97434Tim Northover
194172062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateToken(".",  DotL));
194272062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc E = SMLoc::getFromPointer(NameLoc.getPointer() + CondCodePos + 3);
194372062f5744557e270a38192554c3126ea5f97434Tim Northover    Operands.push_back(AArch64Operand::CreateCondCode(Code, S, E));
194472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
194572062f5744557e270a38192554c3126ea5f97434Tim Northover
194672062f5744557e270a38192554c3126ea5f97434Tim Northover  // Now we parse the operands of this instruction
194772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::EndOfStatement)) {
194872062f5744557e270a38192554c3126ea5f97434Tim Northover    // Read the first operand.
194972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ParseOperand(Operands, Mnemonic)) {
1950cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
195172062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
195272062f5744557e270a38192554c3126ea5f97434Tim Northover    }
195372062f5744557e270a38192554c3126ea5f97434Tim Northover
195472062f5744557e270a38192554c3126ea5f97434Tim Northover    while (getLexer().is(AsmToken::Comma)) {
195572062f5744557e270a38192554c3126ea5f97434Tim Northover      Parser.Lex();  // Eat the comma.
195672062f5744557e270a38192554c3126ea5f97434Tim Northover
195772062f5744557e270a38192554c3126ea5f97434Tim Northover      // Parse and remember the operand.
195872062f5744557e270a38192554c3126ea5f97434Tim Northover      if (ParseOperand(Operands, Mnemonic)) {
1959cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
196072062f5744557e270a38192554c3126ea5f97434Tim Northover        return true;
196172062f5744557e270a38192554c3126ea5f97434Tim Northover      }
196272062f5744557e270a38192554c3126ea5f97434Tim Northover
196372062f5744557e270a38192554c3126ea5f97434Tim Northover
196472062f5744557e270a38192554c3126ea5f97434Tim Northover      // After successfully parsing some operands there are two special cases to
196572062f5744557e270a38192554c3126ea5f97434Tim Northover      // consider (i.e. notional operands not separated by commas). Both are due
196672062f5744557e270a38192554c3126ea5f97434Tim Northover      // to memory specifiers:
196772062f5744557e270a38192554c3126ea5f97434Tim Northover      //  + An RBrac will end an address for load/store/prefetch
196872062f5744557e270a38192554c3126ea5f97434Tim Northover      //  + An '!' will indicate a pre-indexed operation.
196972062f5744557e270a38192554c3126ea5f97434Tim Northover      //
197072062f5744557e270a38192554c3126ea5f97434Tim Northover      // It's someone else's responsibility to make sure these tokens are sane
197172062f5744557e270a38192554c3126ea5f97434Tim Northover      // in the given context!
197272062f5744557e270a38192554c3126ea5f97434Tim Northover      if (Parser.getTok().is(AsmToken::RBrac)) {
197372062f5744557e270a38192554c3126ea5f97434Tim Northover        SMLoc Loc = Parser.getTok().getLoc();
197472062f5744557e270a38192554c3126ea5f97434Tim Northover        Operands.push_back(AArch64Operand::CreateToken("]", Loc));
197572062f5744557e270a38192554c3126ea5f97434Tim Northover        Parser.Lex();
197672062f5744557e270a38192554c3126ea5f97434Tim Northover      }
197772062f5744557e270a38192554c3126ea5f97434Tim Northover
197872062f5744557e270a38192554c3126ea5f97434Tim Northover      if (Parser.getTok().is(AsmToken::Exclaim)) {
197972062f5744557e270a38192554c3126ea5f97434Tim Northover        SMLoc Loc = Parser.getTok().getLoc();
198072062f5744557e270a38192554c3126ea5f97434Tim Northover        Operands.push_back(AArch64Operand::CreateToken("!", Loc));
198172062f5744557e270a38192554c3126ea5f97434Tim Northover        Parser.Lex();
198272062f5744557e270a38192554c3126ea5f97434Tim Northover      }
198372062f5744557e270a38192554c3126ea5f97434Tim Northover    }
198472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
198572062f5744557e270a38192554c3126ea5f97434Tim Northover
198672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::EndOfStatement)) {
198772062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc Loc = getLexer().getLoc();
1988cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1989b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(Loc, "expected comma before next operand");
199072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
199172062f5744557e270a38192554c3126ea5f97434Tim Northover
199272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Eat the EndOfStatement
199372062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
199472062f5744557e270a38192554c3126ea5f97434Tim Northover
199572062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
199672062f5744557e270a38192554c3126ea5f97434Tim Northover}
199772062f5744557e270a38192554c3126ea5f97434Tim Northover
199872062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
199972062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef IDVal = DirectiveID.getIdentifier();
200072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (IDVal == ".hword")
200172062f5744557e270a38192554c3126ea5f97434Tim Northover    return ParseDirectiveWord(2, DirectiveID.getLoc());
200272062f5744557e270a38192554c3126ea5f97434Tim Northover  else if (IDVal == ".word")
200372062f5744557e270a38192554c3126ea5f97434Tim Northover    return ParseDirectiveWord(4, DirectiveID.getLoc());
200472062f5744557e270a38192554c3126ea5f97434Tim Northover  else if (IDVal == ".xword")
200572062f5744557e270a38192554c3126ea5f97434Tim Northover    return ParseDirectiveWord(8, DirectiveID.getLoc());
200672062f5744557e270a38192554c3126ea5f97434Tim Northover  else if (IDVal == ".tlsdesccall")
200772062f5744557e270a38192554c3126ea5f97434Tim Northover    return ParseDirectiveTLSDescCall(DirectiveID.getLoc());
200872062f5744557e270a38192554c3126ea5f97434Tim Northover
200972062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
201072062f5744557e270a38192554c3126ea5f97434Tim Northover}
201172062f5744557e270a38192554c3126ea5f97434Tim Northover
201272062f5744557e270a38192554c3126ea5f97434Tim Northover/// parseDirectiveWord
201372062f5744557e270a38192554c3126ea5f97434Tim Northover///  ::= .word [ expression (, expression)* ]
201472062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
201572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (getLexer().isNot(AsmToken::EndOfStatement)) {
201672062f5744557e270a38192554c3126ea5f97434Tim Northover    for (;;) {
201772062f5744557e270a38192554c3126ea5f97434Tim Northover      const MCExpr *Value;
2018cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
201972062f5744557e270a38192554c3126ea5f97434Tim Northover        return true;
202072062f5744557e270a38192554c3126ea5f97434Tim Northover
2021a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola      getParser().getStreamer().EmitValue(Value, Size);
202272062f5744557e270a38192554c3126ea5f97434Tim Northover
202372062f5744557e270a38192554c3126ea5f97434Tim Northover      if (getLexer().is(AsmToken::EndOfStatement))
202472062f5744557e270a38192554c3126ea5f97434Tim Northover        break;
202572062f5744557e270a38192554c3126ea5f97434Tim Northover
202672062f5744557e270a38192554c3126ea5f97434Tim Northover      // FIXME: Improve diagnostic.
202772062f5744557e270a38192554c3126ea5f97434Tim Northover      if (getLexer().isNot(AsmToken::Comma))
202872062f5744557e270a38192554c3126ea5f97434Tim Northover        return Error(L, "unexpected token in directive");
202972062f5744557e270a38192554c3126ea5f97434Tim Northover      Parser.Lex();
203072062f5744557e270a38192554c3126ea5f97434Tim Northover    }
203172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
203272062f5744557e270a38192554c3126ea5f97434Tim Northover
203372062f5744557e270a38192554c3126ea5f97434Tim Northover  Parser.Lex();
203472062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
203572062f5744557e270a38192554c3126ea5f97434Tim Northover}
203672062f5744557e270a38192554c3126ea5f97434Tim Northover
203772062f5744557e270a38192554c3126ea5f97434Tim Northover// parseDirectiveTLSDescCall:
203872062f5744557e270a38192554c3126ea5f97434Tim Northover//   ::= .tlsdesccall symbol
203972062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::ParseDirectiveTLSDescCall(SMLoc L) {
204072062f5744557e270a38192554c3126ea5f97434Tim Northover  StringRef Name;
2041cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach  if (getParser().parseIdentifier(Name))
204272062f5744557e270a38192554c3126ea5f97434Tim Northover    return Error(L, "expected symbol after directive");
204372062f5744557e270a38192554c3126ea5f97434Tim Northover
204472062f5744557e270a38192554c3126ea5f97434Tim Northover  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
204572062f5744557e270a38192554c3126ea5f97434Tim Northover  const MCSymbolRefExpr *Expr = MCSymbolRefExpr::Create(Sym, getContext());
204672062f5744557e270a38192554c3126ea5f97434Tim Northover
204772062f5744557e270a38192554c3126ea5f97434Tim Northover  MCInst Inst;
204872062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.setOpcode(AArch64::TLSDESCCALL);
204972062f5744557e270a38192554c3126ea5f97434Tim Northover  Inst.addOperand(MCOperand::CreateExpr(Expr));
205072062f5744557e270a38192554c3126ea5f97434Tim Northover
205172062f5744557e270a38192554c3126ea5f97434Tim Northover  getParser().getStreamer().EmitInstruction(Inst);
205272062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
205372062f5744557e270a38192554c3126ea5f97434Tim Northover}
205472062f5744557e270a38192554c3126ea5f97434Tim Northover
205572062f5744557e270a38192554c3126ea5f97434Tim Northover
205672062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
205772062f5744557e270a38192554c3126ea5f97434Tim Northover                                 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
205872062f5744557e270a38192554c3126ea5f97434Tim Northover                                 MCStreamer &Out, unsigned &ErrorInfo,
205972062f5744557e270a38192554c3126ea5f97434Tim Northover                                 bool MatchingInlineAsm) {
206072062f5744557e270a38192554c3126ea5f97434Tim Northover  MCInst Inst;
206172062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned MatchResult;
2062dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
206372062f5744557e270a38192554c3126ea5f97434Tim Northover                                     MatchingInlineAsm);
2064b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover
2065b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
2066b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(IDLoc, "too few operands for instruction");
2067b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover
206872062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (MatchResult) {
206972062f5744557e270a38192554c3126ea5f97434Tim Northover  default: break;
207072062f5744557e270a38192554c3126ea5f97434Tim Northover  case Match_Success:
207172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (validateInstruction(Inst, Operands))
207272062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
207372062f5744557e270a38192554c3126ea5f97434Tim Northover
207472062f5744557e270a38192554c3126ea5f97434Tim Northover    Out.EmitInstruction(Inst);
207572062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
207672062f5744557e270a38192554c3126ea5f97434Tim Northover  case Match_MissingFeature:
207772062f5744557e270a38192554c3126ea5f97434Tim Northover    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
207872062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;
207972062f5744557e270a38192554c3126ea5f97434Tim Northover  case Match_InvalidOperand: {
208072062f5744557e270a38192554c3126ea5f97434Tim Northover    SMLoc ErrorLoc = IDLoc;
208172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (ErrorInfo != ~0U) {
208272062f5744557e270a38192554c3126ea5f97434Tim Northover      ErrorLoc = ((AArch64Operand*)Operands[ErrorInfo])->getStartLoc();
208372062f5744557e270a38192554c3126ea5f97434Tim Northover      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
208472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
208572062f5744557e270a38192554c3126ea5f97434Tim Northover
208672062f5744557e270a38192554c3126ea5f97434Tim Northover    return Error(ErrorLoc, "invalid operand for instruction");
208772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
208872062f5744557e270a38192554c3126ea5f97434Tim Northover  case Match_MnemonicFail:
208972062f5744557e270a38192554c3126ea5f97434Tim Northover    return Error(IDLoc, "invalid instruction");
2090b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover
2091b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_AddSubRegExtendSmall:
2092b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2093b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover      "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
2094b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_AddSubRegExtendLarge:
2095b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2096b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover      "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
2097b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_AddSubRegShift32:
2098b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2099b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover       "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
2100b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_AddSubRegShift64:
2101b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2102b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover       "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
2103b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_AddSubSecondSource:
2104b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover      return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2105b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover          "expected compatible register, symbol or integer in range [0, 4095]");
2106b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_CVTFixedPos32:
2107b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2108b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [1, 32]");
2109b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_CVTFixedPos64:
2110b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2111b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [1, 64]");
2112b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_CondCode:
2113b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2114b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected AArch64 condition code");
2115b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_FPImm:
2116b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    // Any situation which allows a nontrivial floating-point constant also
2117b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    // allows a register.
2118b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2119b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected compatible register or floating-point constant");
2120b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_FPZero:
2121b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
212287773c318fcee853fb34a80a10c4347d523bdafbTim Northover                 "expected floating-point constant #0.0 or invalid register type");
2123b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_Label:
2124b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2125b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected label or encodable integer pc offset");
2126b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_Lane1:
2127b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2128b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected lane specifier '[1]'");
2129b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend32_1:
2130b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2131b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'uxtw' or 'sxtw' with optional shift of #0");
2132b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend32_2:
2133b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2134b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
2135b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend32_4:
2136b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2137b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
2138b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend32_8:
2139b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2140b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
2141b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend32_16:
2142b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2143b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'lsl' or 'sxtw' with optional shift of #0 or #4");
2144b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend64_1:
2145b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2146b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'lsl' or 'sxtx' with optional shift of #0");
2147b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend64_2:
2148b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2149b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
2150b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend64_4:
2151b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2152b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
2153b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend64_8:
2154b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2155b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
2156b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreExtend64_16:
2157b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2158b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
2159b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreSImm7_4:
2160b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2161b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer multiple of 4 in range [-256, 252]");
2162b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreSImm7_8:
2163b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2164b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer multiple of 8 in range [-512, 508]");
2165b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreSImm7_16:
2166b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2167b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer multiple of 16 in range [-1024, 1016]");
2168b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreSImm9:
2169b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2170b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [-256, 255]");
2171b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreUImm12_1:
2172b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2173b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected symbolic reference or integer in range [0, 4095]");
2174b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreUImm12_2:
2175b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2176b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected symbolic reference or integer in range [0, 8190]");
2177b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreUImm12_4:
2178b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2179b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected symbolic reference or integer in range [0, 16380]");
2180b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreUImm12_8:
2181b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2182b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected symbolic reference or integer in range [0, 32760]");
2183b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LoadStoreUImm12_16:
2184b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2185b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected symbolic reference or integer in range [0, 65520]");
2186b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_LogicalSecondSource:
2187b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2188b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected compatible register or logical immediate");
2189b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_MOVWUImm16:
2190b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2191b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected relocated symbol or integer in range [0, 65535]");
2192b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_MRS:
2193b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2194b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected readable system register");
2195b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_MSR:
2196b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2197b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected writable system register or pstate");
2198b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_NamedImm_at:
2199b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2200b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                "expected symbolic 'at' operand: s1e[0-3][rw] or s12e[01][rw]");
2201b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_NamedImm_dbarrier:
2202b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2203b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover             "expected integer in range [0, 15] or symbolic barrier operand");
2204b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_NamedImm_dc:
2205b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2206b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected symbolic 'dc' operand");
2207b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_NamedImm_ic:
2208b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2209b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected 'ic' operand: 'ialluis', 'iallu' or 'ivau'");
2210b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_NamedImm_isb:
2211b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2212b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [0, 15] or 'sy'");
2213b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_NamedImm_prefetch:
2214b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2215b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected prefetch hint: p(ld|st|i)l[123](strm|keep)");
2216b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_NamedImm_tlbi:
2217b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2218b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected translation buffer invalidation operand");
2219b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_UImm16:
2220b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2221b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [0, 65535]");
2222b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_UImm3:
2223b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2224b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [0, 7]");
2225b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_UImm4:
2226b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2227b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [0, 15]");
2228b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_UImm5:
2229b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2230b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [0, 31]");
2231b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_UImm6:
2232b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2233b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [0, 63]");
2234b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_UImm7:
2235b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2236b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [0, 127]");
2237b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_Width32:
2238b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2239b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [<lsb>, 31]");
2240b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover  case Match_Width64:
2241b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover    return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2242b5161863866b64498a7faa20e612c55de4bca6f8Tim Northover                 "expected integer in range [<lsb>, 63]");
224372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
224472062f5744557e270a38192554c3126ea5f97434Tim Northover
224572062f5744557e270a38192554c3126ea5f97434Tim Northover  llvm_unreachable("Implement any new match types added!");
224672062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
224772062f5744557e270a38192554c3126ea5f97434Tim Northover}
224872062f5744557e270a38192554c3126ea5f97434Tim Northover
224972062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64Operand::print(raw_ostream &OS) const {
225072062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Kind) {
225172062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_CondCode:
225272062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << "<CondCode: " << CondCode.Code << ">";
225372062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
225472062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_FPImmediate:
225572062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << "<fpimm: " << FPImm.Val << ">";
225672062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
225772062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_ImmWithLSL:
225872062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << "<immwithlsl: imm=" << ImmWithLSL.Val
225972062f5744557e270a38192554c3126ea5f97434Tim Northover       << ", shift=" << ImmWithLSL.ShiftAmount << ">";
226072062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
226172062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_Immediate:
226272062f5744557e270a38192554c3126ea5f97434Tim Northover    getImm()->print(OS);
226372062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
226472062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_Register:
226572062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << "<register " << getReg() << '>';
226672062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
226772062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_Token:
226872062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << '\'' << getToken() << '\'';
226972062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
227072062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_ShiftExtend:
227172062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << "<shift: type=" << ShiftExtend.ShiftType
227272062f5744557e270a38192554c3126ea5f97434Tim Northover       << ", amount=" << ShiftExtend.Amount << ">";
227372062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
227472062f5744557e270a38192554c3126ea5f97434Tim Northover  case k_SysReg: {
227572062f5744557e270a38192554c3126ea5f97434Tim Northover    StringRef Name(SysReg.Data, SysReg.Length);
227672062f5744557e270a38192554c3126ea5f97434Tim Northover    OS << "<sysreg: " << Name << '>';
227772062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
227872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
227972062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
228072062f5744557e270a38192554c3126ea5f97434Tim Northover    llvm_unreachable("No idea how to print this kind of operand");
228172062f5744557e270a38192554c3126ea5f97434Tim Northover    break;
228272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
228372062f5744557e270a38192554c3126ea5f97434Tim Northover}
228472062f5744557e270a38192554c3126ea5f97434Tim Northover
228572062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64Operand::dump() const {
228672062f5744557e270a38192554c3126ea5f97434Tim Northover  print(errs());
228772062f5744557e270a38192554c3126ea5f97434Tim Northover}
228872062f5744557e270a38192554c3126ea5f97434Tim Northover
228972062f5744557e270a38192554c3126ea5f97434Tim Northover
229072062f5744557e270a38192554c3126ea5f97434Tim Northover/// Force static initialization.
229172062f5744557e270a38192554c3126ea5f97434Tim Northoverextern "C" void LLVMInitializeAArch64AsmParser() {
229272062f5744557e270a38192554c3126ea5f97434Tim Northover  RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64Target);
229372062f5744557e270a38192554c3126ea5f97434Tim Northover}
229472062f5744557e270a38192554c3126ea5f97434Tim Northover
229572062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_REGISTER_MATCHER
229672062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_MATCHER_IMPLEMENTATION
229772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenAsmMatcher.inc"
2298