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 "MCTargetDesc/X86BaseInfo.h"
11 #include "X86AsmInstrumentation.h"
12 #include "X86AsmParserCommon.h"
13 #include "X86Operand.h"
14 #include "X86ISelLowering.h"
15 #include "llvm/ADT/APFloat.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/MCRegisterInfo.h"
29 #include "llvm/MC/MCStreamer.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/MC/MCSymbol.h"
32 #include "llvm/MC/MCTargetAsmParser.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include "llvm/Support/raw_ostream.h"
43 static const char OpPrecedence[] = {
58 class X86AsmParser : public MCTargetAsmParser {
60 const MCInstrInfo &MII;
61 ParseInstructionInfo *InstInfo;
62 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
64 SMLoc consumeToken() {
65 MCAsmParser &Parser = getParser();
66 SMLoc Result = Parser.getTok().getLoc();
71 enum InfixCalculatorTok {
86 class InfixCalculator {
87 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
88 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
89 SmallVector<ICToken, 4> PostfixStack;
92 int64_t popOperand() {
93 assert (!PostfixStack.empty() && "Poped an empty stack!");
94 ICToken Op = PostfixStack.pop_back_val();
95 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
96 && "Expected and immediate or register!");
99 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
100 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
101 "Unexpected operand!");
102 PostfixStack.push_back(std::make_pair(Op, Val));
105 void popOperator() { InfixOperatorStack.pop_back(); }
106 void pushOperator(InfixCalculatorTok Op) {
107 // Push the new operator if the stack is empty.
108 if (InfixOperatorStack.empty()) {
109 InfixOperatorStack.push_back(Op);
113 // Push the new operator if it has a higher precedence than the operator
114 // on the top of the stack or the operator on the top of the stack is a
116 unsigned Idx = InfixOperatorStack.size() - 1;
117 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
118 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
119 InfixOperatorStack.push_back(Op);
123 // The operator on the top of the stack has higher precedence than the
125 unsigned ParenCount = 0;
127 // Nothing to process.
128 if (InfixOperatorStack.empty())
131 Idx = InfixOperatorStack.size() - 1;
132 StackOp = InfixOperatorStack[Idx];
133 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
136 // If we have an even parentheses count and we see a left parentheses,
137 // then stop processing.
138 if (!ParenCount && StackOp == IC_LPAREN)
141 if (StackOp == IC_RPAREN) {
143 InfixOperatorStack.pop_back();
144 } else if (StackOp == IC_LPAREN) {
146 InfixOperatorStack.pop_back();
148 InfixOperatorStack.pop_back();
149 PostfixStack.push_back(std::make_pair(StackOp, 0));
152 // Push the new operator.
153 InfixOperatorStack.push_back(Op);
156 // Push any remaining operators onto the postfix stack.
157 while (!InfixOperatorStack.empty()) {
158 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
159 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
160 PostfixStack.push_back(std::make_pair(StackOp, 0));
163 if (PostfixStack.empty())
166 SmallVector<ICToken, 16> OperandStack;
167 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
168 ICToken Op = PostfixStack[i];
169 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
170 OperandStack.push_back(Op);
172 assert (OperandStack.size() > 1 && "Too few operands.");
174 ICToken Op2 = OperandStack.pop_back_val();
175 ICToken Op1 = OperandStack.pop_back_val();
178 report_fatal_error("Unexpected operator!");
181 Val = Op1.second + Op2.second;
182 OperandStack.push_back(std::make_pair(IC_IMM, Val));
185 Val = Op1.second - Op2.second;
186 OperandStack.push_back(std::make_pair(IC_IMM, Val));
189 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
190 "Multiply operation with an immediate and a register!");
191 Val = Op1.second * Op2.second;
192 OperandStack.push_back(std::make_pair(IC_IMM, Val));
195 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
196 "Divide operation with an immediate and a register!");
197 assert (Op2.second != 0 && "Division by zero!");
198 Val = Op1.second / Op2.second;
199 OperandStack.push_back(std::make_pair(IC_IMM, Val));
202 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
203 "Or operation with an immediate and a register!");
204 Val = Op1.second | Op2.second;
205 OperandStack.push_back(std::make_pair(IC_IMM, Val));
208 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
209 "And operation with an immediate and a register!");
210 Val = Op1.second & Op2.second;
211 OperandStack.push_back(std::make_pair(IC_IMM, Val));
214 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
215 "Left shift operation with an immediate and a register!");
216 Val = Op1.second << Op2.second;
217 OperandStack.push_back(std::make_pair(IC_IMM, Val));
220 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
221 "Right shift operation with an immediate and a register!");
222 Val = Op1.second >> Op2.second;
223 OperandStack.push_back(std::make_pair(IC_IMM, Val));
228 assert (OperandStack.size() == 1 && "Expected a single result.");
229 return OperandStack.pop_back_val().second;
233 enum IntelExprState {
253 class IntelExprStateMachine {
254 IntelExprState State, PrevState;
255 unsigned BaseReg, IndexReg, TmpReg, Scale;
259 bool StopOnLBrac, AddImmPrefix;
261 InlineAsmIdentifierInfo Info;
263 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
264 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
265 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
266 AddImmPrefix(addimmprefix) { Info.clear(); }
268 unsigned getBaseReg() { return BaseReg; }
269 unsigned getIndexReg() { return IndexReg; }
270 unsigned getScale() { return Scale; }
271 const MCExpr *getSym() { return Sym; }
272 StringRef getSymName() { return SymName; }
273 int64_t getImm() { return Imm + IC.execute(); }
274 bool isValidEndState() {
275 return State == IES_RBRAC || State == IES_INTEGER;
277 bool getStopOnLBrac() { return StopOnLBrac; }
278 bool getAddImmPrefix() { return AddImmPrefix; }
279 bool hadError() { return State == IES_ERROR; }
281 InlineAsmIdentifierInfo &getIdentifierInfo() {
286 IntelExprState CurrState = State;
295 IC.pushOperator(IC_OR);
298 PrevState = CurrState;
301 IntelExprState CurrState = State;
310 IC.pushOperator(IC_AND);
313 PrevState = CurrState;
316 IntelExprState CurrState = State;
325 IC.pushOperator(IC_LSHIFT);
328 PrevState = CurrState;
331 IntelExprState CurrState = State;
340 IC.pushOperator(IC_RSHIFT);
343 PrevState = CurrState;
346 IntelExprState CurrState = State;
355 IC.pushOperator(IC_PLUS);
356 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
357 // If we already have a BaseReg, then assume this is the IndexReg with
362 assert (!IndexReg && "BaseReg/IndexReg already set!");
369 PrevState = CurrState;
372 IntelExprState CurrState = State;
388 // Only push the minus operator if it is not a unary operator.
389 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
390 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
391 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
392 IC.pushOperator(IC_MINUS);
393 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
394 // If we already have a BaseReg, then assume this is the IndexReg with
399 assert (!IndexReg && "BaseReg/IndexReg already set!");
406 PrevState = CurrState;
409 IntelExprState CurrState = State;
419 PrevState = CurrState;
421 void onRegister(unsigned Reg) {
422 IntelExprState CurrState = State;
429 State = IES_REGISTER;
431 IC.pushOperand(IC_REGISTER);
434 // Index Register - Scale * Register
435 if (PrevState == IES_INTEGER) {
436 assert (!IndexReg && "IndexReg already set!");
437 State = IES_REGISTER;
439 // Get the scale and replace the 'Scale * Register' with '0'.
440 Scale = IC.popOperand();
441 IC.pushOperand(IC_IMM);
448 PrevState = CurrState;
450 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
461 SymName = SymRefName;
462 IC.pushOperand(IC_IMM);
466 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
467 IntelExprState CurrState = State;
483 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
484 // Index Register - Register * Scale
485 assert (!IndexReg && "IndexReg already set!");
488 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
489 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
492 // Get the scale and replace the 'Register * Scale' with '0'.
494 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
495 PrevState == IES_OR || PrevState == IES_AND ||
496 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
497 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
498 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
499 PrevState == IES_NOT) &&
500 CurrState == IES_MINUS) {
501 // Unary minus. No need to pop the minus operand because it was never
503 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
504 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
505 PrevState == IES_OR || PrevState == IES_AND ||
506 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
507 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
508 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
509 PrevState == IES_NOT) &&
510 CurrState == IES_NOT) {
511 // Unary not. No need to pop the not operand because it was never
513 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
515 IC.pushOperand(IC_IMM, TmpInt);
519 PrevState = CurrState;
531 State = IES_MULTIPLY;
532 IC.pushOperator(IC_MULTIPLY);
545 IC.pushOperator(IC_DIVIDE);
557 IC.pushOperator(IC_PLUS);
562 IntelExprState CurrState = State;
571 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
572 // If we already have a BaseReg, then assume this is the IndexReg with
577 assert (!IndexReg && "BaseReg/IndexReg already set!");
584 PrevState = CurrState;
587 IntelExprState CurrState = State;
602 // FIXME: We don't handle this type of unary minus or not, yet.
603 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
604 PrevState == IES_OR || PrevState == IES_AND ||
605 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
606 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
607 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
608 PrevState == IES_NOT) &&
609 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
614 IC.pushOperator(IC_LPAREN);
617 PrevState = CurrState;
629 IC.pushOperator(IC_RPAREN);
635 bool Error(SMLoc L, const Twine &Msg,
636 ArrayRef<SMRange> Ranges = None,
637 bool MatchingInlineAsm = false) {
638 MCAsmParser &Parser = getParser();
639 if (MatchingInlineAsm) return true;
640 return Parser.Error(L, Msg, Ranges);
643 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
644 ArrayRef<SMRange> Ranges = None,
645 bool MatchingInlineAsm = false) {
646 MCAsmParser &Parser = getParser();
647 Parser.eatToEndOfStatement();
648 return Error(L, Msg, Ranges, MatchingInlineAsm);
651 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
656 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
657 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
658 std::unique_ptr<X86Operand> ParseOperand();
659 std::unique_ptr<X86Operand> ParseATTOperand();
660 std::unique_ptr<X86Operand> ParseIntelOperand();
661 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
662 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
663 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
664 std::unique_ptr<X86Operand>
665 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
666 std::unique_ptr<X86Operand>
667 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
668 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
669 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
670 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
674 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
675 InlineAsmIdentifierInfo &Info,
676 bool IsUnevaluatedOperand, SMLoc &End);
678 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
680 std::unique_ptr<X86Operand>
681 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
682 unsigned IndexReg, unsigned Scale, SMLoc Start,
683 SMLoc End, unsigned Size, StringRef Identifier,
684 InlineAsmIdentifierInfo &Info);
686 bool ParseDirectiveWord(unsigned Size, SMLoc L);
687 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
689 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
690 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
692 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
693 /// instrumentation around Inst.
694 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
696 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
697 OperandVector &Operands, MCStreamer &Out,
699 bool MatchingInlineAsm) override;
701 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
702 MCStreamer &Out, bool MatchingInlineAsm);
704 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
705 bool MatchingInlineAsm);
707 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
708 OperandVector &Operands, MCStreamer &Out,
710 bool MatchingInlineAsm);
712 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
713 OperandVector &Operands, MCStreamer &Out,
715 bool MatchingInlineAsm);
717 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
719 /// doSrcDstMatch - Returns true if operands are matching in their
720 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
721 /// the parsing mode (Intel vs. AT&T).
722 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
724 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
725 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
726 /// \return \c true if no parsing errors occurred, \c false otherwise.
727 bool HandleAVX512Operand(OperandVector &Operands,
728 const MCParsedAsmOperand &Op);
730 bool is64BitMode() const {
731 // FIXME: Can tablegen auto-generate this?
732 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
734 bool is32BitMode() const {
735 // FIXME: Can tablegen auto-generate this?
736 return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
738 bool is16BitMode() const {
739 // FIXME: Can tablegen auto-generate this?
740 return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
742 void SwitchMode(uint64_t mode) {
743 uint64_t oldMode = STI.getFeatureBits() &
744 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit);
745 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(oldMode | mode));
746 setAvailableFeatures(FB);
747 assert(mode == (STI.getFeatureBits() &
748 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit)));
751 unsigned getPointerWidth() {
752 if (is16BitMode()) return 16;
753 if (is32BitMode()) return 32;
754 if (is64BitMode()) return 64;
755 llvm_unreachable("invalid mode");
758 bool isParsingIntelSyntax() {
759 return getParser().getAssemblerDialect();
762 /// @name Auto-generated Matcher Functions
765 #define GET_ASSEMBLER_HEADER
766 #include "X86GenAsmMatcher.inc"
771 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &Parser,
772 const MCInstrInfo &mii, const MCTargetOptions &Options)
773 : MCTargetAsmParser(), STI(sti), MII(mii), InstInfo(nullptr) {
775 // Initialize the set of available features.
776 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
777 Instrumentation.reset(
778 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
781 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
783 void SetFrameRegister(unsigned RegNo) override;
785 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
786 SMLoc NameLoc, OperandVector &Operands) override;
788 bool ParseDirective(AsmToken DirectiveID) override;
790 } // end anonymous namespace
792 /// @name Auto-generated Match Functions
795 static unsigned MatchRegisterName(StringRef Name);
799 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
801 // If we have both a base register and an index register make sure they are
802 // both 64-bit or 32-bit registers.
803 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
804 if (BaseReg != 0 && IndexReg != 0) {
805 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
806 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
807 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
808 IndexReg != X86::RIZ) {
809 ErrMsg = "base register is 64-bit, but index register is not";
812 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
813 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
814 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
815 IndexReg != X86::EIZ){
816 ErrMsg = "base register is 32-bit, but index register is not";
819 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
820 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
821 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
822 ErrMsg = "base register is 16-bit, but index register is not";
825 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
826 IndexReg != X86::SI && IndexReg != X86::DI) ||
827 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
828 IndexReg != X86::BX && IndexReg != X86::BP)) {
829 ErrMsg = "invalid 16-bit base/index register combination";
837 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
839 // Return true and let a normal complaint about bogus operands happen.
840 if (!Op1.isMem() || !Op2.isMem())
843 // Actually these might be the other way round if Intel syntax is
844 // being used. It doesn't matter.
845 unsigned diReg = Op1.Mem.BaseReg;
846 unsigned siReg = Op2.Mem.BaseReg;
848 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
849 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
850 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
851 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
852 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
853 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
854 // Again, return true and let another error happen.
858 bool X86AsmParser::ParseRegister(unsigned &RegNo,
859 SMLoc &StartLoc, SMLoc &EndLoc) {
860 MCAsmParser &Parser = getParser();
862 const AsmToken &PercentTok = Parser.getTok();
863 StartLoc = PercentTok.getLoc();
865 // If we encounter a %, ignore it. This code handles registers with and
866 // without the prefix, unprefixed registers can occur in cfi directives.
867 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
868 Parser.Lex(); // Eat percent token.
870 const AsmToken &Tok = Parser.getTok();
871 EndLoc = Tok.getEndLoc();
873 if (Tok.isNot(AsmToken::Identifier)) {
874 if (isParsingIntelSyntax()) return true;
875 return Error(StartLoc, "invalid register name",
876 SMRange(StartLoc, EndLoc));
879 RegNo = MatchRegisterName(Tok.getString());
881 // If the match failed, try the register name as lowercase.
883 RegNo = MatchRegisterName(Tok.getString().lower());
885 if (!is64BitMode()) {
886 // FIXME: This should be done using Requires<Not64BitMode> and
887 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
889 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
891 if (RegNo == X86::RIZ ||
892 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
893 X86II::isX86_64NonExtLowByteReg(RegNo) ||
894 X86II::isX86_64ExtendedReg(RegNo))
895 return Error(StartLoc, "register %"
896 + Tok.getString() + " is only available in 64-bit mode",
897 SMRange(StartLoc, EndLoc));
900 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
901 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
903 Parser.Lex(); // Eat 'st'
905 // Check to see if we have '(4)' after %st.
906 if (getLexer().isNot(AsmToken::LParen))
911 const AsmToken &IntTok = Parser.getTok();
912 if (IntTok.isNot(AsmToken::Integer))
913 return Error(IntTok.getLoc(), "expected stack index");
914 switch (IntTok.getIntVal()) {
915 case 0: RegNo = X86::ST0; break;
916 case 1: RegNo = X86::ST1; break;
917 case 2: RegNo = X86::ST2; break;
918 case 3: RegNo = X86::ST3; break;
919 case 4: RegNo = X86::ST4; break;
920 case 5: RegNo = X86::ST5; break;
921 case 6: RegNo = X86::ST6; break;
922 case 7: RegNo = X86::ST7; break;
923 default: return Error(IntTok.getLoc(), "invalid stack index");
926 if (getParser().Lex().isNot(AsmToken::RParen))
927 return Error(Parser.getTok().getLoc(), "expected ')'");
929 EndLoc = Parser.getTok().getEndLoc();
930 Parser.Lex(); // Eat ')'
934 EndLoc = Parser.getTok().getEndLoc();
936 // If this is "db[0-7]", match it as an alias
938 if (RegNo == 0 && Tok.getString().size() == 3 &&
939 Tok.getString().startswith("db")) {
940 switch (Tok.getString()[2]) {
941 case '0': RegNo = X86::DR0; break;
942 case '1': RegNo = X86::DR1; break;
943 case '2': RegNo = X86::DR2; break;
944 case '3': RegNo = X86::DR3; break;
945 case '4': RegNo = X86::DR4; break;
946 case '5': RegNo = X86::DR5; break;
947 case '6': RegNo = X86::DR6; break;
948 case '7': RegNo = X86::DR7; break;
952 EndLoc = Parser.getTok().getEndLoc();
953 Parser.Lex(); // Eat it.
959 if (isParsingIntelSyntax()) return true;
960 return Error(StartLoc, "invalid register name",
961 SMRange(StartLoc, EndLoc));
964 Parser.Lex(); // Eat identifier token.
968 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
969 Instrumentation->SetInitialFrameRegister(RegNo);
972 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
974 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
975 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
976 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
977 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
981 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
983 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
984 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
985 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
986 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
990 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
991 if (isParsingIntelSyntax())
992 return ParseIntelOperand();
993 return ParseATTOperand();
996 /// getIntelMemOperandSize - Return intel memory operand size.
997 static unsigned getIntelMemOperandSize(StringRef OpStr) {
998 unsigned Size = StringSwitch<unsigned>(OpStr)
999 .Cases("BYTE", "byte", 8)
1000 .Cases("WORD", "word", 16)
1001 .Cases("DWORD", "dword", 32)
1002 .Cases("QWORD", "qword", 64)
1003 .Cases("XWORD", "xword", 80)
1004 .Cases("XMMWORD", "xmmword", 128)
1005 .Cases("YMMWORD", "ymmword", 256)
1006 .Cases("ZMMWORD", "zmmword", 512)
1007 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1012 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1013 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1014 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1015 InlineAsmIdentifierInfo &Info) {
1016 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1017 // some other label reference.
1018 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1019 // Insert an explicit size if the user didn't have one.
1021 Size = getPointerWidth();
1022 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1026 // Create an absolute memory reference in order to match against
1027 // instructions taking a PC relative operand.
1028 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1029 Identifier, Info.OpDecl);
1032 // We either have a direct symbol reference, or an offset from a symbol. The
1033 // parser always puts the symbol on the LHS, so look there for size
1034 // calculation purposes.
1035 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1037 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1040 Size = Info.Type * 8; // Size is in terms of bits in this context.
1042 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1047 // When parsing inline assembly we set the base register to a non-zero value
1048 // if we don't know the actual value at this time. This is necessary to
1049 // get the matching correct in some cases.
1050 BaseReg = BaseReg ? BaseReg : 1;
1051 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1052 IndexReg, Scale, Start, End, Size, Identifier,
1057 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
1058 StringRef SymName, int64_t ImmDisp,
1059 int64_t FinalImmDisp, SMLoc &BracLoc,
1060 SMLoc &StartInBrac, SMLoc &End) {
1061 // Remove the '[' and ']' from the IR string.
1062 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1063 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
1065 // If ImmDisp is non-zero, then we parsed a displacement before the
1066 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1067 // If ImmDisp doesn't match the displacement computed by the state machine
1068 // then we have an additional displacement in the bracketed expression.
1069 if (ImmDisp != FinalImmDisp) {
1071 // We have an immediate displacement before the bracketed expression.
1072 // Adjust this to match the final immediate displacement.
1074 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1075 E = AsmRewrites->end(); I != E; ++I) {
1076 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1078 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1079 assert (!Found && "ImmDisp already rewritten.");
1080 (*I).Kind = AOK_Imm;
1081 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1082 (*I).Val = FinalImmDisp;
1087 assert (Found && "Unable to rewrite ImmDisp.");
1090 // We have a symbolic and an immediate displacement, but no displacement
1091 // before the bracketed expression. Put the immediate displacement
1092 // before the bracketed expression.
1093 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1096 // Remove all the ImmPrefix rewrites within the brackets.
1097 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1098 E = AsmRewrites->end(); I != E; ++I) {
1099 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1101 if ((*I).Kind == AOK_ImmPrefix)
1102 (*I).Kind = AOK_Delete;
1104 const char *SymLocPtr = SymName.data();
1105 // Skip everything before the symbol.
1106 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1107 assert(Len > 0 && "Expected a non-negative length.");
1108 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1110 // Skip everything after the symbol.
1111 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1112 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1113 assert(Len > 0 && "Expected a non-negative length.");
1114 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1118 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1119 MCAsmParser &Parser = getParser();
1120 const AsmToken &Tok = Parser.getTok();
1124 bool UpdateLocLex = true;
1126 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1127 // identifier. Don't try an parse it as a register.
1128 if (Tok.getString().startswith("."))
1131 // If we're parsing an immediate expression, we don't expect a '['.
1132 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1135 AsmToken::TokenKind TK = getLexer().getKind();
1138 if (SM.isValidEndState()) {
1142 return Error(Tok.getLoc(), "unknown token in expression");
1144 case AsmToken::EndOfStatement: {
1148 case AsmToken::String:
1149 case AsmToken::Identifier: {
1150 // This could be a register or a symbolic displacement.
1153 SMLoc IdentLoc = Tok.getLoc();
1154 StringRef Identifier = Tok.getString();
1155 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1156 SM.onRegister(TmpReg);
1157 UpdateLocLex = false;
1160 if (!isParsingInlineAsm()) {
1161 if (getParser().parsePrimaryExpr(Val, End))
1162 return Error(Tok.getLoc(), "Unexpected identifier!");
1164 // This is a dot operator, not an adjacent identifier.
1165 if (Identifier.find('.') != StringRef::npos) {
1168 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1169 if (ParseIntelIdentifier(Val, Identifier, Info,
1170 /*Unevaluated=*/false, End))
1174 SM.onIdentifierExpr(Val, Identifier);
1175 UpdateLocLex = false;
1178 return Error(Tok.getLoc(), "Unexpected identifier!");
1180 case AsmToken::Integer: {
1182 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1183 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1185 // Look for 'b' or 'f' following an Integer as a directional label
1186 SMLoc Loc = getTok().getLoc();
1187 int64_t IntVal = getTok().getIntVal();
1188 End = consumeToken();
1189 UpdateLocLex = false;
1190 if (getLexer().getKind() == AsmToken::Identifier) {
1191 StringRef IDVal = getTok().getString();
1192 if (IDVal == "f" || IDVal == "b") {
1194 getContext().GetDirectionalLocalSymbol(IntVal, IDVal == "b");
1195 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1197 MCSymbolRefExpr::Create(Sym, Variant, getContext());
1198 if (IDVal == "b" && Sym->isUndefined())
1199 return Error(Loc, "invalid reference to undefined symbol");
1200 StringRef Identifier = Sym->getName();
1201 SM.onIdentifierExpr(Val, Identifier);
1202 End = consumeToken();
1204 if (SM.onInteger(IntVal, ErrMsg))
1205 return Error(Loc, ErrMsg);
1208 if (SM.onInteger(IntVal, ErrMsg))
1209 return Error(Loc, ErrMsg);
1213 case AsmToken::Plus: SM.onPlus(); break;
1214 case AsmToken::Minus: SM.onMinus(); break;
1215 case AsmToken::Tilde: SM.onNot(); break;
1216 case AsmToken::Star: SM.onStar(); break;
1217 case AsmToken::Slash: SM.onDivide(); break;
1218 case AsmToken::Pipe: SM.onOr(); break;
1219 case AsmToken::Amp: SM.onAnd(); break;
1220 case AsmToken::LessLess:
1221 SM.onLShift(); break;
1222 case AsmToken::GreaterGreater:
1223 SM.onRShift(); break;
1224 case AsmToken::LBrac: SM.onLBrac(); break;
1225 case AsmToken::RBrac: SM.onRBrac(); break;
1226 case AsmToken::LParen: SM.onLParen(); break;
1227 case AsmToken::RParen: SM.onRParen(); break;
1230 return Error(Tok.getLoc(), "unknown token in expression");
1232 if (!Done && UpdateLocLex)
1233 End = consumeToken();
1238 std::unique_ptr<X86Operand>
1239 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1240 int64_t ImmDisp, unsigned Size) {
1241 MCAsmParser &Parser = getParser();
1242 const AsmToken &Tok = Parser.getTok();
1243 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1244 if (getLexer().isNot(AsmToken::LBrac))
1245 return ErrorOperand(BracLoc, "Expected '[' token!");
1246 Parser.Lex(); // Eat '['
1248 SMLoc StartInBrac = Tok.getLoc();
1249 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1250 // may have already parsed an immediate displacement before the bracketed
1252 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1253 if (ParseIntelExpression(SM, End))
1256 const MCExpr *Disp = nullptr;
1257 if (const MCExpr *Sym = SM.getSym()) {
1258 // A symbolic displacement.
1260 if (isParsingInlineAsm())
1261 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1262 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1266 if (SM.getImm() || !Disp) {
1267 const MCExpr *Imm = MCConstantExpr::Create(SM.getImm(), getContext());
1269 Disp = MCBinaryExpr::CreateAdd(Disp, Imm, getContext());
1271 Disp = Imm; // An immediate displacement only.
1274 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1275 // will in fact do global lookup the field name inside all global typedefs,
1276 // but we don't emulate that.
1277 if (Tok.getString().find('.') != StringRef::npos) {
1278 const MCExpr *NewDisp;
1279 if (ParseIntelDotOperator(Disp, NewDisp))
1282 End = Tok.getEndLoc();
1283 Parser.Lex(); // Eat the field.
1287 int BaseReg = SM.getBaseReg();
1288 int IndexReg = SM.getIndexReg();
1289 int Scale = SM.getScale();
1290 if (!isParsingInlineAsm()) {
1292 if (!BaseReg && !IndexReg) {
1294 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1295 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1299 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1300 Error(StartInBrac, ErrMsg);
1303 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1304 IndexReg, Scale, Start, End, Size);
1307 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1308 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1309 End, Size, SM.getSymName(), Info);
1312 // Inline assembly may use variable names with namespace alias qualifiers.
1313 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1314 StringRef &Identifier,
1315 InlineAsmIdentifierInfo &Info,
1316 bool IsUnevaluatedOperand, SMLoc &End) {
1317 MCAsmParser &Parser = getParser();
1318 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1321 StringRef LineBuf(Identifier.data());
1323 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1325 const AsmToken &Tok = Parser.getTok();
1326 SMLoc Loc = Tok.getLoc();
1328 // Advance the token stream until the end of the current token is
1329 // after the end of what the frontend claimed.
1330 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1332 End = Tok.getEndLoc();
1335 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
1336 if (End.getPointer() == EndPtr) break;
1338 Identifier = LineBuf;
1340 // If the identifier lookup was unsuccessful, assume that we are dealing with
1343 StringRef InternalName =
1344 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1346 assert(InternalName.size() && "We should have an internal name here.");
1347 // Push a rewrite for replacing the identifier name with the internal name.
1348 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1353 // Create the symbol reference.
1354 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
1355 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1356 Val = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());
1360 /// \brief Parse intel style segment override.
1361 std::unique_ptr<X86Operand>
1362 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1364 MCAsmParser &Parser = getParser();
1365 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1366 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1367 if (Tok.isNot(AsmToken::Colon))
1368 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1369 Parser.Lex(); // Eat ':'
1371 int64_t ImmDisp = 0;
1372 if (getLexer().is(AsmToken::Integer)) {
1373 ImmDisp = Tok.getIntVal();
1374 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1376 if (isParsingInlineAsm())
1377 InstInfo->AsmRewrites->push_back(
1378 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1380 if (getLexer().isNot(AsmToken::LBrac)) {
1381 // An immediate following a 'segment register', 'colon' token sequence can
1382 // be followed by a bracketed expression. If it isn't we know we have our
1383 // final segment override.
1384 const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext());
1385 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1386 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1387 Start, ImmDispToken.getEndLoc(), Size);
1391 if (getLexer().is(AsmToken::LBrac))
1392 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1396 if (!isParsingInlineAsm()) {
1397 if (getParser().parsePrimaryExpr(Val, End))
1398 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1400 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1403 InlineAsmIdentifierInfo Info;
1404 StringRef Identifier = Tok.getString();
1405 if (ParseIntelIdentifier(Val, Identifier, Info,
1406 /*Unevaluated=*/false, End))
1408 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1409 /*Scale=*/1, Start, End, Size, Identifier, Info);
1412 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1413 std::unique_ptr<X86Operand>
1414 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1415 MCAsmParser &Parser = getParser();
1416 const AsmToken &Tok = Parser.getTok();
1417 // Eat "{" and mark the current place.
1418 const SMLoc consumedToken = consumeToken();
1419 if (Tok.getIdentifier().startswith("r")){
1420 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1421 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1422 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1423 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1424 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1427 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1428 Parser.Lex(); // Eat "r*" of r*-sae
1429 if (!getLexer().is(AsmToken::Minus))
1430 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1431 Parser.Lex(); // Eat "-"
1432 Parser.Lex(); // Eat the sae
1433 if (!getLexer().is(AsmToken::RCurly))
1434 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1435 Parser.Lex(); // Eat "}"
1436 const MCExpr *RndModeOp =
1437 MCConstantExpr::Create(rndMode, Parser.getContext());
1438 return X86Operand::CreateImm(RndModeOp, Start, End);
1440 if(Tok.getIdentifier().equals("sae")){
1441 Parser.Lex(); // Eat the sae
1442 if (!getLexer().is(AsmToken::RCurly))
1443 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1444 Parser.Lex(); // Eat "}"
1445 return X86Operand::CreateToken("{sae}", consumedToken);
1447 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1449 /// ParseIntelMemOperand - Parse intel style memory operand.
1450 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1453 MCAsmParser &Parser = getParser();
1454 const AsmToken &Tok = Parser.getTok();
1457 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1458 if (getLexer().is(AsmToken::LBrac))
1459 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1460 assert(ImmDisp == 0);
1463 if (!isParsingInlineAsm()) {
1464 if (getParser().parsePrimaryExpr(Val, End))
1465 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1467 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1470 InlineAsmIdentifierInfo Info;
1471 StringRef Identifier = Tok.getString();
1472 if (ParseIntelIdentifier(Val, Identifier, Info,
1473 /*Unevaluated=*/false, End))
1476 if (!getLexer().is(AsmToken::LBrac))
1477 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1478 /*Scale=*/1, Start, End, Size, Identifier, Info);
1480 Parser.Lex(); // Eat '['
1482 // Parse Identifier [ ImmDisp ]
1483 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1484 /*AddImmPrefix=*/false);
1485 if (ParseIntelExpression(SM, End))
1489 Error(Start, "cannot use more than one symbol in memory operand");
1492 if (SM.getBaseReg()) {
1493 Error(Start, "cannot use base register with variable reference");
1496 if (SM.getIndexReg()) {
1497 Error(Start, "cannot use index register with variable reference");
1501 const MCExpr *Disp = MCConstantExpr::Create(SM.getImm(), getContext());
1502 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1503 // we're pointing to a local variable in memory, so the base register is
1504 // really the frame or stack pointer.
1505 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1506 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1507 Start, End, Size, Identifier, Info.OpDecl);
1510 /// Parse the '.' operator.
1511 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1512 const MCExpr *&NewDisp) {
1513 MCAsmParser &Parser = getParser();
1514 const AsmToken &Tok = Parser.getTok();
1515 int64_t OrigDispVal, DotDispVal;
1517 // FIXME: Handle non-constant expressions.
1518 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1519 OrigDispVal = OrigDisp->getValue();
1521 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1523 // Drop the optional '.'.
1524 StringRef DotDispStr = Tok.getString();
1525 if (DotDispStr.startswith("."))
1526 DotDispStr = DotDispStr.drop_front(1);
1528 // .Imm gets lexed as a real.
1529 if (Tok.is(AsmToken::Real)) {
1531 DotDispStr.getAsInteger(10, DotDisp);
1532 DotDispVal = DotDisp.getZExtValue();
1533 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1535 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1536 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1538 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1539 DotDispVal = DotDisp;
1541 return Error(Tok.getLoc(), "Unexpected token type!");
1543 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1544 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1545 unsigned Len = DotDispStr.size();
1546 unsigned Val = OrigDispVal + DotDispVal;
1547 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1551 NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
1555 /// Parse the 'offset' operator. This operator is used to specify the
1556 /// location rather then the content of a variable.
1557 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1558 MCAsmParser &Parser = getParser();
1559 const AsmToken &Tok = Parser.getTok();
1560 SMLoc OffsetOfLoc = Tok.getLoc();
1561 Parser.Lex(); // Eat offset.
1564 InlineAsmIdentifierInfo Info;
1565 SMLoc Start = Tok.getLoc(), End;
1566 StringRef Identifier = Tok.getString();
1567 if (ParseIntelIdentifier(Val, Identifier, Info,
1568 /*Unevaluated=*/false, End))
1571 // Don't emit the offset operator.
1572 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1574 // The offset operator will have an 'r' constraint, thus we need to create
1575 // register operand to ensure proper matching. Just pick a GPR based on
1576 // the size of a pointer.
1578 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1579 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1580 OffsetOfLoc, Identifier, Info.OpDecl);
1583 enum IntelOperatorKind {
1589 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1590 /// returns the number of elements in an array. It returns the value 1 for
1591 /// non-array variables. The SIZE operator returns the size of a C or C++
1592 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1593 /// TYPE operator returns the size of a C or C++ type or variable. If the
1594 /// variable is an array, TYPE returns the size of a single element.
1595 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1596 MCAsmParser &Parser = getParser();
1597 const AsmToken &Tok = Parser.getTok();
1598 SMLoc TypeLoc = Tok.getLoc();
1599 Parser.Lex(); // Eat operator.
1601 const MCExpr *Val = nullptr;
1602 InlineAsmIdentifierInfo Info;
1603 SMLoc Start = Tok.getLoc(), End;
1604 StringRef Identifier = Tok.getString();
1605 if (ParseIntelIdentifier(Val, Identifier, Info,
1606 /*Unevaluated=*/true, End))
1610 return ErrorOperand(Start, "unable to lookup expression");
1614 default: llvm_unreachable("Unexpected operand kind!");
1615 case IOK_LENGTH: CVal = Info.Length; break;
1616 case IOK_SIZE: CVal = Info.Size; break;
1617 case IOK_TYPE: CVal = Info.Type; break;
1620 // Rewrite the type operator and the C or C++ type or variable in terms of an
1621 // immediate. E.g. TYPE foo -> $$4
1622 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1623 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1625 const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1626 return X86Operand::CreateImm(Imm, Start, End);
1629 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1630 MCAsmParser &Parser = getParser();
1631 const AsmToken &Tok = Parser.getTok();
1634 // Offset, length, type and size operators.
1635 if (isParsingInlineAsm()) {
1636 StringRef AsmTokStr = Tok.getString();
1637 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1638 return ParseIntelOffsetOfOperator();
1639 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1640 return ParseIntelOperator(IOK_LENGTH);
1641 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1642 return ParseIntelOperator(IOK_SIZE);
1643 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1644 return ParseIntelOperator(IOK_TYPE);
1647 unsigned Size = getIntelMemOperandSize(Tok.getString());
1649 Parser.Lex(); // Eat operand size (e.g., byte, word).
1650 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1651 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1652 Parser.Lex(); // Eat ptr.
1654 Start = Tok.getLoc();
1657 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1658 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1659 AsmToken StartTok = Tok;
1660 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1661 /*AddImmPrefix=*/false);
1662 if (ParseIntelExpression(SM, End))
1665 int64_t Imm = SM.getImm();
1666 if (isParsingInlineAsm()) {
1667 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1668 if (StartTok.getString().size() == Len)
1669 // Just add a prefix if this wasn't a complex immediate expression.
1670 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1672 // Otherwise, rewrite the complex expression as a single immediate.
1673 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
1676 if (getLexer().isNot(AsmToken::LBrac)) {
1677 // If a directional label (ie. 1f or 2b) was parsed above from
1678 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1679 // to the MCExpr with the directional local symbol and this is a
1680 // memory operand not an immediate operand.
1682 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1685 const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext());
1686 return X86Operand::CreateImm(ImmExpr, Start, End);
1689 // Only positive immediates are valid.
1691 return ErrorOperand(Start, "expected a positive immediate displacement "
1692 "before bracketed expr.");
1694 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1695 return ParseIntelMemOperand(Imm, Start, Size);
1698 // rounding mode token
1699 if (STI.getFeatureBits() & X86::FeatureAVX512 &&
1700 getLexer().is(AsmToken::LCurly))
1701 return ParseRoundingModeOp(Start, End);
1705 if (!ParseRegister(RegNo, Start, End)) {
1706 // If this is a segment register followed by a ':', then this is the start
1707 // of a segment override, otherwise this is a normal register reference.
1708 if (getLexer().isNot(AsmToken::Colon))
1709 return X86Operand::CreateReg(RegNo, Start, End);
1711 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1715 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1718 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1719 MCAsmParser &Parser = getParser();
1720 switch (getLexer().getKind()) {
1722 // Parse a memory operand with no segment register.
1723 return ParseMemOperand(0, Parser.getTok().getLoc());
1724 case AsmToken::Percent: {
1725 // Read the register.
1728 if (ParseRegister(RegNo, Start, End)) return nullptr;
1729 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1730 Error(Start, "%eiz and %riz can only be used as index registers",
1731 SMRange(Start, End));
1735 // If this is a segment register followed by a ':', then this is the start
1736 // of a memory reference, otherwise this is a normal register reference.
1737 if (getLexer().isNot(AsmToken::Colon))
1738 return X86Operand::CreateReg(RegNo, Start, End);
1740 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1741 return ErrorOperand(Start, "invalid segment register");
1743 getParser().Lex(); // Eat the colon.
1744 return ParseMemOperand(RegNo, Start);
1746 case AsmToken::Dollar: {
1747 // $42 -> immediate.
1748 SMLoc Start = Parser.getTok().getLoc(), End;
1751 if (getParser().parseExpression(Val, End))
1753 return X86Operand::CreateImm(Val, Start, End);
1755 case AsmToken::LCurly:{
1756 SMLoc Start = Parser.getTok().getLoc(), End;
1757 if (STI.getFeatureBits() & X86::FeatureAVX512)
1758 return ParseRoundingModeOp(Start, End);
1759 return ErrorOperand(Start, "unknown token in expression");
1764 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1765 const MCParsedAsmOperand &Op) {
1766 MCAsmParser &Parser = getParser();
1767 if(STI.getFeatureBits() & X86::FeatureAVX512) {
1768 if (getLexer().is(AsmToken::LCurly)) {
1769 // Eat "{" and mark the current place.
1770 const SMLoc consumedToken = consumeToken();
1771 // Distinguish {1to<NUM>} from {%k<NUM>}.
1772 if(getLexer().is(AsmToken::Integer)) {
1773 // Parse memory broadcasting ({1to<NUM>}).
1774 if (getLexer().getTok().getIntVal() != 1)
1775 return !ErrorAndEatStatement(getLexer().getLoc(),
1776 "Expected 1to<NUM> at this point");
1777 Parser.Lex(); // Eat "1" of 1to8
1778 if (!getLexer().is(AsmToken::Identifier) ||
1779 !getLexer().getTok().getIdentifier().startswith("to"))
1780 return !ErrorAndEatStatement(getLexer().getLoc(),
1781 "Expected 1to<NUM> at this point");
1782 // Recognize only reasonable suffixes.
1783 const char *BroadcastPrimitive =
1784 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1785 .Case("to2", "{1to2}")
1786 .Case("to4", "{1to4}")
1787 .Case("to8", "{1to8}")
1788 .Case("to16", "{1to16}")
1790 if (!BroadcastPrimitive)
1791 return !ErrorAndEatStatement(getLexer().getLoc(),
1792 "Invalid memory broadcast primitive.");
1793 Parser.Lex(); // Eat "toN" of 1toN
1794 if (!getLexer().is(AsmToken::RCurly))
1795 return !ErrorAndEatStatement(getLexer().getLoc(),
1796 "Expected } at this point");
1797 Parser.Lex(); // Eat "}"
1798 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1800 // No AVX512 specific primitives can pass
1801 // after memory broadcasting, so return.
1804 // Parse mask register {%k1}
1805 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1806 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1807 Operands.push_back(std::move(Op));
1808 if (!getLexer().is(AsmToken::RCurly))
1809 return !ErrorAndEatStatement(getLexer().getLoc(),
1810 "Expected } at this point");
1811 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1813 // Parse "zeroing non-masked" semantic {z}
1814 if (getLexer().is(AsmToken::LCurly)) {
1815 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1816 if (!getLexer().is(AsmToken::Identifier) ||
1817 getLexer().getTok().getIdentifier() != "z")
1818 return !ErrorAndEatStatement(getLexer().getLoc(),
1819 "Expected z at this point");
1820 Parser.Lex(); // Eat the z
1821 if (!getLexer().is(AsmToken::RCurly))
1822 return !ErrorAndEatStatement(getLexer().getLoc(),
1823 "Expected } at this point");
1824 Parser.Lex(); // Eat the }
1833 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1834 /// has already been parsed if present.
1835 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1838 MCAsmParser &Parser = getParser();
1839 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1840 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1841 // only way to do this without lookahead is to eat the '(' and see what is
1843 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1844 if (getLexer().isNot(AsmToken::LParen)) {
1846 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1848 // After parsing the base expression we could either have a parenthesized
1849 // memory address or not. If not, return now. If so, eat the (.
1850 if (getLexer().isNot(AsmToken::LParen)) {
1851 // Unless we have a segment register, treat this as an immediate.
1853 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1854 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1861 // Okay, we have a '('. We don't know if this is an expression or not, but
1862 // so we have to eat the ( to see beyond it.
1863 SMLoc LParenLoc = Parser.getTok().getLoc();
1864 Parser.Lex(); // Eat the '('.
1866 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1867 // Nothing to do here, fall into the code below with the '(' part of the
1868 // memory operand consumed.
1872 // It must be an parenthesized expression, parse it now.
1873 if (getParser().parseParenExpression(Disp, ExprEnd))
1876 // After parsing the base expression we could either have a parenthesized
1877 // memory address or not. If not, return now. If so, eat the (.
1878 if (getLexer().isNot(AsmToken::LParen)) {
1879 // Unless we have a segment register, treat this as an immediate.
1881 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1883 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1892 // If we reached here, then we just ate the ( of the memory operand. Process
1893 // the rest of the memory operand.
1894 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1895 SMLoc IndexLoc, BaseLoc;
1897 if (getLexer().is(AsmToken::Percent)) {
1898 SMLoc StartLoc, EndLoc;
1899 BaseLoc = Parser.getTok().getLoc();
1900 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1901 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1902 Error(StartLoc, "eiz and riz can only be used as index registers",
1903 SMRange(StartLoc, EndLoc));
1908 if (getLexer().is(AsmToken::Comma)) {
1909 Parser.Lex(); // Eat the comma.
1910 IndexLoc = Parser.getTok().getLoc();
1912 // Following the comma we should have either an index register, or a scale
1913 // value. We don't support the later form, but we want to parse it
1916 // Not that even though it would be completely consistent to support syntax
1917 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1918 if (getLexer().is(AsmToken::Percent)) {
1920 if (ParseRegister(IndexReg, L, L)) return nullptr;
1922 if (getLexer().isNot(AsmToken::RParen)) {
1923 // Parse the scale amount:
1924 // ::= ',' [scale-expression]
1925 if (getLexer().isNot(AsmToken::Comma)) {
1926 Error(Parser.getTok().getLoc(),
1927 "expected comma in scale expression");
1930 Parser.Lex(); // Eat the comma.
1932 if (getLexer().isNot(AsmToken::RParen)) {
1933 SMLoc Loc = Parser.getTok().getLoc();
1936 if (getParser().parseAbsoluteExpression(ScaleVal)){
1937 Error(Loc, "expected scale expression");
1941 // Validate the scale amount.
1942 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1944 Error(Loc, "scale factor in 16-bit address must be 1");
1947 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1948 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1951 Scale = (unsigned)ScaleVal;
1954 } else if (getLexer().isNot(AsmToken::RParen)) {
1955 // A scale amount without an index is ignored.
1957 SMLoc Loc = Parser.getTok().getLoc();
1960 if (getParser().parseAbsoluteExpression(Value))
1964 Warning(Loc, "scale factor without index register is ignored");
1969 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1970 if (getLexer().isNot(AsmToken::RParen)) {
1971 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1974 SMLoc MemEnd = Parser.getTok().getEndLoc();
1975 Parser.Lex(); // Eat the ')'.
1977 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
1978 // and then only in non-64-bit modes. Except for DX, which is a special case
1979 // because an unofficial form of in/out instructions uses it.
1980 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1981 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
1982 BaseReg != X86::SI && BaseReg != X86::DI)) &&
1983 BaseReg != X86::DX) {
1984 Error(BaseLoc, "invalid 16-bit base register");
1988 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
1989 Error(IndexLoc, "16-bit memory operand may not include only index register");
1994 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1995 Error(BaseLoc, ErrMsg);
1999 if (SegReg || BaseReg || IndexReg)
2000 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2001 IndexReg, Scale, MemStart, MemEnd);
2002 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2005 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2006 SMLoc NameLoc, OperandVector &Operands) {
2007 MCAsmParser &Parser = getParser();
2009 StringRef PatchedName = Name;
2011 // FIXME: Hack to recognize setneb as setne.
2012 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2013 PatchedName != "setb" && PatchedName != "setnb")
2014 PatchedName = PatchedName.substr(0, Name.size()-1);
2016 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2017 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2018 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2019 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2020 bool IsVCMP = PatchedName[0] == 'v';
2021 unsigned CCIdx = IsVCMP ? 4 : 3;
2022 unsigned ComparisonCode = StringSwitch<unsigned>(
2023 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2027 .Case("unord", 0x03)
2032 /* AVX only from here */
2033 .Case("eq_uq", 0x08)
2036 .Case("false", 0x0B)
2037 .Case("neq_oq", 0x0C)
2041 .Case("eq_os", 0x10)
2042 .Case("lt_oq", 0x11)
2043 .Case("le_oq", 0x12)
2044 .Case("unord_s", 0x13)
2045 .Case("neq_us", 0x14)
2046 .Case("nlt_uq", 0x15)
2047 .Case("nle_uq", 0x16)
2048 .Case("ord_s", 0x17)
2049 .Case("eq_us", 0x18)
2050 .Case("nge_uq", 0x19)
2051 .Case("ngt_uq", 0x1A)
2052 .Case("false_os", 0x1B)
2053 .Case("neq_os", 0x1C)
2054 .Case("ge_oq", 0x1D)
2055 .Case("gt_oq", 0x1E)
2056 .Case("true_us", 0x1F)
2058 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2060 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2063 const MCExpr *ImmOp = MCConstantExpr::Create(ComparisonCode,
2064 getParser().getContext());
2065 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2067 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2071 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2072 if (PatchedName.startswith("vpcmp") &&
2073 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2074 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2075 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2076 unsigned ComparisonCode = StringSwitch<unsigned>(
2077 PatchedName.slice(5, PatchedName.size() - CCIdx))
2078 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2081 //.Case("false", 0x3) // Not a documented alias.
2085 //.Case("true", 0x7) // Not a documented alias.
2087 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2088 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2090 const MCExpr *ImmOp = MCConstantExpr::Create(ComparisonCode,
2091 getParser().getContext());
2092 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2094 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2098 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2099 if (PatchedName.startswith("vpcom") &&
2100 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2101 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2102 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2103 unsigned ComparisonCode = StringSwitch<unsigned>(
2104 PatchedName.slice(5, PatchedName.size() - CCIdx))
2114 if (ComparisonCode != ~0U) {
2115 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2117 const MCExpr *ImmOp = MCConstantExpr::Create(ComparisonCode,
2118 getParser().getContext());
2119 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2121 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2125 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2127 // Determine whether this is an instruction prefix.
2129 Name == "lock" || Name == "rep" ||
2130 Name == "repe" || Name == "repz" ||
2131 Name == "repne" || Name == "repnz" ||
2132 Name == "rex64" || Name == "data16";
2135 // This does the actual operand parsing. Don't parse any more if we have a
2136 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2137 // just want to parse the "lock" as the first instruction and the "incl" as
2139 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2141 // Parse '*' modifier.
2142 if (getLexer().is(AsmToken::Star))
2143 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2145 // Read the operands.
2147 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2148 Operands.push_back(std::move(Op));
2149 if (!HandleAVX512Operand(Operands, *Operands.back()))
2152 Parser.eatToEndOfStatement();
2155 // check for comma and eat it
2156 if (getLexer().is(AsmToken::Comma))
2162 if (getLexer().isNot(AsmToken::EndOfStatement))
2163 return ErrorAndEatStatement(getLexer().getLoc(),
2164 "unexpected token in argument list");
2167 // Consume the EndOfStatement or the prefix separator Slash
2168 if (getLexer().is(AsmToken::EndOfStatement) ||
2169 (isPrefix && getLexer().is(AsmToken::Slash)))
2172 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2173 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2174 // documented form in various unofficial manuals, so a lot of code uses it.
2175 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2176 Operands.size() == 3) {
2177 X86Operand &Op = (X86Operand &)*Operands.back();
2178 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2179 isa<MCConstantExpr>(Op.Mem.Disp) &&
2180 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2181 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2182 SMLoc Loc = Op.getEndLoc();
2183 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2186 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2187 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2188 Operands.size() == 3) {
2189 X86Operand &Op = (X86Operand &)*Operands[1];
2190 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2191 isa<MCConstantExpr>(Op.Mem.Disp) &&
2192 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2193 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2194 SMLoc Loc = Op.getEndLoc();
2195 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2199 // Append default arguments to "ins[bwld]"
2200 if (Name.startswith("ins") && Operands.size() == 1 &&
2201 (Name == "insb" || Name == "insw" || Name == "insl" ||
2203 if (isParsingIntelSyntax()) {
2204 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2205 Operands.push_back(DefaultMemDIOperand(NameLoc));
2207 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2208 Operands.push_back(DefaultMemDIOperand(NameLoc));
2212 // Append default arguments to "outs[bwld]"
2213 if (Name.startswith("outs") && Operands.size() == 1 &&
2214 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2215 Name == "outsd" )) {
2216 if (isParsingIntelSyntax()) {
2217 Operands.push_back(DefaultMemSIOperand(NameLoc));
2218 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2220 Operands.push_back(DefaultMemSIOperand(NameLoc));
2221 Operands.push_back(X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2225 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2226 // values of $SIREG according to the mode. It would be nice if this
2227 // could be achieved with InstAlias in the tables.
2228 if (Name.startswith("lods") && Operands.size() == 1 &&
2229 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2230 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2231 Operands.push_back(DefaultMemSIOperand(NameLoc));
2233 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2234 // values of $DIREG according to the mode. It would be nice if this
2235 // could be achieved with InstAlias in the tables.
2236 if (Name.startswith("stos") && Operands.size() == 1 &&
2237 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2238 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2239 Operands.push_back(DefaultMemDIOperand(NameLoc));
2241 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2242 // values of $DIREG according to the mode. It would be nice if this
2243 // could be achieved with InstAlias in the tables.
2244 if (Name.startswith("scas") && Operands.size() == 1 &&
2245 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2246 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2247 Operands.push_back(DefaultMemDIOperand(NameLoc));
2249 // Add default SI and DI operands to "cmps[bwlq]".
2250 if (Name.startswith("cmps") &&
2251 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2252 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2253 if (Operands.size() == 1) {
2254 if (isParsingIntelSyntax()) {
2255 Operands.push_back(DefaultMemSIOperand(NameLoc));
2256 Operands.push_back(DefaultMemDIOperand(NameLoc));
2258 Operands.push_back(DefaultMemDIOperand(NameLoc));
2259 Operands.push_back(DefaultMemSIOperand(NameLoc));
2261 } else if (Operands.size() == 3) {
2262 X86Operand &Op = (X86Operand &)*Operands[1];
2263 X86Operand &Op2 = (X86Operand &)*Operands[2];
2264 if (!doSrcDstMatch(Op, Op2))
2265 return Error(Op.getStartLoc(),
2266 "mismatching source and destination index registers");
2270 // Add default SI and DI operands to "movs[bwlq]".
2271 if ((Name.startswith("movs") &&
2272 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2273 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2274 (Name.startswith("smov") &&
2275 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2276 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2277 if (Operands.size() == 1) {
2278 if (Name == "movsd")
2279 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2280 if (isParsingIntelSyntax()) {
2281 Operands.push_back(DefaultMemDIOperand(NameLoc));
2282 Operands.push_back(DefaultMemSIOperand(NameLoc));
2284 Operands.push_back(DefaultMemSIOperand(NameLoc));
2285 Operands.push_back(DefaultMemDIOperand(NameLoc));
2287 } else if (Operands.size() == 3) {
2288 X86Operand &Op = (X86Operand &)*Operands[1];
2289 X86Operand &Op2 = (X86Operand &)*Operands[2];
2290 if (!doSrcDstMatch(Op, Op2))
2291 return Error(Op.getStartLoc(),
2292 "mismatching source and destination index registers");
2296 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2298 if ((Name.startswith("shr") || Name.startswith("sar") ||
2299 Name.startswith("shl") || Name.startswith("sal") ||
2300 Name.startswith("rcl") || Name.startswith("rcr") ||
2301 Name.startswith("rol") || Name.startswith("ror")) &&
2302 Operands.size() == 3) {
2303 if (isParsingIntelSyntax()) {
2305 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2306 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2307 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2308 Operands.pop_back();
2310 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2311 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2312 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2313 Operands.erase(Operands.begin() + 1);
2317 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2318 // instalias with an immediate operand yet.
2319 if (Name == "int" && Operands.size() == 2) {
2320 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2321 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2322 cast<MCConstantExpr>(Op1.getImm())->getValue() == 3) {
2323 Operands.erase(Operands.begin() + 1);
2324 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2331 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2334 TmpInst.setOpcode(Opcode);
2336 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2337 TmpInst.addOperand(MCOperand::CreateReg(Reg));
2338 TmpInst.addOperand(Inst.getOperand(0));
2343 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2344 bool isCmp = false) {
2345 if (!Inst.getOperand(0).isImm() ||
2346 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2349 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2352 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2353 bool isCmp = false) {
2354 if (!Inst.getOperand(0).isImm() ||
2355 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2358 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2361 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2362 bool isCmp = false) {
2363 if (!Inst.getOperand(0).isImm() ||
2364 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2367 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2370 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2371 switch (Inst.getOpcode()) {
2372 default: return true;
2374 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2375 assert(Op.isImm() && "expected immediate");
2377 if (!Op.getImm()->EvaluateAsAbsolute(Res) || Res > 255) {
2378 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2383 llvm_unreachable("handle the instruction appropriately");
2386 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2387 switch (Inst.getOpcode()) {
2388 default: return false;
2389 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2390 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2391 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2392 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2393 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2394 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2395 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2396 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2397 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2398 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2399 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2400 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2401 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2402 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2403 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2404 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2405 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2406 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2407 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2408 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2409 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2410 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2411 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2412 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2413 case X86::VMOVAPDrr:
2414 case X86::VMOVAPDYrr:
2415 case X86::VMOVAPSrr:
2416 case X86::VMOVAPSYrr:
2417 case X86::VMOVDQArr:
2418 case X86::VMOVDQAYrr:
2419 case X86::VMOVDQUrr:
2420 case X86::VMOVDQUYrr:
2421 case X86::VMOVUPDrr:
2422 case X86::VMOVUPDYrr:
2423 case X86::VMOVUPSrr:
2424 case X86::VMOVUPSYrr: {
2425 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2426 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2430 switch (Inst.getOpcode()) {
2431 default: llvm_unreachable("Invalid opcode");
2432 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2433 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2434 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2435 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2436 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2437 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2438 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2439 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2440 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2441 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2442 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2443 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2445 Inst.setOpcode(NewOpc);
2449 case X86::VMOVSSrr: {
2450 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2451 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2454 switch (Inst.getOpcode()) {
2455 default: llvm_unreachable("Invalid opcode");
2456 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2457 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2459 Inst.setOpcode(NewOpc);
2465 static const char *getSubtargetFeatureName(uint64_t Val);
2467 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2469 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2473 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2474 OperandVector &Operands,
2475 MCStreamer &Out, uint64_t &ErrorInfo,
2476 bool MatchingInlineAsm) {
2477 if (isParsingIntelSyntax())
2478 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2480 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2484 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2485 OperandVector &Operands, MCStreamer &Out,
2486 bool MatchingInlineAsm) {
2487 // FIXME: This should be replaced with a real .td file alias mechanism.
2488 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2490 const char *Repl = StringSwitch<const char *>(Op.getToken())
2491 .Case("finit", "fninit")
2492 .Case("fsave", "fnsave")
2493 .Case("fstcw", "fnstcw")
2494 .Case("fstcww", "fnstcw")
2495 .Case("fstenv", "fnstenv")
2496 .Case("fstsw", "fnstsw")
2497 .Case("fstsww", "fnstsw")
2498 .Case("fclex", "fnclex")
2502 Inst.setOpcode(X86::WAIT);
2504 if (!MatchingInlineAsm)
2505 EmitInstruction(Inst, Operands, Out);
2506 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2510 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2511 bool MatchingInlineAsm) {
2512 assert(ErrorInfo && "Unknown missing feature!");
2513 ArrayRef<SMRange> EmptyRanges = None;
2514 SmallString<126> Msg;
2515 raw_svector_ostream OS(Msg);
2516 OS << "instruction requires:";
2518 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2519 if (ErrorInfo & Mask)
2520 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2523 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2526 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2527 OperandVector &Operands,
2529 uint64_t &ErrorInfo,
2530 bool MatchingInlineAsm) {
2531 assert(!Operands.empty() && "Unexpect empty operand list!");
2532 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2533 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2534 ArrayRef<SMRange> EmptyRanges = None;
2536 // First, handle aliases that expand to multiple instructions.
2537 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2539 bool WasOriginallyInvalidOperand = false;
2542 // First, try a direct match.
2543 switch (MatchInstructionImpl(Operands, Inst,
2544 ErrorInfo, MatchingInlineAsm,
2545 isParsingIntelSyntax())) {
2546 default: llvm_unreachable("Unexpected match result!");
2548 if (!validateInstruction(Inst, Operands))
2551 // Some instructions need post-processing to, for example, tweak which
2552 // encoding is selected. Loop on it while changes happen so the
2553 // individual transformations can chain off each other.
2554 if (!MatchingInlineAsm)
2555 while (processInstruction(Inst, Operands))
2559 if (!MatchingInlineAsm)
2560 EmitInstruction(Inst, Operands, Out);
2561 Opcode = Inst.getOpcode();
2563 case Match_MissingFeature:
2564 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2565 case Match_InvalidOperand:
2566 WasOriginallyInvalidOperand = true;
2568 case Match_MnemonicFail:
2572 // FIXME: Ideally, we would only attempt suffix matches for things which are
2573 // valid prefixes, and we could just infer the right unambiguous
2574 // type. However, that requires substantially more matcher support than the
2577 // Change the operand to point to a temporary token.
2578 StringRef Base = Op.getToken();
2579 SmallString<16> Tmp;
2582 Op.setTokenValue(Tmp);
2584 // If this instruction starts with an 'f', then it is a floating point stack
2585 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2586 // 80-bit floating point, which use the suffixes s,l,t respectively.
2588 // Otherwise, we assume that this may be an integer instruction, which comes
2589 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2590 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2592 // Check for the various suffix matches.
2593 uint64_t ErrorInfoIgnore;
2594 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2597 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2598 Tmp.back() = Suffixes[I];
2599 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2600 MatchingInlineAsm, isParsingIntelSyntax());
2601 // If this returned as a missing feature failure, remember that.
2602 if (Match[I] == Match_MissingFeature)
2603 ErrorInfoMissingFeature = ErrorInfoIgnore;
2606 // Restore the old token.
2607 Op.setTokenValue(Base);
2609 // If exactly one matched, then we treat that as a successful match (and the
2610 // instruction will already have been filled in correctly, since the failing
2611 // matches won't have modified it).
2612 unsigned NumSuccessfulMatches =
2613 std::count(std::begin(Match), std::end(Match), Match_Success);
2614 if (NumSuccessfulMatches == 1) {
2616 if (!MatchingInlineAsm)
2617 EmitInstruction(Inst, Operands, Out);
2618 Opcode = Inst.getOpcode();
2622 // Otherwise, the match failed, try to produce a decent error message.
2624 // If we had multiple suffix matches, then identify this as an ambiguous
2626 if (NumSuccessfulMatches > 1) {
2628 unsigned NumMatches = 0;
2629 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2630 if (Match[I] == Match_Success)
2631 MatchChars[NumMatches++] = Suffixes[I];
2633 SmallString<126> Msg;
2634 raw_svector_ostream OS(Msg);
2635 OS << "ambiguous instructions require an explicit suffix (could be ";
2636 for (unsigned i = 0; i != NumMatches; ++i) {
2639 if (i + 1 == NumMatches)
2641 OS << "'" << Base << MatchChars[i] << "'";
2644 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2648 // Okay, we know that none of the variants matched successfully.
2650 // If all of the instructions reported an invalid mnemonic, then the original
2651 // mnemonic was invalid.
2652 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2653 if (!WasOriginallyInvalidOperand) {
2654 ArrayRef<SMRange> Ranges =
2655 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2656 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2657 Ranges, MatchingInlineAsm);
2660 // Recover location info for the operand if we know which was the problem.
2661 if (ErrorInfo != ~0ULL) {
2662 if (ErrorInfo >= Operands.size())
2663 return Error(IDLoc, "too few operands for instruction",
2664 EmptyRanges, MatchingInlineAsm);
2666 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2667 if (Operand.getStartLoc().isValid()) {
2668 SMRange OperandRange = Operand.getLocRange();
2669 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2670 OperandRange, MatchingInlineAsm);
2674 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2678 // If one instruction matched with a missing feature, report this as a
2680 if (std::count(std::begin(Match), std::end(Match),
2681 Match_MissingFeature) == 1) {
2682 ErrorInfo = ErrorInfoMissingFeature;
2683 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2687 // If one instruction matched with an invalid operand, report this as an
2689 if (std::count(std::begin(Match), std::end(Match),
2690 Match_InvalidOperand) == 1) {
2691 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2695 // If all of these were an outright failure, report it in a useless way.
2696 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2697 EmptyRanges, MatchingInlineAsm);
2701 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2702 OperandVector &Operands,
2704 uint64_t &ErrorInfo,
2705 bool MatchingInlineAsm) {
2706 assert(!Operands.empty() && "Unexpect empty operand list!");
2707 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2708 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2709 StringRef Mnemonic = Op.getToken();
2710 ArrayRef<SMRange> EmptyRanges = None;
2712 // First, handle aliases that expand to multiple instructions.
2713 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2717 // Find one unsized memory operand, if present.
2718 X86Operand *UnsizedMemOp = nullptr;
2719 for (const auto &Op : Operands) {
2720 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2721 if (X86Op->isMemUnsized())
2722 UnsizedMemOp = X86Op;
2725 // Allow some instructions to have implicitly pointer-sized operands. This is
2726 // compatible with gas.
2728 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2729 for (const char *Instr : PtrSizedInstrs) {
2730 if (Mnemonic == Instr) {
2731 UnsizedMemOp->Mem.Size = getPointerWidth();
2737 // If an unsized memory operand is present, try to match with each memory
2738 // operand size. In Intel assembly, the size is not part of the instruction
2740 SmallVector<unsigned, 8> Match;
2741 uint64_t ErrorInfoMissingFeature = 0;
2742 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2743 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2744 for (unsigned Size : MopSizes) {
2745 UnsizedMemOp->Mem.Size = Size;
2746 uint64_t ErrorInfoIgnore;
2747 unsigned LastOpcode = Inst.getOpcode();
2749 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2750 MatchingInlineAsm, isParsingIntelSyntax());
2751 if (Match.empty() || LastOpcode != Inst.getOpcode())
2754 // If this returned as a missing feature failure, remember that.
2755 if (Match.back() == Match_MissingFeature)
2756 ErrorInfoMissingFeature = ErrorInfoIgnore;
2759 // Restore the size of the unsized memory operand if we modified it.
2761 UnsizedMemOp->Mem.Size = 0;
2764 // If we haven't matched anything yet, this is not a basic integer or FPU
2765 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2766 // matching with the unsized operand.
2767 if (Match.empty()) {
2768 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2770 isParsingIntelSyntax()));
2771 // If this returned as a missing feature failure, remember that.
2772 if (Match.back() == Match_MissingFeature)
2773 ErrorInfoMissingFeature = ErrorInfo;
2776 // Restore the size of the unsized memory operand if we modified it.
2778 UnsizedMemOp->Mem.Size = 0;
2780 // If it's a bad mnemonic, all results will be the same.
2781 if (Match.back() == Match_MnemonicFail) {
2782 ArrayRef<SMRange> Ranges =
2783 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2784 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2785 Ranges, MatchingInlineAsm);
2788 // If exactly one matched, then we treat that as a successful match (and the
2789 // instruction will already have been filled in correctly, since the failing
2790 // matches won't have modified it).
2791 unsigned NumSuccessfulMatches =
2792 std::count(std::begin(Match), std::end(Match), Match_Success);
2793 if (NumSuccessfulMatches == 1) {
2794 if (!validateInstruction(Inst, Operands))
2797 // Some instructions need post-processing to, for example, tweak which
2798 // encoding is selected. Loop on it while changes happen so the individual
2799 // transformations can chain off each other.
2800 if (!MatchingInlineAsm)
2801 while (processInstruction(Inst, Operands))
2804 if (!MatchingInlineAsm)
2805 EmitInstruction(Inst, Operands, Out);
2806 Opcode = Inst.getOpcode();
2808 } else if (NumSuccessfulMatches > 1) {
2809 assert(UnsizedMemOp &&
2810 "multiple matches only possible with unsized memory operands");
2811 ArrayRef<SMRange> Ranges =
2812 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2813 return Error(UnsizedMemOp->getStartLoc(),
2814 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2815 Ranges, MatchingInlineAsm);
2818 // If one instruction matched with a missing feature, report this as a
2820 if (std::count(std::begin(Match), std::end(Match),
2821 Match_MissingFeature) == 1) {
2822 ErrorInfo = ErrorInfoMissingFeature;
2823 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2827 // If one instruction matched with an invalid operand, report this as an
2829 if (std::count(std::begin(Match), std::end(Match),
2830 Match_InvalidOperand) == 1) {
2831 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2835 // If all of these were an outright failure, report it in a useless way.
2836 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2840 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2841 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2844 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2845 MCAsmParser &Parser = getParser();
2846 StringRef IDVal = DirectiveID.getIdentifier();
2847 if (IDVal == ".word")
2848 return ParseDirectiveWord(2, DirectiveID.getLoc());
2849 else if (IDVal.startswith(".code"))
2850 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2851 else if (IDVal.startswith(".att_syntax")) {
2852 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2853 if (Parser.getTok().getString() == "prefix")
2855 else if (Parser.getTok().getString() == "noprefix")
2856 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2857 "supported: registers must have a "
2858 "'%' prefix in .att_syntax");
2860 getParser().setAssemblerDialect(0);
2862 } else if (IDVal.startswith(".intel_syntax")) {
2863 getParser().setAssemblerDialect(1);
2864 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2865 if (Parser.getTok().getString() == "noprefix")
2867 else if (Parser.getTok().getString() == "prefix")
2868 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2869 "supported: registers must not have "
2870 "a '%' prefix in .intel_syntax");
2877 /// ParseDirectiveWord
2878 /// ::= .word [ expression (, expression)* ]
2879 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2880 MCAsmParser &Parser = getParser();
2881 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2883 const MCExpr *Value;
2884 if (getParser().parseExpression(Value))
2887 getParser().getStreamer().EmitValue(Value, Size);
2889 if (getLexer().is(AsmToken::EndOfStatement))
2892 // FIXME: Improve diagnostic.
2893 if (getLexer().isNot(AsmToken::Comma)) {
2894 Error(L, "unexpected token in directive");
2905 /// ParseDirectiveCode
2906 /// ::= .code16 | .code32 | .code64
2907 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2908 MCAsmParser &Parser = getParser();
2909 if (IDVal == ".code16") {
2911 if (!is16BitMode()) {
2912 SwitchMode(X86::Mode16Bit);
2913 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2915 } else if (IDVal == ".code32") {
2917 if (!is32BitMode()) {
2918 SwitchMode(X86::Mode32Bit);
2919 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2921 } else if (IDVal == ".code64") {
2923 if (!is64BitMode()) {
2924 SwitchMode(X86::Mode64Bit);
2925 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2928 Error(L, "unknown directive " + IDVal);
2935 // Force static initialization.
2936 extern "C" void LLVMInitializeX86AsmParser() {
2937 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2938 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2941 #define GET_REGISTER_MATCHER
2942 #define GET_MATCHER_IMPLEMENTATION
2943 #define GET_SUBTARGET_FEATURE_NAME
2944 #include "X86GenAsmMatcher.inc"