1 //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "InstPrinter/X86IntelInstPrinter.h"
11 #include "MCTargetDesc/X86BaseInfo.h"
12 #include "MCTargetDesc/X86TargetStreamer.h"
13 #include "X86AsmInstrumentation.h"
14 #include "X86AsmParserCommon.h"
15 #include "X86Operand.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCParser/MCAsmLexer.h"
26 #include "llvm/MC/MCParser/MCAsmParser.h"
27 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
28 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCSection.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSubtargetInfo.h"
33 #include "llvm/MC/MCSymbol.h"
34 #include "llvm/Support/SourceMgr.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include "llvm/Support/raw_ostream.h"
42 static bool checkScale(unsigned Scale, StringRef &ErrMsg) {
43 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
44 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
52 static const char OpPrecedence[] = {
71 class X86AsmParser : public MCTargetAsmParser {
72 ParseInstructionInfo *InstInfo;
73 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
77 SMLoc consumeToken() {
78 MCAsmParser &Parser = getParser();
79 SMLoc Result = Parser.getTok().getLoc();
84 X86TargetStreamer &getTargetStreamer() {
85 assert(getParser().getStreamer().getTargetStreamer() &&
86 "do not have a target streamer");
87 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
88 return static_cast<X86TargetStreamer &>(TS);
91 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
92 uint64_t &ErrorInfo, bool matchingInlineAsm,
93 unsigned VariantID = 0) {
94 // In Code16GCC mode, match as 32-bit.
96 SwitchMode(X86::Mode32Bit);
97 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
98 matchingInlineAsm, VariantID);
100 SwitchMode(X86::Mode16Bit);
104 enum InfixCalculatorTok {
123 enum IntelOperatorKind {
131 class InfixCalculator {
132 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
133 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
134 SmallVector<ICToken, 4> PostfixStack;
136 bool isUnaryOperator(const InfixCalculatorTok Op) {
137 return Op == IC_NEG || Op == IC_NOT;
141 int64_t popOperand() {
142 assert (!PostfixStack.empty() && "Poped an empty stack!");
143 ICToken Op = PostfixStack.pop_back_val();
144 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
145 return -1; // The invalid Scale value will be caught later by checkScale
148 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
149 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
150 "Unexpected operand!");
151 PostfixStack.push_back(std::make_pair(Op, Val));
154 void popOperator() { InfixOperatorStack.pop_back(); }
155 void pushOperator(InfixCalculatorTok Op) {
156 // Push the new operator if the stack is empty.
157 if (InfixOperatorStack.empty()) {
158 InfixOperatorStack.push_back(Op);
162 // Push the new operator if it has a higher precedence than the operator
163 // on the top of the stack or the operator on the top of the stack is a
165 unsigned Idx = InfixOperatorStack.size() - 1;
166 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
167 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
168 InfixOperatorStack.push_back(Op);
172 // The operator on the top of the stack has higher precedence than the
174 unsigned ParenCount = 0;
176 // Nothing to process.
177 if (InfixOperatorStack.empty())
180 Idx = InfixOperatorStack.size() - 1;
181 StackOp = InfixOperatorStack[Idx];
182 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
185 // If we have an even parentheses count and we see a left parentheses,
186 // then stop processing.
187 if (!ParenCount && StackOp == IC_LPAREN)
190 if (StackOp == IC_RPAREN) {
192 InfixOperatorStack.pop_back();
193 } else if (StackOp == IC_LPAREN) {
195 InfixOperatorStack.pop_back();
197 InfixOperatorStack.pop_back();
198 PostfixStack.push_back(std::make_pair(StackOp, 0));
201 // Push the new operator.
202 InfixOperatorStack.push_back(Op);
206 // Push any remaining operators onto the postfix stack.
207 while (!InfixOperatorStack.empty()) {
208 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
209 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
210 PostfixStack.push_back(std::make_pair(StackOp, 0));
213 if (PostfixStack.empty())
216 SmallVector<ICToken, 16> OperandStack;
217 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
218 ICToken Op = PostfixStack[i];
219 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
220 OperandStack.push_back(Op);
221 } else if (isUnaryOperator(Op.first)) {
222 assert (OperandStack.size() > 0 && "Too few operands.");
223 ICToken Operand = OperandStack.pop_back_val();
224 assert (Operand.first == IC_IMM &&
225 "Unary operation with a register!");
228 report_fatal_error("Unexpected operator!");
231 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));
234 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));
238 assert (OperandStack.size() > 1 && "Too few operands.");
240 ICToken Op2 = OperandStack.pop_back_val();
241 ICToken Op1 = OperandStack.pop_back_val();
244 report_fatal_error("Unexpected operator!");
247 Val = Op1.second + Op2.second;
248 OperandStack.push_back(std::make_pair(IC_IMM, Val));
251 Val = Op1.second - Op2.second;
252 OperandStack.push_back(std::make_pair(IC_IMM, Val));
255 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
256 "Multiply operation with an immediate and a register!");
257 Val = Op1.second * Op2.second;
258 OperandStack.push_back(std::make_pair(IC_IMM, Val));
261 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
262 "Divide operation with an immediate and a register!");
263 assert (Op2.second != 0 && "Division by zero!");
264 Val = Op1.second / Op2.second;
265 OperandStack.push_back(std::make_pair(IC_IMM, Val));
268 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
269 "Modulo operation with an immediate and a register!");
270 Val = Op1.second % Op2.second;
271 OperandStack.push_back(std::make_pair(IC_IMM, Val));
274 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
275 "Or operation with an immediate and a register!");
276 Val = Op1.second | Op2.second;
277 OperandStack.push_back(std::make_pair(IC_IMM, Val));
280 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
281 "Xor operation with an immediate and a register!");
282 Val = Op1.second ^ Op2.second;
283 OperandStack.push_back(std::make_pair(IC_IMM, Val));
286 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
287 "And operation with an immediate and a register!");
288 Val = Op1.second & Op2.second;
289 OperandStack.push_back(std::make_pair(IC_IMM, Val));
292 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
293 "Left shift operation with an immediate and a register!");
294 Val = Op1.second << Op2.second;
295 OperandStack.push_back(std::make_pair(IC_IMM, Val));
298 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
299 "Right shift operation with an immediate and a register!");
300 Val = Op1.second >> Op2.second;
301 OperandStack.push_back(std::make_pair(IC_IMM, Val));
306 assert (OperandStack.size() == 1 && "Expected a single result.");
307 return OperandStack.pop_back_val().second;
311 enum IntelExprState {
334 class IntelExprStateMachine {
335 IntelExprState State, PrevState;
336 unsigned BaseReg, IndexReg, TmpReg, Scale;
341 InlineAsmIdentifierInfo Info;
346 IntelExprStateMachine()
347 : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0),
348 TmpReg(0), Scale(1), Imm(0), Sym(nullptr), BracCount(0),
351 void addImm(int64_t imm) { Imm += imm; }
352 short getBracCount() { return BracCount; }
353 bool isMemExpr() { return MemExpr; }
354 unsigned getBaseReg() { return BaseReg; }
355 unsigned getIndexReg() { return IndexReg; }
356 unsigned getScale() { return Scale; }
357 const MCExpr *getSym() { return Sym; }
358 StringRef getSymName() { return SymName; }
359 int64_t getImm() { return Imm + IC.execute(); }
360 bool isValidEndState() {
361 return State == IES_RBRAC || State == IES_INTEGER;
363 bool hadError() { return State == IES_ERROR; }
364 InlineAsmIdentifierInfo &getIdentifierInfo() { return Info; }
367 IntelExprState CurrState = State;
376 IC.pushOperator(IC_OR);
379 PrevState = CurrState;
382 IntelExprState CurrState = State;
391 IC.pushOperator(IC_XOR);
394 PrevState = CurrState;
397 IntelExprState CurrState = State;
406 IC.pushOperator(IC_AND);
409 PrevState = CurrState;
412 IntelExprState CurrState = State;
421 IC.pushOperator(IC_LSHIFT);
424 PrevState = CurrState;
427 IntelExprState CurrState = State;
436 IC.pushOperator(IC_RSHIFT);
439 PrevState = CurrState;
441 bool onPlus(StringRef &ErrMsg) {
442 IntelExprState CurrState = State;
451 IC.pushOperator(IC_PLUS);
452 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
453 // If we already have a BaseReg, then assume this is the IndexReg with
459 ErrMsg = "BaseReg/IndexReg already set!";
468 PrevState = CurrState;
471 bool onMinus(StringRef &ErrMsg) {
472 IntelExprState CurrState = State;
495 // push minus operator if it is not a negate operator
496 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
497 CurrState == IES_INTEGER || CurrState == IES_RBRAC)
498 IC.pushOperator(IC_MINUS);
499 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
500 // We have negate operator for Scale: it's illegal
501 ErrMsg = "Scale can't be negative";
504 IC.pushOperator(IC_NEG);
505 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
506 // If we already have a BaseReg, then assume this is the IndexReg with
512 ErrMsg = "BaseReg/IndexReg already set!";
521 PrevState = CurrState;
525 IntelExprState CurrState = State;
545 IC.pushOperator(IC_NOT);
548 PrevState = CurrState;
551 bool onRegister(unsigned Reg, StringRef &ErrMsg) {
552 IntelExprState CurrState = State;
560 State = IES_REGISTER;
562 IC.pushOperand(IC_REGISTER);
565 // Index Register - Scale * Register
566 if (PrevState == IES_INTEGER) {
568 ErrMsg = "BaseReg/IndexReg already set!";
571 State = IES_REGISTER;
573 // Get the scale and replace the 'Scale * Register' with '0'.
574 Scale = IC.popOperand();
575 if (checkScale(Scale, ErrMsg))
577 IC.pushOperand(IC_IMM);
584 PrevState = CurrState;
587 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
588 const InlineAsmIdentifierInfo &IDInfo,
589 bool ParsingInlineAsm, StringRef &ErrMsg) {
590 // InlineAsm: Treat an enum value as an integer
591 if (ParsingInlineAsm)
592 if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
593 return onInteger(IDInfo.Enum.EnumVal, ErrMsg);
594 // Treat a symbolic constant like an integer
595 if (auto *CE = dyn_cast<MCConstantExpr>(SymRef))
596 return onInteger(CE->getValue(), ErrMsg);
598 bool HasSymbol = Sym != nullptr;
611 SymName = SymRefName;
612 IC.pushOperand(IC_IMM);
613 if (ParsingInlineAsm)
618 ErrMsg = "cannot use more than one symbol in memory operand";
621 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
622 IntelExprState CurrState = State;
642 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
643 // Index Register - Register * Scale
645 ErrMsg = "BaseReg/IndexReg already set!";
650 if (checkScale(Scale, ErrMsg))
652 // Get the scale and replace the 'Register * Scale' with '0'.
655 IC.pushOperand(IC_IMM, TmpInt);
659 PrevState = CurrState;
671 State = IES_MULTIPLY;
672 IC.pushOperator(IC_MULTIPLY);
685 IC.pushOperator(IC_DIVIDE);
698 IC.pushOperator(IC_MOD);
714 IC.pushOperator(IC_PLUS);
717 assert(!BracCount && "BracCount should be zero on parsing's start");
726 IntelExprState CurrState = State;
734 if (BracCount-- != 1)
737 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
738 // If we already have a BaseReg, then assume this is the IndexReg with
743 assert (!IndexReg && "BaseReg/IndexReg already set!");
750 PrevState = CurrState;
754 IntelExprState CurrState = State;
774 IC.pushOperator(IC_LPAREN);
777 PrevState = CurrState;
789 IC.pushOperator(IC_RPAREN);
795 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None,
796 bool MatchingInlineAsm = false) {
797 MCAsmParser &Parser = getParser();
798 if (MatchingInlineAsm) {
799 if (!getLexer().isAtStartOfStatement())
800 Parser.eatToEndOfStatement();
803 return Parser.Error(L, Msg, Range);
806 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
811 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
812 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
813 bool IsSIReg(unsigned Reg);
814 unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg);
816 AddDefaultSrcDestOperands(OperandVector &Operands,
817 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
818 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
819 bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
820 OperandVector &FinalOperands);
821 std::unique_ptr<X86Operand> ParseOperand();
822 std::unique_ptr<X86Operand> ParseATTOperand();
823 std::unique_ptr<X86Operand> ParseIntelOperand();
824 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
825 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
826 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
827 unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
828 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
829 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM);
830 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
832 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
833 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,
834 InlineAsmIdentifierInfo &Info,
835 bool IsUnevaluatedOperand, SMLoc &End);
837 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
839 bool ParseIntelMemoryOperandSize(unsigned &Size);
840 std::unique_ptr<X86Operand>
841 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
842 unsigned IndexReg, unsigned Scale, SMLoc Start,
843 SMLoc End, unsigned Size, StringRef Identifier,
844 const InlineAsmIdentifierInfo &Info);
846 bool parseDirectiveEven(SMLoc L);
847 bool ParseDirectiveWord(unsigned Size, SMLoc L);
848 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
850 /// CodeView FPO data directives.
851 bool parseDirectiveFPOProc(SMLoc L);
852 bool parseDirectiveFPOSetFrame(SMLoc L);
853 bool parseDirectiveFPOPushReg(SMLoc L);
854 bool parseDirectiveFPOStackAlloc(SMLoc L);
855 bool parseDirectiveFPOEndPrologue(SMLoc L);
856 bool parseDirectiveFPOEndProc(SMLoc L);
857 bool parseDirectiveFPOData(SMLoc L);
859 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
860 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
862 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
863 /// instrumentation around Inst.
864 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
866 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
867 OperandVector &Operands, MCStreamer &Out,
869 bool MatchingInlineAsm) override;
871 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
872 MCStreamer &Out, bool MatchingInlineAsm);
874 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
875 bool MatchingInlineAsm);
877 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
878 OperandVector &Operands, MCStreamer &Out,
880 bool MatchingInlineAsm);
882 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
883 OperandVector &Operands, MCStreamer &Out,
885 bool MatchingInlineAsm);
887 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
889 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
890 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
891 /// return false if no parsing errors occurred, true otherwise.
892 bool HandleAVX512Operand(OperandVector &Operands,
893 const MCParsedAsmOperand &Op);
895 bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
897 bool is64BitMode() const {
898 // FIXME: Can tablegen auto-generate this?
899 return getSTI().getFeatureBits()[X86::Mode64Bit];
901 bool is32BitMode() const {
902 // FIXME: Can tablegen auto-generate this?
903 return getSTI().getFeatureBits()[X86::Mode32Bit];
905 bool is16BitMode() const {
906 // FIXME: Can tablegen auto-generate this?
907 return getSTI().getFeatureBits()[X86::Mode16Bit];
909 void SwitchMode(unsigned mode) {
910 MCSubtargetInfo &STI = copySTI();
911 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
912 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
913 uint64_t FB = ComputeAvailableFeatures(
914 STI.ToggleFeature(OldMode.flip(mode)));
915 setAvailableFeatures(FB);
917 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
920 unsigned getPointerWidth() {
921 if (is16BitMode()) return 16;
922 if (is32BitMode()) return 32;
923 if (is64BitMode()) return 64;
924 llvm_unreachable("invalid mode");
927 bool isParsingIntelSyntax() {
928 return getParser().getAssemblerDialect();
931 /// @name Auto-generated Matcher Functions
934 #define GET_ASSEMBLER_HEADER
935 #include "X86GenAsmMatcher.inc"
941 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
942 const MCInstrInfo &mii, const MCTargetOptions &Options)
943 : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr),
946 // Initialize the set of available features.
947 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
948 Instrumentation.reset(
949 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
952 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
954 void SetFrameRegister(unsigned RegNo) override;
956 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
957 SMLoc NameLoc, OperandVector &Operands) override;
959 bool ParseDirective(AsmToken DirectiveID) override;
961 } // end anonymous namespace
963 /// @name Auto-generated Match Functions
966 static unsigned MatchRegisterName(StringRef Name);
970 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
971 unsigned Scale, StringRef &ErrMsg) {
972 // If we have both a base register and an index register make sure they are
973 // both 64-bit or 32-bit registers.
974 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
976 if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) {
977 ErrMsg = "invalid base+index expression";
980 if (BaseReg != 0 && IndexReg != 0) {
981 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
982 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
983 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
984 IndexReg != X86::RIZ) {
985 ErrMsg = "base register is 64-bit, but index register is not";
988 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
989 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
990 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
991 IndexReg != X86::EIZ){
992 ErrMsg = "base register is 32-bit, but index register is not";
995 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
996 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
997 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
998 ErrMsg = "base register is 16-bit, but index register is not";
1001 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
1002 IndexReg != X86::SI && IndexReg != X86::DI) ||
1003 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
1004 IndexReg != X86::BX && IndexReg != X86::BP)) {
1005 ErrMsg = "invalid 16-bit base/index register combination";
1010 return checkScale(Scale, ErrMsg);
1013 bool X86AsmParser::ParseRegister(unsigned &RegNo,
1014 SMLoc &StartLoc, SMLoc &EndLoc) {
1015 MCAsmParser &Parser = getParser();
1017 const AsmToken &PercentTok = Parser.getTok();
1018 StartLoc = PercentTok.getLoc();
1020 // If we encounter a %, ignore it. This code handles registers with and
1021 // without the prefix, unprefixed registers can occur in cfi directives.
1022 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
1023 Parser.Lex(); // Eat percent token.
1025 const AsmToken &Tok = Parser.getTok();
1026 EndLoc = Tok.getEndLoc();
1028 if (Tok.isNot(AsmToken::Identifier)) {
1029 if (isParsingIntelSyntax()) return true;
1030 return Error(StartLoc, "invalid register name",
1031 SMRange(StartLoc, EndLoc));
1034 RegNo = MatchRegisterName(Tok.getString());
1036 // If the match failed, try the register name as lowercase.
1038 RegNo = MatchRegisterName(Tok.getString().lower());
1040 // The "flags" register cannot be referenced directly.
1041 // Treat it as an identifier instead.
1042 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
1045 if (!is64BitMode()) {
1046 // FIXME: This should be done using Requires<Not64BitMode> and
1047 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
1049 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
1051 if (RegNo == X86::RIZ ||
1052 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1053 X86II::isX86_64NonExtLowByteReg(RegNo) ||
1054 X86II::isX86_64ExtendedReg(RegNo))
1055 return Error(StartLoc, "register %"
1056 + Tok.getString() + " is only available in 64-bit mode",
1057 SMRange(StartLoc, EndLoc));
1058 } else if (!getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1059 if (X86II::is32ExtendedReg(RegNo))
1060 return Error(StartLoc, "register %"
1061 + Tok.getString() + " is only available with AVX512",
1062 SMRange(StartLoc, EndLoc));
1065 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
1066 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
1068 Parser.Lex(); // Eat 'st'
1070 // Check to see if we have '(4)' after %st.
1071 if (getLexer().isNot(AsmToken::LParen))
1076 const AsmToken &IntTok = Parser.getTok();
1077 if (IntTok.isNot(AsmToken::Integer))
1078 return Error(IntTok.getLoc(), "expected stack index");
1079 switch (IntTok.getIntVal()) {
1080 case 0: RegNo = X86::ST0; break;
1081 case 1: RegNo = X86::ST1; break;
1082 case 2: RegNo = X86::ST2; break;
1083 case 3: RegNo = X86::ST3; break;
1084 case 4: RegNo = X86::ST4; break;
1085 case 5: RegNo = X86::ST5; break;
1086 case 6: RegNo = X86::ST6; break;
1087 case 7: RegNo = X86::ST7; break;
1088 default: return Error(IntTok.getLoc(), "invalid stack index");
1091 if (getParser().Lex().isNot(AsmToken::RParen))
1092 return Error(Parser.getTok().getLoc(), "expected ')'");
1094 EndLoc = Parser.getTok().getEndLoc();
1095 Parser.Lex(); // Eat ')'
1099 EndLoc = Parser.getTok().getEndLoc();
1101 // If this is "db[0-15]", match it as an alias
1103 if (RegNo == 0 && Tok.getString().startswith("db")) {
1104 if (Tok.getString().size() == 3) {
1105 switch (Tok.getString()[2]) {
1106 case '0': RegNo = X86::DR0; break;
1107 case '1': RegNo = X86::DR1; break;
1108 case '2': RegNo = X86::DR2; break;
1109 case '3': RegNo = X86::DR3; break;
1110 case '4': RegNo = X86::DR4; break;
1111 case '5': RegNo = X86::DR5; break;
1112 case '6': RegNo = X86::DR6; break;
1113 case '7': RegNo = X86::DR7; break;
1114 case '8': RegNo = X86::DR8; break;
1115 case '9': RegNo = X86::DR9; break;
1117 } else if (Tok.getString().size() == 4 && Tok.getString()[2] == '1') {
1118 switch (Tok.getString()[3]) {
1119 case '0': RegNo = X86::DR10; break;
1120 case '1': RegNo = X86::DR11; break;
1121 case '2': RegNo = X86::DR12; break;
1122 case '3': RegNo = X86::DR13; break;
1123 case '4': RegNo = X86::DR14; break;
1124 case '5': RegNo = X86::DR15; break;
1129 EndLoc = Parser.getTok().getEndLoc();
1130 Parser.Lex(); // Eat it.
1136 if (isParsingIntelSyntax()) return true;
1137 return Error(StartLoc, "invalid register name",
1138 SMRange(StartLoc, EndLoc));
1141 Parser.Lex(); // Eat identifier token.
1145 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1146 Instrumentation->SetInitialFrameRegister(RegNo);
1149 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1150 bool Parse32 = is32BitMode() || Code16GCC;
1151 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1152 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1153 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1154 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1158 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1159 bool Parse32 = is32BitMode() || Code16GCC;
1160 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1161 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1162 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1163 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
1167 bool X86AsmParser::IsSIReg(unsigned Reg) {
1169 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
1181 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
1183 switch (RegClassID) {
1184 default: llvm_unreachable("Unexpected register class");
1185 case X86::GR64RegClassID:
1186 return IsSIReg ? X86::RSI : X86::RDI;
1187 case X86::GR32RegClassID:
1188 return IsSIReg ? X86::ESI : X86::EDI;
1189 case X86::GR16RegClassID:
1190 return IsSIReg ? X86::SI : X86::DI;
1194 void X86AsmParser::AddDefaultSrcDestOperands(
1195 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1196 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1197 if (isParsingIntelSyntax()) {
1198 Operands.push_back(std::move(Dst));
1199 Operands.push_back(std::move(Src));
1202 Operands.push_back(std::move(Src));
1203 Operands.push_back(std::move(Dst));
1207 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1208 OperandVector &FinalOperands) {
1210 if (OrigOperands.size() > 1) {
1211 // Check if sizes match, OrigOperands also contains the instruction name
1212 assert(OrigOperands.size() == FinalOperands.size() + 1 &&
1213 "Operand size mismatch");
1215 SmallVector<std::pair<SMLoc, std::string>, 2> Warnings;
1216 // Verify types match
1217 int RegClassID = -1;
1218 for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1219 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1220 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1222 if (FinalOp.isReg() &&
1223 (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
1224 // Return false and let a normal complaint about bogus operands happen
1227 if (FinalOp.isMem()) {
1229 if (!OrigOp.isMem())
1230 // Return false and let a normal complaint about bogus operands happen
1233 unsigned OrigReg = OrigOp.Mem.BaseReg;
1234 unsigned FinalReg = FinalOp.Mem.BaseReg;
1236 // If we've already encounterd a register class, make sure all register
1237 // bases are of the same register class
1238 if (RegClassID != -1 &&
1239 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1240 return Error(OrigOp.getStartLoc(),
1241 "mismatching source and destination index registers");
1244 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1245 RegClassID = X86::GR64RegClassID;
1246 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1247 RegClassID = X86::GR32RegClassID;
1248 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1249 RegClassID = X86::GR16RegClassID;
1251 // Unexpected register class type
1252 // Return false and let a normal complaint about bogus operands happen
1255 bool IsSI = IsSIReg(FinalReg);
1256 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
1258 if (FinalReg != OrigReg) {
1259 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
1260 Warnings.push_back(std::make_pair(
1261 OrigOp.getStartLoc(),
1262 "memory operand is only for determining the size, " + RegName +
1263 " will be used for the location"));
1266 FinalOp.Mem.Size = OrigOp.Mem.Size;
1267 FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
1268 FinalOp.Mem.BaseReg = FinalReg;
1272 // Produce warnings only if all the operands passed the adjustment - prevent
1273 // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
1274 for (auto &WarningMsg : Warnings) {
1275 Warning(WarningMsg.first, WarningMsg.second);
1278 // Remove old operands
1279 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1280 OrigOperands.pop_back();
1282 // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
1283 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1284 OrigOperands.push_back(std::move(FinalOperands[i]));
1289 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1290 if (isParsingIntelSyntax())
1291 return ParseIntelOperand();
1292 return ParseATTOperand();
1295 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1296 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1297 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1298 const InlineAsmIdentifierInfo &Info) {
1299 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1300 // some other label reference.
1301 if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) {
1302 // Insert an explicit size if the user didn't have one.
1304 Size = getPointerWidth();
1305 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1308 // Create an absolute memory reference in order to match against
1309 // instructions taking a PC relative operand.
1310 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1311 Identifier, Info.Label.Decl);
1313 // We either have a direct symbol reference, or an offset from a symbol. The
1314 // parser always puts the symbol on the LHS, so look there for size
1315 // calculation purposes.
1316 unsigned FrontendSize = 0;
1317 void *Decl = nullptr;
1318 bool IsGlobalLV = false;
1319 if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
1320 // Size is in terms of bits in this context.
1321 FrontendSize = Info.Var.Type * 8;
1322 Decl = Info.Var.Decl;
1323 IsGlobalLV = Info.Var.IsGlobalLV;
1325 // It is widely common for MS InlineAsm to use a global variable and one/two
1326 // registers in a mmory expression, and though unaccessible via rip/eip.
1327 if (IsGlobalLV && (BaseReg || IndexReg)) {
1328 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End);
1329 // Otherwise, we set the base register to a non-zero value
1330 // if we don't know the actual value at this time. This is necessary to
1331 // get the matching correct in some cases.
1333 BaseReg = BaseReg ? BaseReg : 1;
1334 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1335 IndexReg, Scale, Start, End, Size, Identifier,
1336 Decl, FrontendSize);
1340 // Some binary bitwise operators have a named synonymous
1341 // Query a candidate string for being such a named operator
1342 // and if so - invoke the appropriate handler
1343 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) {
1344 // A named operator should be either lower or upper case, but not a mix
1345 if (Name.compare(Name.lower()) && Name.compare(Name.upper()))
1347 if (Name.equals_lower("not"))
1349 else if (Name.equals_lower("or"))
1351 else if (Name.equals_lower("shl"))
1353 else if (Name.equals_lower("shr"))
1355 else if (Name.equals_lower("xor"))
1357 else if (Name.equals_lower("and"))
1359 else if (Name.equals_lower("mod"))
1366 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1367 MCAsmParser &Parser = getParser();
1368 const AsmToken &Tok = Parser.getTok();
1371 AsmToken::TokenKind PrevTK = AsmToken::Error;
1374 bool UpdateLocLex = true;
1375 AsmToken::TokenKind TK = getLexer().getKind();
1379 if ((Done = SM.isValidEndState()))
1381 return Error(Tok.getLoc(), "unknown token in expression");
1382 case AsmToken::EndOfStatement:
1385 case AsmToken::Real:
1386 // DotOperator: [ebx].0
1387 UpdateLocLex = false;
1388 if (ParseIntelDotOperator(SM, End))
1391 case AsmToken::String:
1392 case AsmToken::Identifier: {
1393 SMLoc IdentLoc = Tok.getLoc();
1394 StringRef Identifier = Tok.getString();
1395 UpdateLocLex = false;
1398 if (Tok.isNot(AsmToken::String) && !ParseRegister(Reg, IdentLoc, End)) {
1399 if (SM.onRegister(Reg, ErrMsg))
1400 return Error(Tok.getLoc(), ErrMsg);
1403 // Operator synonymous ("not", "or" etc.)
1404 if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM)))
1406 // Symbol reference, when parsing assembly content
1407 InlineAsmIdentifierInfo Info;
1409 if (!isParsingInlineAsm()) {
1410 if (getParser().parsePrimaryExpr(Val, End)) {
1411 return Error(Tok.getLoc(), "Unexpected identifier!");
1412 } else if (SM.onIdentifierExpr(Val, Identifier, Info, false, ErrMsg)) {
1413 return Error(IdentLoc, ErrMsg);
1417 // MS InlineAsm operators (TYPE/LENGTH/SIZE)
1418 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
1419 if (OpKind == IOK_OFFSET)
1420 return Error(IdentLoc, "Dealing OFFSET operator as part of"
1421 "a compound immediate expression is yet to be supported");
1422 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
1423 if (SM.onInteger(Val, ErrMsg))
1424 return Error(IdentLoc, ErrMsg);
1429 // MS Dot Operator expression
1430 if (Identifier.count('.') && PrevTK == AsmToken::RBrac) {
1431 if (ParseIntelDotOperator(SM, End))
1435 // MS InlineAsm identifier
1436 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
1438 else if (SM.onIdentifierExpr(Val, Identifier, Info, true, ErrMsg))
1439 return Error(IdentLoc, ErrMsg);
1442 case AsmToken::Integer: {
1443 // Look for 'b' or 'f' following an Integer as a directional label
1444 SMLoc Loc = getTok().getLoc();
1445 int64_t IntVal = getTok().getIntVal();
1446 End = consumeToken();
1447 UpdateLocLex = false;
1448 if (getLexer().getKind() == AsmToken::Identifier) {
1449 StringRef IDVal = getTok().getString();
1450 if (IDVal == "f" || IDVal == "b") {
1452 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1453 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1455 MCSymbolRefExpr::create(Sym, Variant, getContext());
1456 if (IDVal == "b" && Sym->isUndefined())
1457 return Error(Loc, "invalid reference to undefined symbol");
1458 StringRef Identifier = Sym->getName();
1459 InlineAsmIdentifierInfo Info;
1460 if (SM.onIdentifierExpr(Val, Identifier, Info,
1461 isParsingInlineAsm(), ErrMsg))
1462 return Error(Loc, ErrMsg);
1463 End = consumeToken();
1465 if (SM.onInteger(IntVal, ErrMsg))
1466 return Error(Loc, ErrMsg);
1469 if (SM.onInteger(IntVal, ErrMsg))
1470 return Error(Loc, ErrMsg);
1474 case AsmToken::Plus:
1475 if (SM.onPlus(ErrMsg))
1476 return Error(getTok().getLoc(), ErrMsg);
1478 case AsmToken::Minus:
1479 if (SM.onMinus(ErrMsg))
1480 return Error(getTok().getLoc(), ErrMsg);
1482 case AsmToken::Tilde: SM.onNot(); break;
1483 case AsmToken::Star: SM.onStar(); break;
1484 case AsmToken::Slash: SM.onDivide(); break;
1485 case AsmToken::Percent: SM.onMod(); break;
1486 case AsmToken::Pipe: SM.onOr(); break;
1487 case AsmToken::Caret: SM.onXor(); break;
1488 case AsmToken::Amp: SM.onAnd(); break;
1489 case AsmToken::LessLess:
1490 SM.onLShift(); break;
1491 case AsmToken::GreaterGreater:
1492 SM.onRShift(); break;
1493 case AsmToken::LBrac:
1495 return Error(Tok.getLoc(), "unexpected bracket encountered");
1497 case AsmToken::RBrac:
1499 return Error(Tok.getLoc(), "unexpected bracket encountered");
1501 case AsmToken::LParen: SM.onLParen(); break;
1502 case AsmToken::RParen: SM.onRParen(); break;
1505 return Error(Tok.getLoc(), "unknown token in expression");
1507 if (!Done && UpdateLocLex)
1508 End = consumeToken();
1515 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
1516 SMLoc Start, SMLoc End) {
1518 unsigned ExprLen = End.getPointer() - Start.getPointer();
1519 // Skip everything before a symbol displacement (if we have one)
1521 StringRef SymName = SM.getSymName();
1522 if (unsigned Len = SymName.data() - Start.getPointer())
1523 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);
1524 Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());
1525 ExprLen = End.getPointer() - (SymName.data() + SymName.size());
1526 // If we have only a symbol than there's no need for complex rewrite,
1527 // simply skip everything after it
1528 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
1530 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);
1534 // Build an Intel Expression rewrite
1535 StringRef BaseRegStr;
1536 StringRef IndexRegStr;
1537 if (SM.getBaseReg())
1538 BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());
1539 if (SM.getIndexReg())
1540 IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());
1542 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr());
1543 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
1546 // Inline assembly may use variable names with namespace alias qualifiers.
1547 bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val,
1548 StringRef &Identifier,
1549 InlineAsmIdentifierInfo &Info,
1550 bool IsUnevaluatedOperand,
1552 MCAsmParser &Parser = getParser();
1553 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1556 StringRef LineBuf(Identifier.data());
1557 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1559 const AsmToken &Tok = Parser.getTok();
1560 SMLoc Loc = Tok.getLoc();
1562 // Advance the token stream until the end of the current token is
1563 // after the end of what the frontend claimed.
1564 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1566 End = Tok.getEndLoc();
1568 } while (End.getPointer() < EndPtr);
1569 Identifier = LineBuf;
1571 // The frontend should end parsing on an assembler token boundary, unless it
1573 assert((End.getPointer() == EndPtr ||
1574 Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) &&
1575 "frontend claimed part of a token?");
1577 // If the identifier lookup was unsuccessful, assume that we are dealing with
1579 if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) {
1580 StringRef InternalName =
1581 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1583 assert(InternalName.size() && "We should have an internal name here.");
1584 // Push a rewrite for replacing the identifier name with the internal name.
1585 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1587 } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
1589 // Create the symbol reference.
1590 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1591 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1592 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1596 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1597 std::unique_ptr<X86Operand>
1598 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1599 MCAsmParser &Parser = getParser();
1600 const AsmToken &Tok = Parser.getTok();
1601 // Eat "{" and mark the current place.
1602 const SMLoc consumedToken = consumeToken();
1603 if (Tok.getIdentifier().startswith("r")){
1604 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1605 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1606 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1607 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1608 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1611 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1612 Parser.Lex(); // Eat "r*" of r*-sae
1613 if (!getLexer().is(AsmToken::Minus))
1614 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1615 Parser.Lex(); // Eat "-"
1616 Parser.Lex(); // Eat the sae
1617 if (!getLexer().is(AsmToken::RCurly))
1618 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1619 Parser.Lex(); // Eat "}"
1620 const MCExpr *RndModeOp =
1621 MCConstantExpr::create(rndMode, Parser.getContext());
1622 return X86Operand::CreateImm(RndModeOp, Start, End);
1624 if(Tok.getIdentifier().equals("sae")){
1625 Parser.Lex(); // Eat the sae
1626 if (!getLexer().is(AsmToken::RCurly))
1627 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1628 Parser.Lex(); // Eat "}"
1629 return X86Operand::CreateToken("{sae}", consumedToken);
1631 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1634 /// Parse the '.' operator.
1635 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) {
1636 const AsmToken &Tok = getTok();
1639 // Drop the optional '.'.
1640 StringRef DotDispStr = Tok.getString();
1641 if (DotDispStr.startswith("."))
1642 DotDispStr = DotDispStr.drop_front(1);
1644 // .Imm gets lexed as a real.
1645 if (Tok.is(AsmToken::Real)) {
1647 DotDispStr.getAsInteger(10, DotDisp);
1648 Offset = DotDisp.getZExtValue();
1649 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1650 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1651 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1653 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1655 return Error(Tok.getLoc(), "Unexpected token type!");
1657 // Eat the DotExpression and update End
1658 End = SMLoc::getFromPointer(DotDispStr.data());
1659 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
1660 while (Tok.getLoc().getPointer() < DotExprEndLoc)
1666 /// Parse the 'offset' operator. This operator is used to specify the
1667 /// location rather then the content of a variable.
1668 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1669 MCAsmParser &Parser = getParser();
1670 const AsmToken &Tok = Parser.getTok();
1671 SMLoc OffsetOfLoc = Tok.getLoc();
1672 Parser.Lex(); // Eat offset.
1675 InlineAsmIdentifierInfo Info;
1676 SMLoc Start = Tok.getLoc(), End;
1677 StringRef Identifier = Tok.getString();
1678 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1679 /*Unevaluated=*/false, End))
1682 void *Decl = nullptr;
1683 // FIXME: MS evaluates "offset <Constant>" to the underlying integral
1684 if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
1685 return ErrorOperand(Start, "offset operator cannot yet handle constants");
1686 else if (Info.isKind(InlineAsmIdentifierInfo::IK_Var))
1687 Decl = Info.Var.Decl;
1688 // Don't emit the offset operator.
1689 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1691 // The offset operator will have an 'r' constraint, thus we need to create
1692 // register operand to ensure proper matching. Just pick a GPR based on
1693 // the size of a pointer.
1694 bool Parse32 = is32BitMode() || Code16GCC;
1695 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1697 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1698 OffsetOfLoc, Identifier, Decl);
1701 // Query a candidate string for being an Intel assembly operator
1702 // Report back its kind, or IOK_INVALID if does not evaluated as a known one
1703 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
1704 return StringSwitch<unsigned>(Name)
1705 .Cases("TYPE","type",IOK_TYPE)
1706 .Cases("SIZE","size",IOK_SIZE)
1707 .Cases("LENGTH","length",IOK_LENGTH)
1708 .Cases("OFFSET","offset",IOK_OFFSET)
1709 .Default(IOK_INVALID);
1712 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1713 /// returns the number of elements in an array. It returns the value 1 for
1714 /// non-array variables. The SIZE operator returns the size of a C or C++
1715 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1716 /// TYPE operator returns the size of a C or C++ type or variable. If the
1717 /// variable is an array, TYPE returns the size of a single element.
1718 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
1719 MCAsmParser &Parser = getParser();
1720 const AsmToken &Tok = Parser.getTok();
1721 Parser.Lex(); // Eat operator.
1723 const MCExpr *Val = nullptr;
1724 InlineAsmIdentifierInfo Info;
1725 SMLoc Start = Tok.getLoc(), End;
1726 StringRef Identifier = Tok.getString();
1727 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
1728 /*Unevaluated=*/true, End))
1731 if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
1732 Error(Start, "unable to lookup expression");
1738 default: llvm_unreachable("Unexpected operand kind!");
1739 case IOK_LENGTH: CVal = Info.Var.Length; break;
1740 case IOK_SIZE: CVal = Info.Var.Size; break;
1741 case IOK_TYPE: CVal = Info.Var.Type; break;
1747 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
1748 Size = StringSwitch<unsigned>(getTok().getString())
1749 .Cases("BYTE", "byte", 8)
1750 .Cases("WORD", "word", 16)
1751 .Cases("DWORD", "dword", 32)
1752 .Cases("FLOAT", "float", 32)
1753 .Cases("LONG", "long", 32)
1754 .Cases("FWORD", "fword", 48)
1755 .Cases("DOUBLE", "double", 64)
1756 .Cases("QWORD", "qword", 64)
1757 .Cases("MMWORD","mmword", 64)
1758 .Cases("XWORD", "xword", 80)
1759 .Cases("TBYTE", "tbyte", 80)
1760 .Cases("XMMWORD", "xmmword", 128)
1761 .Cases("YMMWORD", "ymmword", 256)
1762 .Cases("ZMMWORD", "zmmword", 512)
1763 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1766 const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
1767 if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr")))
1768 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1774 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1775 MCAsmParser &Parser = getParser();
1776 const AsmToken &Tok = Parser.getTok();
1779 // FIXME: Offset operator
1780 // Should be handled as part of immediate expression, as other operators
1781 // Currently, only supported as a stand-alone operand
1782 if (isParsingInlineAsm())
1783 if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET)
1784 return ParseIntelOffsetOfOperator();
1786 // Parse optional Size directive.
1788 if (ParseIntelMemoryOperandSize(Size))
1790 bool PtrInOperand = bool(Size);
1792 Start = Tok.getLoc();
1794 // Rounding mode operand.
1795 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
1796 getLexer().is(AsmToken::LCurly))
1797 return ParseRoundingModeOp(Start, End);
1799 // Register operand.
1801 if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) {
1802 if (RegNo == X86::RIP)
1803 return ErrorOperand(Start, "rip can only be used as a base register");
1804 // A Register followed by ':' is considered a segment override
1805 if (Tok.isNot(AsmToken::Colon))
1806 return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) :
1807 ErrorOperand(Start, "expected memory operand after 'ptr', "
1808 "found register operand instead");
1809 // An alleged segment override. check if we have a valid segment register
1810 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1811 return ErrorOperand(Start, "invalid segment register");
1812 // Eat ':' and update Start location
1813 Start = Lex().getLoc();
1816 // Immediates and Memory
1817 IntelExprStateMachine SM;
1818 if (ParseIntelExpression(SM, End))
1821 if (isParsingInlineAsm())
1822 RewriteIntelExpression(SM, Start, Tok.getLoc());
1824 int64_t Imm = SM.getImm();
1825 const MCExpr *Disp = SM.getSym();
1826 const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());
1828 Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());
1832 // RegNo != 0 specifies a valid segment register,
1833 // and we are parsing a segment override
1834 if (!SM.isMemExpr() && !RegNo)
1835 return X86Operand::CreateImm(Disp, Start, End);
1838 unsigned BaseReg = SM.getBaseReg();
1839 unsigned IndexReg = SM.getIndexReg();
1840 unsigned Scale = SM.getScale();
1842 if ((BaseReg || IndexReg) &&
1843 CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg))
1844 return ErrorOperand(Start, ErrMsg);
1845 if (isParsingInlineAsm())
1846 return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg,
1847 Scale, Start, End, Size, SM.getSymName(),
1848 SM.getIdentifierInfo());
1849 if (!(BaseReg || IndexReg || RegNo))
1850 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1851 return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
1852 BaseReg, IndexReg, Scale, Start, End, Size);
1855 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1856 MCAsmParser &Parser = getParser();
1857 switch (getLexer().getKind()) {
1859 // Parse a memory operand with no segment register.
1860 return ParseMemOperand(0, Parser.getTok().getLoc());
1861 case AsmToken::Percent: {
1862 // Read the register.
1865 if (ParseRegister(RegNo, Start, End)) return nullptr;
1866 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1867 Error(Start, "%eiz and %riz can only be used as index registers",
1868 SMRange(Start, End));
1871 if (RegNo == X86::RIP) {
1872 Error(Start, "%rip can only be used as a base register",
1873 SMRange(Start, End));
1877 // If this is a segment register followed by a ':', then this is the start
1878 // of a memory reference, otherwise this is a normal register reference.
1879 if (getLexer().isNot(AsmToken::Colon))
1880 return X86Operand::CreateReg(RegNo, Start, End);
1882 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1883 return ErrorOperand(Start, "invalid segment register");
1885 getParser().Lex(); // Eat the colon.
1886 return ParseMemOperand(RegNo, Start);
1888 case AsmToken::Dollar: {
1889 // $42 -> immediate.
1890 SMLoc Start = Parser.getTok().getLoc(), End;
1893 if (getParser().parseExpression(Val, End))
1895 return X86Operand::CreateImm(Val, Start, End);
1897 case AsmToken::LCurly:{
1898 SMLoc Start = Parser.getTok().getLoc(), End;
1899 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
1900 return ParseRoundingModeOp(Start, End);
1901 return ErrorOperand(Start, "Unexpected '{' in expression");
1906 // true on failure, false otherwise
1907 // If no {z} mark was found - Parser doesn't advance
1908 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
1909 const SMLoc &StartLoc) {
1910 MCAsmParser &Parser = getParser();
1911 // Assuming we are just pass the '{' mark, quering the next token
1912 // Searched for {z}, but none was found. Return false, as no parsing error was
1914 if (!(getLexer().is(AsmToken::Identifier) &&
1915 (getLexer().getTok().getIdentifier() == "z")))
1917 Parser.Lex(); // Eat z
1918 // Query and eat the '}' mark
1919 if (!getLexer().is(AsmToken::RCurly))
1920 return Error(getLexer().getLoc(), "Expected } at this point");
1921 Parser.Lex(); // Eat '}'
1922 // Assign Z with the {z} mark opernad
1923 Z = X86Operand::CreateToken("{z}", StartLoc);
1927 // true on failure, false otherwise
1928 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1929 const MCParsedAsmOperand &Op) {
1930 MCAsmParser &Parser = getParser();
1931 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) {
1932 if (getLexer().is(AsmToken::LCurly)) {
1933 // Eat "{" and mark the current place.
1934 const SMLoc consumedToken = consumeToken();
1935 // Distinguish {1to<NUM>} from {%k<NUM>}.
1936 if(getLexer().is(AsmToken::Integer)) {
1937 // Parse memory broadcasting ({1to<NUM>}).
1938 if (getLexer().getTok().getIntVal() != 1)
1939 return TokError("Expected 1to<NUM> at this point");
1940 Parser.Lex(); // Eat "1" of 1to8
1941 if (!getLexer().is(AsmToken::Identifier) ||
1942 !getLexer().getTok().getIdentifier().startswith("to"))
1943 return TokError("Expected 1to<NUM> at this point");
1944 // Recognize only reasonable suffixes.
1945 const char *BroadcastPrimitive =
1946 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1947 .Case("to2", "{1to2}")
1948 .Case("to4", "{1to4}")
1949 .Case("to8", "{1to8}")
1950 .Case("to16", "{1to16}")
1952 if (!BroadcastPrimitive)
1953 return TokError("Invalid memory broadcast primitive.");
1954 Parser.Lex(); // Eat "toN" of 1toN
1955 if (!getLexer().is(AsmToken::RCurly))
1956 return TokError("Expected } at this point");
1957 Parser.Lex(); // Eat "}"
1958 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1960 // No AVX512 specific primitives can pass
1961 // after memory broadcasting, so return.
1964 // Parse either {k}{z}, {z}{k}, {k} or {z}
1965 // last one have no meaning, but GCC accepts it
1966 // Currently, we're just pass a '{' mark
1967 std::unique_ptr<X86Operand> Z;
1968 if (ParseZ(Z, consumedToken))
1970 // Reaching here means that parsing of the allegadly '{z}' mark yielded
1972 // Query for the need of further parsing for a {%k<NUM>} mark
1973 if (!Z || getLexer().is(AsmToken::LCurly)) {
1974 SMLoc StartLoc = Z ? consumeToken() : consumedToken;
1975 // Parse an op-mask register mark ({%k<NUM>}), which is now to be
1979 if (!ParseRegister(RegNo, RegLoc, StartLoc) &&
1980 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
1981 if (RegNo == X86::K0)
1982 return Error(RegLoc, "Register k0 can't be used as write mask");
1983 if (!getLexer().is(AsmToken::RCurly))
1984 return Error(getLexer().getLoc(), "Expected } at this point");
1985 Operands.push_back(X86Operand::CreateToken("{", StartLoc));
1987 X86Operand::CreateReg(RegNo, StartLoc, StartLoc));
1988 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1990 return Error(getLexer().getLoc(),
1991 "Expected an op-mask register at this point");
1992 // {%k<NUM>} mark is found, inquire for {z}
1993 if (getLexer().is(AsmToken::LCurly) && !Z) {
1994 // Have we've found a parsing error, or found no (expected) {z} mark
1995 // - report an error
1996 if (ParseZ(Z, consumeToken()) || !Z)
1997 return Error(getLexer().getLoc(),
1998 "Expected a {z} mark at this point");
2001 // '{z}' on its own is meaningless, hence should be ignored.
2002 // on the contrary - have it been accompanied by a K register,
2005 Operands.push_back(std::move(Z));
2013 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
2014 /// has already been parsed if present.
2015 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
2018 MCAsmParser &Parser = getParser();
2019 // We have to disambiguate a parenthesized expression "(4+5)" from the start
2020 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
2021 // only way to do this without lookahead is to eat the '(' and see what is
2023 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
2024 if (getLexer().isNot(AsmToken::LParen)) {
2026 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
2028 // After parsing the base expression we could either have a parenthesized
2029 // memory address or not. If not, return now. If so, eat the (.
2030 if (getLexer().isNot(AsmToken::LParen)) {
2031 // Unless we have a segment register, treat this as an immediate.
2033 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
2034 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2041 // Okay, we have a '('. We don't know if this is an expression or not, but
2042 // so we have to eat the ( to see beyond it.
2043 SMLoc LParenLoc = Parser.getTok().getLoc();
2044 Parser.Lex(); // Eat the '('.
2046 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
2047 // Nothing to do here, fall into the code below with the '(' part of the
2048 // memory operand consumed.
2051 getLexer().UnLex(AsmToken(AsmToken::LParen, "("));
2053 // It must be either an parenthesized expression, or an expression that
2054 // begins from a parenthesized expression, parse it now. Example: (1+2) or
2056 if (getParser().parseExpression(Disp, ExprEnd))
2059 // After parsing the base expression we could either have a parenthesized
2060 // memory address or not. If not, return now. If so, eat the (.
2061 if (getLexer().isNot(AsmToken::LParen)) {
2062 // Unless we have a segment register, treat this as an immediate.
2064 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
2066 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
2075 // If we reached here, then we just ate the ( of the memory operand. Process
2076 // the rest of the memory operand.
2077 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
2078 SMLoc IndexLoc, BaseLoc;
2080 if (getLexer().is(AsmToken::Percent)) {
2081 SMLoc StartLoc, EndLoc;
2082 BaseLoc = Parser.getTok().getLoc();
2083 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
2084 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
2085 Error(StartLoc, "eiz and riz can only be used as index registers",
2086 SMRange(StartLoc, EndLoc));
2091 if (getLexer().is(AsmToken::Comma)) {
2092 Parser.Lex(); // Eat the comma.
2093 IndexLoc = Parser.getTok().getLoc();
2095 // Following the comma we should have either an index register, or a scale
2096 // value. We don't support the later form, but we want to parse it
2099 // Not that even though it would be completely consistent to support syntax
2100 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
2101 if (getLexer().is(AsmToken::Percent)) {
2103 if (ParseRegister(IndexReg, L, L))
2105 if (BaseReg == X86::RIP) {
2106 Error(IndexLoc, "%rip as base register can not have an index register");
2109 if (IndexReg == X86::RIP) {
2110 Error(IndexLoc, "%rip is not allowed as an index register");
2114 if (getLexer().isNot(AsmToken::RParen)) {
2115 // Parse the scale amount:
2116 // ::= ',' [scale-expression]
2117 if (getLexer().isNot(AsmToken::Comma)) {
2118 Error(Parser.getTok().getLoc(),
2119 "expected comma in scale expression");
2122 Parser.Lex(); // Eat the comma.
2124 if (getLexer().isNot(AsmToken::RParen)) {
2125 SMLoc Loc = Parser.getTok().getLoc();
2128 if (getParser().parseAbsoluteExpression(ScaleVal)){
2129 Error(Loc, "expected scale expression");
2133 // Validate the scale amount.
2134 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2136 Error(Loc, "scale factor in 16-bit address must be 1");
2139 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2141 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2144 Scale = (unsigned)ScaleVal;
2147 } else if (getLexer().isNot(AsmToken::RParen)) {
2148 // A scale amount without an index is ignored.
2150 SMLoc Loc = Parser.getTok().getLoc();
2153 if (getParser().parseAbsoluteExpression(Value))
2157 Warning(Loc, "scale factor without index register is ignored");
2162 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2163 if (getLexer().isNot(AsmToken::RParen)) {
2164 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2167 SMLoc MemEnd = Parser.getTok().getEndLoc();
2168 Parser.Lex(); // Eat the ')'.
2170 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2171 // and then only in non-64-bit modes. Except for DX, which is a special case
2172 // because an unofficial form of in/out instructions uses it.
2173 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2174 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2175 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2176 BaseReg != X86::DX) {
2177 Error(BaseLoc, "invalid 16-bit base register");
2181 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2182 Error(IndexLoc, "16-bit memory operand may not include only index register");
2187 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) {
2188 Error(BaseLoc, ErrMsg);
2192 if (SegReg || BaseReg || IndexReg)
2193 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2194 IndexReg, Scale, MemStart, MemEnd);
2195 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2198 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2199 SMLoc NameLoc, OperandVector &Operands) {
2200 MCAsmParser &Parser = getParser();
2202 StringRef PatchedName = Name;
2204 if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) &&
2205 isParsingIntelSyntax() && isParsingInlineAsm()) {
2206 StringRef NextTok = Parser.getTok().getString();
2207 if (NextTok == "short") {
2209 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
2210 // Eat the short keyword
2212 // MS ignores the short keyword, it determines the jmp type based
2213 // on the distance of the label
2214 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
2215 NextTok.size() + 1);
2219 // FIXME: Hack to recognize setneb as setne.
2220 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2221 PatchedName != "setb" && PatchedName != "setnb")
2222 PatchedName = PatchedName.substr(0, Name.size()-1);
2224 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2225 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2226 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2227 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2228 bool IsVCMP = PatchedName[0] == 'v';
2229 unsigned CCIdx = IsVCMP ? 4 : 3;
2230 unsigned ComparisonCode = StringSwitch<unsigned>(
2231 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2233 .Case("eq_oq", 0x00)
2235 .Case("lt_os", 0x01)
2237 .Case("le_os", 0x02)
2238 .Case("unord", 0x03)
2239 .Case("unord_q", 0x03)
2241 .Case("neq_uq", 0x04)
2243 .Case("nlt_us", 0x05)
2245 .Case("nle_us", 0x06)
2247 .Case("ord_q", 0x07)
2248 /* AVX only from here */
2249 .Case("eq_uq", 0x08)
2251 .Case("nge_us", 0x09)
2253 .Case("ngt_us", 0x0A)
2254 .Case("false", 0x0B)
2255 .Case("false_oq", 0x0B)
2256 .Case("neq_oq", 0x0C)
2258 .Case("ge_os", 0x0D)
2260 .Case("gt_os", 0x0E)
2262 .Case("true_uq", 0x0F)
2263 .Case("eq_os", 0x10)
2264 .Case("lt_oq", 0x11)
2265 .Case("le_oq", 0x12)
2266 .Case("unord_s", 0x13)
2267 .Case("neq_us", 0x14)
2268 .Case("nlt_uq", 0x15)
2269 .Case("nle_uq", 0x16)
2270 .Case("ord_s", 0x17)
2271 .Case("eq_us", 0x18)
2272 .Case("nge_uq", 0x19)
2273 .Case("ngt_uq", 0x1A)
2274 .Case("false_os", 0x1B)
2275 .Case("neq_os", 0x1C)
2276 .Case("ge_oq", 0x1D)
2277 .Case("gt_oq", 0x1E)
2278 .Case("true_us", 0x1F)
2280 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2282 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2285 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2286 getParser().getContext());
2287 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2289 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2293 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2294 if (PatchedName.startswith("vpcmp") &&
2295 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2296 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2297 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2298 unsigned ComparisonCode = StringSwitch<unsigned>(
2299 PatchedName.slice(5, PatchedName.size() - CCIdx))
2300 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2303 //.Case("false", 0x3) // Not a documented alias.
2307 //.Case("true", 0x7) // Not a documented alias.
2309 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2310 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2312 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2313 getParser().getContext());
2314 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2316 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2320 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2321 if (PatchedName.startswith("vpcom") &&
2322 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2323 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2324 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2325 unsigned ComparisonCode = StringSwitch<unsigned>(
2326 PatchedName.slice(5, PatchedName.size() - CCIdx))
2336 if (ComparisonCode != ~0U) {
2337 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2339 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2340 getParser().getContext());
2341 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2343 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2348 // Determine whether this is an instruction prefix.
2350 // Enhance prefixes integrity robustness. for example, following forms
2351 // are currently tolerated:
2352 // repz repnz <insn> ; GAS errors for the use of two similar prefixes
2353 // lock addq %rax, %rbx ; Destination operand must be of memory type
2354 // xacquire <insn> ; xacquire must be accompanied by 'lock'
2355 bool isPrefix = StringSwitch<bool>(Name)
2356 .Cases("rex64", "data32", "data16", true)
2357 .Cases("xacquire", "xrelease", true)
2358 .Cases("acquire", "release", isParsingIntelSyntax())
2361 auto isLockRepeatPrefix = [](StringRef N) {
2362 return StringSwitch<bool>(N)
2363 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", true)
2367 bool CurlyAsEndOfStatement = false;
2369 unsigned Flags = X86::IP_NO_PREFIX;
2370 while (isLockRepeatPrefix(Name.lower())) {
2372 StringSwitch<unsigned>(Name)
2373 .Cases("lock", "lock", X86::IP_HAS_LOCK)
2374 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
2375 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
2376 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
2378 if (getLexer().is(AsmToken::EndOfStatement)) {
2379 // We don't have real instr with the given prefix
2380 // let's use the prefix as the instr.
2381 // TODO: there could be several prefixes one after another
2382 Flags = X86::IP_NO_PREFIX;
2385 Name = Parser.getTok().getString();
2386 Parser.Lex(); // eat the prefix
2387 // Hack: we could have something like "rep # some comment" or
2388 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
2389 while (Name.startswith(";") || Name.startswith("\n") ||
2390 Name.startswith("#") || Name.startswith("\t") ||
2391 Name.startswith("/")) {
2392 Name = Parser.getTok().getString();
2393 Parser.Lex(); // go to next prefix or instr
2399 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2401 // This does the actual operand parsing. Don't parse any more if we have a
2402 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2403 // just want to parse the "lock" as the first instruction and the "incl" as
2405 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2406 // Parse '*' modifier.
2407 if (getLexer().is(AsmToken::Star))
2408 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2410 // Read the operands.
2412 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2413 Operands.push_back(std::move(Op));
2414 if (HandleAVX512Operand(Operands, *Operands.back()))
2419 // check for comma and eat it
2420 if (getLexer().is(AsmToken::Comma))
2426 // In MS inline asm curly braces mark the beginning/end of a block,
2427 // therefore they should be interepreted as end of statement
2428 CurlyAsEndOfStatement =
2429 isParsingIntelSyntax() && isParsingInlineAsm() &&
2430 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
2431 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
2432 return TokError("unexpected token in argument list");
2435 // Consume the EndOfStatement or the prefix separator Slash
2436 if (getLexer().is(AsmToken::EndOfStatement) ||
2437 (isPrefix && getLexer().is(AsmToken::Slash)))
2439 else if (CurlyAsEndOfStatement)
2440 // Add an actual EndOfStatement before the curly brace
2441 Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
2442 getLexer().getTok().getLoc(), 0);
2444 // This is for gas compatibility and cannot be done in td.
2445 // Adding "p" for some floating point with no argument.
2446 // For example: fsub --> fsubp
2448 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
2449 if (IsFp && Operands.size() == 1) {
2450 const char *Repl = StringSwitch<const char *>(Name)
2451 .Case("fsub", "fsubp")
2452 .Case("fdiv", "fdivp")
2453 .Case("fsubr", "fsubrp")
2454 .Case("fdivr", "fdivrp");
2455 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
2458 // Moving a 32 or 16 bit value into a segment register has the same
2459 // behavior. Modify such instructions to always take shorter form.
2460 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2461 (Operands.size() == 3)) {
2462 X86Operand &Op1 = (X86Operand &)*Operands[1];
2463 X86Operand &Op2 = (X86Operand &)*Operands[2];
2464 SMLoc Loc = Op1.getEndLoc();
2465 if (Op1.isReg() && Op2.isReg() &&
2466 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2468 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2469 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2470 // Change instruction name to match new instruction.
2471 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2472 Name = is16BitMode() ? "movw" : "movl";
2473 Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2475 // Select the correct equivalent 16-/32-bit source register.
2477 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2478 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2482 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
2483 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2484 // documented form in various unofficial manuals, so a lot of code uses it.
2485 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
2486 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
2487 Operands.size() == 3) {
2488 X86Operand &Op = (X86Operand &)*Operands.back();
2489 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2490 isa<MCConstantExpr>(Op.Mem.Disp) &&
2491 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2492 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2493 SMLoc Loc = Op.getEndLoc();
2494 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2497 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
2498 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
2499 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
2500 Operands.size() == 3) {
2501 X86Operand &Op = (X86Operand &)*Operands[1];
2502 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2503 isa<MCConstantExpr>(Op.Mem.Disp) &&
2504 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2505 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2506 SMLoc Loc = Op.getEndLoc();
2507 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2511 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
2512 bool HadVerifyError = false;
2514 // Append default arguments to "ins[bwld]"
2515 if (Name.startswith("ins") &&
2516 (Operands.size() == 1 || Operands.size() == 3) &&
2517 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
2520 AddDefaultSrcDestOperands(TmpOperands,
2521 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2522 DefaultMemDIOperand(NameLoc));
2523 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2526 // Append default arguments to "outs[bwld]"
2527 if (Name.startswith("outs") &&
2528 (Operands.size() == 1 || Operands.size() == 3) &&
2529 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2530 Name == "outsd" || Name == "outs")) {
2531 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2532 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2533 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2536 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2537 // values of $SIREG according to the mode. It would be nice if this
2538 // could be achieved with InstAlias in the tables.
2539 if (Name.startswith("lods") &&
2540 (Operands.size() == 1 || Operands.size() == 2) &&
2541 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2542 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
2543 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
2544 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2547 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2548 // values of $DIREG according to the mode. It would be nice if this
2549 // could be achieved with InstAlias in the tables.
2550 if (Name.startswith("stos") &&
2551 (Operands.size() == 1 || Operands.size() == 2) &&
2552 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2553 Name == "stosl" || Name == "stosd" || Name == "stosq")) {
2554 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2555 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2558 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2559 // values of $DIREG according to the mode. It would be nice if this
2560 // could be achieved with InstAlias in the tables.
2561 if (Name.startswith("scas") &&
2562 (Operands.size() == 1 || Operands.size() == 2) &&
2563 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2564 Name == "scasl" || Name == "scasd" || Name == "scasq")) {
2565 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
2566 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2569 // Add default SI and DI operands to "cmps[bwlq]".
2570 if (Name.startswith("cmps") &&
2571 (Operands.size() == 1 || Operands.size() == 3) &&
2572 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2573 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2574 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
2575 DefaultMemSIOperand(NameLoc));
2576 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2579 // Add default SI and DI operands to "movs[bwlq]".
2580 if (((Name.startswith("movs") &&
2581 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2582 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2583 (Name.startswith("smov") &&
2584 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2585 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
2586 (Operands.size() == 1 || Operands.size() == 3)) {
2587 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
2588 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2589 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
2590 DefaultMemDIOperand(NameLoc));
2591 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
2594 // Check if we encountered an error for one the string insturctions
2595 if (HadVerifyError) {
2596 return HadVerifyError;
2599 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2601 if ((Name.startswith("shr") || Name.startswith("sar") ||
2602 Name.startswith("shl") || Name.startswith("sal") ||
2603 Name.startswith("rcl") || Name.startswith("rcr") ||
2604 Name.startswith("rol") || Name.startswith("ror")) &&
2605 Operands.size() == 3) {
2606 if (isParsingIntelSyntax()) {
2608 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2609 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2610 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2611 Operands.pop_back();
2613 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2614 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2615 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2616 Operands.erase(Operands.begin() + 1);
2620 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2621 // instalias with an immediate operand yet.
2622 if (Name == "int" && Operands.size() == 2) {
2623 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2625 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2626 if (CE->getValue() == 3) {
2627 Operands.erase(Operands.begin() + 1);
2628 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2632 // Transforms "xlat mem8" into "xlatb"
2633 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
2634 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2636 Warning(Op1.getStartLoc(), "memory operand is only for determining the "
2637 "size, (R|E)BX will be used for the location");
2638 Operands.pop_back();
2639 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
2644 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
2648 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2652 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2653 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
2655 switch (Inst.getOpcode()) {
2656 case X86::VGATHERDPDYrm:
2657 case X86::VGATHERDPDrm:
2658 case X86::VGATHERDPSYrm:
2659 case X86::VGATHERDPSrm:
2660 case X86::VGATHERQPDYrm:
2661 case X86::VGATHERQPDrm:
2662 case X86::VGATHERQPSYrm:
2663 case X86::VGATHERQPSrm:
2664 case X86::VPGATHERDDYrm:
2665 case X86::VPGATHERDDrm:
2666 case X86::VPGATHERDQYrm:
2667 case X86::VPGATHERDQrm:
2668 case X86::VPGATHERQDYrm:
2669 case X86::VPGATHERQDrm:
2670 case X86::VPGATHERQQYrm:
2671 case X86::VPGATHERQQrm: {
2672 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2673 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
2675 MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg());
2676 if (Dest == Mask || Dest == Index || Mask == Index)
2677 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
2678 "registers should be distinct");
2681 case X86::VGATHERDPDZ128rm:
2682 case X86::VGATHERDPDZ256rm:
2683 case X86::VGATHERDPDZrm:
2684 case X86::VGATHERDPSZ128rm:
2685 case X86::VGATHERDPSZ256rm:
2686 case X86::VGATHERDPSZrm:
2687 case X86::VGATHERQPDZ128rm:
2688 case X86::VGATHERQPDZ256rm:
2689 case X86::VGATHERQPDZrm:
2690 case X86::VGATHERQPSZ128rm:
2691 case X86::VGATHERQPSZ256rm:
2692 case X86::VGATHERQPSZrm:
2693 case X86::VPGATHERDDZ128rm:
2694 case X86::VPGATHERDDZ256rm:
2695 case X86::VPGATHERDDZrm:
2696 case X86::VPGATHERDQZ128rm:
2697 case X86::VPGATHERDQZ256rm:
2698 case X86::VPGATHERDQZrm:
2699 case X86::VPGATHERQDZ128rm:
2700 case X86::VPGATHERQDZ256rm:
2701 case X86::VPGATHERQDZrm:
2702 case X86::VPGATHERQQZ128rm:
2703 case X86::VPGATHERQQZ256rm:
2704 case X86::VPGATHERQQZrm: {
2705 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
2707 MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg());
2709 return Warning(Ops[0]->getStartLoc(), "index and destination registers "
2710 "should be distinct");
2718 static const char *getSubtargetFeatureName(uint64_t Val);
2720 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2722 Instrumentation->InstrumentAndEmitInstruction(
2723 Inst, Operands, getContext(), MII, Out,
2724 getParser().shouldPrintSchedInfo());
2727 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2728 OperandVector &Operands,
2729 MCStreamer &Out, uint64_t &ErrorInfo,
2730 bool MatchingInlineAsm) {
2731 if (isParsingIntelSyntax())
2732 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2734 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2738 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2739 OperandVector &Operands, MCStreamer &Out,
2740 bool MatchingInlineAsm) {
2741 // FIXME: This should be replaced with a real .td file alias mechanism.
2742 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2744 const char *Repl = StringSwitch<const char *>(Op.getToken())
2745 .Case("finit", "fninit")
2746 .Case("fsave", "fnsave")
2747 .Case("fstcw", "fnstcw")
2748 .Case("fstcww", "fnstcw")
2749 .Case("fstenv", "fnstenv")
2750 .Case("fstsw", "fnstsw")
2751 .Case("fstsww", "fnstsw")
2752 .Case("fclex", "fnclex")
2756 Inst.setOpcode(X86::WAIT);
2758 if (!MatchingInlineAsm)
2759 EmitInstruction(Inst, Operands, Out);
2760 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2764 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2765 bool MatchingInlineAsm) {
2766 assert(ErrorInfo && "Unknown missing feature!");
2767 SmallString<126> Msg;
2768 raw_svector_ostream OS(Msg);
2769 OS << "instruction requires:";
2771 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2772 if (ErrorInfo & Mask)
2773 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2776 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
2779 static unsigned getPrefixes(OperandVector &Operands) {
2780 unsigned Result = 0;
2781 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
2782 if (Prefix.isPrefix()) {
2783 Result = Prefix.getPrefix();
2784 Operands.pop_back();
2789 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2790 OperandVector &Operands,
2792 uint64_t &ErrorInfo,
2793 bool MatchingInlineAsm) {
2794 assert(!Operands.empty() && "Unexpect empty operand list!");
2795 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2796 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2797 SMRange EmptyRange = None;
2799 // First, handle aliases that expand to multiple instructions.
2800 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2802 bool WasOriginallyInvalidOperand = false;
2803 unsigned Prefixes = getPrefixes(Operands);
2808 Inst.setFlags(Prefixes);
2810 // First, try a direct match.
2811 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2812 isParsingIntelSyntax())) {
2813 default: llvm_unreachable("Unexpected match result!");
2815 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
2817 // Some instructions need post-processing to, for example, tweak which
2818 // encoding is selected. Loop on it while changes happen so the
2819 // individual transformations can chain off each other.
2820 if (!MatchingInlineAsm)
2821 while (processInstruction(Inst, Operands))
2825 if (!MatchingInlineAsm)
2826 EmitInstruction(Inst, Operands, Out);
2827 Opcode = Inst.getOpcode();
2829 case Match_MissingFeature:
2830 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2831 case Match_InvalidOperand:
2832 WasOriginallyInvalidOperand = true;
2834 case Match_MnemonicFail:
2838 // FIXME: Ideally, we would only attempt suffix matches for things which are
2839 // valid prefixes, and we could just infer the right unambiguous
2840 // type. However, that requires substantially more matcher support than the
2843 // Change the operand to point to a temporary token.
2844 StringRef Base = Op.getToken();
2845 SmallString<16> Tmp;
2848 Op.setTokenValue(Tmp);
2850 // If this instruction starts with an 'f', then it is a floating point stack
2851 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2852 // 80-bit floating point, which use the suffixes s,l,t respectively.
2854 // Otherwise, we assume that this may be an integer instruction, which comes
2855 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2856 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2858 // Check for the various suffix matches.
2859 uint64_t ErrorInfoIgnore;
2860 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2863 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2864 Tmp.back() = Suffixes[I];
2865 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2866 MatchingInlineAsm, isParsingIntelSyntax());
2867 // If this returned as a missing feature failure, remember that.
2868 if (Match[I] == Match_MissingFeature)
2869 ErrorInfoMissingFeature = ErrorInfoIgnore;
2872 // Restore the old token.
2873 Op.setTokenValue(Base);
2875 // If exactly one matched, then we treat that as a successful match (and the
2876 // instruction will already have been filled in correctly, since the failing
2877 // matches won't have modified it).
2878 unsigned NumSuccessfulMatches =
2879 std::count(std::begin(Match), std::end(Match), Match_Success);
2880 if (NumSuccessfulMatches == 1) {
2882 if (!MatchingInlineAsm)
2883 EmitInstruction(Inst, Operands, Out);
2884 Opcode = Inst.getOpcode();
2888 // Otherwise, the match failed, try to produce a decent error message.
2890 // If we had multiple suffix matches, then identify this as an ambiguous
2892 if (NumSuccessfulMatches > 1) {
2894 unsigned NumMatches = 0;
2895 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2896 if (Match[I] == Match_Success)
2897 MatchChars[NumMatches++] = Suffixes[I];
2899 SmallString<126> Msg;
2900 raw_svector_ostream OS(Msg);
2901 OS << "ambiguous instructions require an explicit suffix (could be ";
2902 for (unsigned i = 0; i != NumMatches; ++i) {
2905 if (i + 1 == NumMatches)
2907 OS << "'" << Base << MatchChars[i] << "'";
2910 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
2914 // Okay, we know that none of the variants matched successfully.
2916 // If all of the instructions reported an invalid mnemonic, then the original
2917 // mnemonic was invalid.
2918 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2919 if (!WasOriginallyInvalidOperand) {
2920 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2921 Op.getLocRange(), MatchingInlineAsm);
2924 // Recover location info for the operand if we know which was the problem.
2925 if (ErrorInfo != ~0ULL) {
2926 if (ErrorInfo >= Operands.size())
2927 return Error(IDLoc, "too few operands for instruction", EmptyRange,
2930 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2931 if (Operand.getStartLoc().isValid()) {
2932 SMRange OperandRange = Operand.getLocRange();
2933 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2934 OperandRange, MatchingInlineAsm);
2938 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
2942 // If one instruction matched with a missing feature, report this as a
2944 if (std::count(std::begin(Match), std::end(Match),
2945 Match_MissingFeature) == 1) {
2946 ErrorInfo = ErrorInfoMissingFeature;
2947 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2951 // If one instruction matched with an invalid operand, report this as an
2953 if (std::count(std::begin(Match), std::end(Match),
2954 Match_InvalidOperand) == 1) {
2955 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
2959 // If all of these were an outright failure, report it in a useless way.
2960 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2961 EmptyRange, MatchingInlineAsm);
2965 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2966 OperandVector &Operands,
2968 uint64_t &ErrorInfo,
2969 bool MatchingInlineAsm) {
2970 assert(!Operands.empty() && "Unexpect empty operand list!");
2971 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2972 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2973 StringRef Mnemonic = Op.getToken();
2974 SMRange EmptyRange = None;
2975 StringRef Base = Op.getToken();
2976 unsigned Prefixes = getPrefixes(Operands);
2978 // First, handle aliases that expand to multiple instructions.
2979 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2984 Inst.setFlags(Prefixes);
2986 // Find one unsized memory operand, if present.
2987 X86Operand *UnsizedMemOp = nullptr;
2988 for (const auto &Op : Operands) {
2989 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2990 if (X86Op->isMemUnsized()) {
2991 UnsizedMemOp = X86Op;
2992 // Have we found an unqualified memory operand,
2993 // break. IA allows only one memory operand.
2998 // Allow some instructions to have implicitly pointer-sized operands. This is
2999 // compatible with gas.
3001 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
3002 for (const char *Instr : PtrSizedInstrs) {
3003 if (Mnemonic == Instr) {
3004 UnsizedMemOp->Mem.Size = getPointerWidth();
3010 SmallVector<unsigned, 8> Match;
3011 uint64_t ErrorInfoMissingFeature = 0;
3013 // If unsized push has immediate operand we should default the default pointer
3014 // size for the size.
3015 if (Mnemonic == "push" && Operands.size() == 2) {
3016 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
3017 if (X86Op->isImm()) {
3018 // If it's not a constant fall through and let remainder take care of it.
3019 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
3020 unsigned Size = getPointerWidth();
3022 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
3023 SmallString<16> Tmp;
3025 Tmp += (is64BitMode())
3027 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
3028 Op.setTokenValue(Tmp);
3029 // Do match in ATT mode to allow explicit suffix usage.
3030 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
3032 false /*isParsingIntelSyntax()*/));
3033 Op.setTokenValue(Base);
3038 // If an unsized memory operand is present, try to match with each memory
3039 // operand size. In Intel assembly, the size is not part of the instruction
3041 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
3042 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
3043 for (unsigned Size : MopSizes) {
3044 UnsizedMemOp->Mem.Size = Size;
3045 uint64_t ErrorInfoIgnore;
3046 unsigned LastOpcode = Inst.getOpcode();
3047 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3048 MatchingInlineAsm, isParsingIntelSyntax());
3049 if (Match.empty() || LastOpcode != Inst.getOpcode())
3052 // If this returned as a missing feature failure, remember that.
3053 if (Match.back() == Match_MissingFeature)
3054 ErrorInfoMissingFeature = ErrorInfoIgnore;
3057 // Restore the size of the unsized memory operand if we modified it.
3058 UnsizedMemOp->Mem.Size = 0;
3061 // If we haven't matched anything yet, this is not a basic integer or FPU
3062 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
3063 // matching with the unsized operand.
3064 if (Match.empty()) {
3065 Match.push_back(MatchInstruction(
3066 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3067 // If this returned as a missing feature failure, remember that.
3068 if (Match.back() == Match_MissingFeature)
3069 ErrorInfoMissingFeature = ErrorInfo;
3072 // Restore the size of the unsized memory operand if we modified it.
3074 UnsizedMemOp->Mem.Size = 0;
3076 // If it's a bad mnemonic, all results will be the same.
3077 if (Match.back() == Match_MnemonicFail) {
3078 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
3079 Op.getLocRange(), MatchingInlineAsm);
3082 unsigned NumSuccessfulMatches =
3083 std::count(std::begin(Match), std::end(Match), Match_Success);
3085 // If matching was ambiguous and we had size information from the frontend,
3086 // try again with that. This handles cases like "movxz eax, m8/m16".
3087 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
3088 UnsizedMemOp->getMemFrontendSize()) {
3089 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
3090 unsigned M = MatchInstruction(
3091 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3092 if (M == Match_Success)
3093 NumSuccessfulMatches = 1;
3095 // Add a rewrite that encodes the size information we used from the
3097 InstInfo->AsmRewrites->emplace_back(
3098 AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
3099 /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
3102 // If exactly one matched, then we treat that as a successful match (and the
3103 // instruction will already have been filled in correctly, since the failing
3104 // matches won't have modified it).
3105 if (NumSuccessfulMatches == 1) {
3106 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
3108 // Some instructions need post-processing to, for example, tweak which
3109 // encoding is selected. Loop on it while changes happen so the individual
3110 // transformations can chain off each other.
3111 if (!MatchingInlineAsm)
3112 while (processInstruction(Inst, Operands))
3115 if (!MatchingInlineAsm)
3116 EmitInstruction(Inst, Operands, Out);
3117 Opcode = Inst.getOpcode();
3119 } else if (NumSuccessfulMatches > 1) {
3120 assert(UnsizedMemOp &&
3121 "multiple matches only possible with unsized memory operands");
3122 return Error(UnsizedMemOp->getStartLoc(),
3123 "ambiguous operand size for instruction '" + Mnemonic + "\'",
3124 UnsizedMemOp->getLocRange());
3127 // If one instruction matched with a missing feature, report this as a
3129 if (std::count(std::begin(Match), std::end(Match),
3130 Match_MissingFeature) == 1) {
3131 ErrorInfo = ErrorInfoMissingFeature;
3132 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3136 // If one instruction matched with an invalid operand, report this as an
3138 if (std::count(std::begin(Match), std::end(Match),
3139 Match_InvalidOperand) == 1) {
3140 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
3144 // If all of these were an outright failure, report it in a useless way.
3145 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
3149 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
3150 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
3153 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
3154 MCAsmParser &Parser = getParser();
3155 StringRef IDVal = DirectiveID.getIdentifier();
3156 if (IDVal == ".word")
3157 return ParseDirectiveWord(2, DirectiveID.getLoc());
3158 else if (IDVal.startswith(".code"))
3159 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
3160 else if (IDVal.startswith(".att_syntax")) {
3161 getParser().setParsingInlineAsm(false);
3162 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3163 if (Parser.getTok().getString() == "prefix")
3165 else if (Parser.getTok().getString() == "noprefix")
3166 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
3167 "supported: registers must have a "
3168 "'%' prefix in .att_syntax");
3170 getParser().setAssemblerDialect(0);
3172 } else if (IDVal.startswith(".intel_syntax")) {
3173 getParser().setAssemblerDialect(1);
3174 getParser().setParsingInlineAsm(true);
3175 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3176 if (Parser.getTok().getString() == "noprefix")
3178 else if (Parser.getTok().getString() == "prefix")
3179 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
3180 "supported: registers must not have "
3181 "a '%' prefix in .intel_syntax");
3184 } else if (IDVal == ".even")
3185 return parseDirectiveEven(DirectiveID.getLoc());
3186 else if (IDVal == ".cv_fpo_proc")
3187 return parseDirectiveFPOProc(DirectiveID.getLoc());
3188 else if (IDVal == ".cv_fpo_setframe")
3189 return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
3190 else if (IDVal == ".cv_fpo_pushreg")
3191 return parseDirectiveFPOPushReg(DirectiveID.getLoc());
3192 else if (IDVal == ".cv_fpo_stackalloc")
3193 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
3194 else if (IDVal == ".cv_fpo_endprologue")
3195 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
3196 else if (IDVal == ".cv_fpo_endproc")
3197 return parseDirectiveFPOEndProc(DirectiveID.getLoc());
3202 /// parseDirectiveEven
3204 bool X86AsmParser::parseDirectiveEven(SMLoc L) {
3205 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3206 TokError("unexpected token in directive");
3209 const MCSection *Section = getStreamer().getCurrentSectionOnly();
3211 getStreamer().InitSections(false);
3212 Section = getStreamer().getCurrentSectionOnly();
3214 if (Section->UseCodeAlign())
3215 getStreamer().EmitCodeAlignment(2, 0);
3217 getStreamer().EmitValueToAlignment(2, 0, 1, 0);
3220 /// ParseDirectiveWord
3221 /// ::= .word [ expression (, expression)* ]
3222 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
3223 MCAsmParser &Parser = getParser();
3224 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3226 const MCExpr *Value;
3227 SMLoc ExprLoc = getLexer().getLoc();
3228 if (getParser().parseExpression(Value))
3231 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
3232 assert(Size <= 8 && "Invalid size");
3233 uint64_t IntValue = MCE->getValue();
3234 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3235 return Error(ExprLoc, "literal value out of range for directive");
3236 getStreamer().EmitIntValue(IntValue, Size);
3238 getStreamer().EmitValue(Value, Size, ExprLoc);
3241 if (getLexer().is(AsmToken::EndOfStatement))
3244 // FIXME: Improve diagnostic.
3245 if (getLexer().isNot(AsmToken::Comma)) {
3246 Error(L, "unexpected token in directive");
3257 /// ParseDirectiveCode
3258 /// ::= .code16 | .code32 | .code64
3259 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
3260 MCAsmParser &Parser = getParser();
3262 if (IDVal == ".code16") {
3264 if (!is16BitMode()) {
3265 SwitchMode(X86::Mode16Bit);
3266 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3268 } else if (IDVal == ".code16gcc") {
3269 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
3272 if (!is16BitMode()) {
3273 SwitchMode(X86::Mode16Bit);
3274 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3276 } else if (IDVal == ".code32") {
3278 if (!is32BitMode()) {
3279 SwitchMode(X86::Mode32Bit);
3280 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3282 } else if (IDVal == ".code64") {
3284 if (!is64BitMode()) {
3285 SwitchMode(X86::Mode64Bit);
3286 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
3289 Error(L, "unknown directive " + IDVal);
3297 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
3298 MCAsmParser &Parser = getParser();
3301 if (Parser.parseIdentifier(ProcName))
3302 return Parser.TokError("expected symbol name");
3303 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
3305 if (!isUIntN(32, ParamsSize))
3306 return Parser.TokError("parameters size out of range");
3307 if (Parser.parseEOL("unexpected tokens"))
3308 return addErrorSuffix(" in '.cv_fpo_proc' directive");
3309 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3310 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
3313 // .cv_fpo_setframe ebp
3314 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
3315 MCAsmParser &Parser = getParser();
3318 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3319 Parser.parseEOL("unexpected tokens"))
3320 return addErrorSuffix(" in '.cv_fpo_setframe' directive");
3321 return getTargetStreamer().emitFPOSetFrame(Reg, L);
3324 // .cv_fpo_pushreg ebx
3325 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
3326 MCAsmParser &Parser = getParser();
3329 if (ParseRegister(Reg, DummyLoc, DummyLoc) ||
3330 Parser.parseEOL("unexpected tokens"))
3331 return addErrorSuffix(" in '.cv_fpo_pushreg' directive");
3332 return getTargetStreamer().emitFPOPushReg(Reg, L);
3335 // .cv_fpo_stackalloc 20
3336 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
3337 MCAsmParser &Parser = getParser();
3339 if (Parser.parseIntToken(Offset, "expected offset") ||
3340 Parser.parseEOL("unexpected tokens"))
3341 return addErrorSuffix(" in '.cv_fpo_stackalloc' directive");
3342 return getTargetStreamer().emitFPOStackAlloc(Offset, L);
3345 // .cv_fpo_endprologue
3346 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
3347 MCAsmParser &Parser = getParser();
3348 if (Parser.parseEOL("unexpected tokens"))
3349 return addErrorSuffix(" in '.cv_fpo_endprologue' directive");
3350 return getTargetStreamer().emitFPOEndPrologue(L);
3354 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
3355 MCAsmParser &Parser = getParser();
3356 if (Parser.parseEOL("unexpected tokens"))
3357 return addErrorSuffix(" in '.cv_fpo_endproc' directive");
3358 return getTargetStreamer().emitFPOEndProc(L);
3361 // Force static initialization.
3362 extern "C" void LLVMInitializeX86AsmParser() {
3363 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target());
3364 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target());
3367 #define GET_REGISTER_MATCHER
3368 #define GET_MATCHER_IMPLEMENTATION
3369 #define GET_SUBTARGET_FEATURE_NAME
3370 #include "X86GenAsmMatcher.inc"