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