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[] = {
59 class X86AsmParser : public MCTargetAsmParser {
61 const MCInstrInfo &MII;
62 ParseInstructionInfo *InstInfo;
63 std::unique_ptr<X86AsmInstrumentation> Instrumentation;
66 SMLoc consumeToken() {
67 MCAsmParser &Parser = getParser();
68 SMLoc Result = Parser.getTok().getLoc();
73 enum InfixCalculatorTok {
89 class InfixCalculator {
90 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
91 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
92 SmallVector<ICToken, 4> PostfixStack;
95 int64_t popOperand() {
96 assert (!PostfixStack.empty() && "Poped an empty stack!");
97 ICToken Op = PostfixStack.pop_back_val();
98 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
99 && "Expected and immediate or register!");
102 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
103 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
104 "Unexpected operand!");
105 PostfixStack.push_back(std::make_pair(Op, Val));
108 void popOperator() { InfixOperatorStack.pop_back(); }
109 void pushOperator(InfixCalculatorTok Op) {
110 // Push the new operator if the stack is empty.
111 if (InfixOperatorStack.empty()) {
112 InfixOperatorStack.push_back(Op);
116 // Push the new operator if it has a higher precedence than the operator
117 // on the top of the stack or the operator on the top of the stack is a
119 unsigned Idx = InfixOperatorStack.size() - 1;
120 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
121 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
122 InfixOperatorStack.push_back(Op);
126 // The operator on the top of the stack has higher precedence than the
128 unsigned ParenCount = 0;
130 // Nothing to process.
131 if (InfixOperatorStack.empty())
134 Idx = InfixOperatorStack.size() - 1;
135 StackOp = InfixOperatorStack[Idx];
136 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
139 // If we have an even parentheses count and we see a left parentheses,
140 // then stop processing.
141 if (!ParenCount && StackOp == IC_LPAREN)
144 if (StackOp == IC_RPAREN) {
146 InfixOperatorStack.pop_back();
147 } else if (StackOp == IC_LPAREN) {
149 InfixOperatorStack.pop_back();
151 InfixOperatorStack.pop_back();
152 PostfixStack.push_back(std::make_pair(StackOp, 0));
155 // Push the new operator.
156 InfixOperatorStack.push_back(Op);
160 // Push any remaining operators onto the postfix stack.
161 while (!InfixOperatorStack.empty()) {
162 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
163 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
164 PostfixStack.push_back(std::make_pair(StackOp, 0));
167 if (PostfixStack.empty())
170 SmallVector<ICToken, 16> OperandStack;
171 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
172 ICToken Op = PostfixStack[i];
173 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
174 OperandStack.push_back(Op);
176 assert (OperandStack.size() > 1 && "Too few operands.");
178 ICToken Op2 = OperandStack.pop_back_val();
179 ICToken Op1 = OperandStack.pop_back_val();
182 report_fatal_error("Unexpected operator!");
185 Val = Op1.second + Op2.second;
186 OperandStack.push_back(std::make_pair(IC_IMM, Val));
189 Val = Op1.second - Op2.second;
190 OperandStack.push_back(std::make_pair(IC_IMM, Val));
193 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
194 "Multiply operation with an immediate and a register!");
195 Val = Op1.second * Op2.second;
196 OperandStack.push_back(std::make_pair(IC_IMM, Val));
199 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
200 "Divide operation with an immediate and a register!");
201 assert (Op2.second != 0 && "Division by zero!");
202 Val = Op1.second / Op2.second;
203 OperandStack.push_back(std::make_pair(IC_IMM, Val));
206 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
207 "Or operation with an immediate and a register!");
208 Val = Op1.second | Op2.second;
209 OperandStack.push_back(std::make_pair(IC_IMM, Val));
212 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
213 "Xor operation with an immediate and a register!");
214 Val = Op1.second ^ Op2.second;
215 OperandStack.push_back(std::make_pair(IC_IMM, Val));
218 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
219 "And operation with an immediate and a register!");
220 Val = Op1.second & Op2.second;
221 OperandStack.push_back(std::make_pair(IC_IMM, Val));
224 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
225 "Left shift operation with an immediate and a register!");
226 Val = Op1.second << Op2.second;
227 OperandStack.push_back(std::make_pair(IC_IMM, Val));
230 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
231 "Right shift operation with an immediate and a register!");
232 Val = Op1.second >> Op2.second;
233 OperandStack.push_back(std::make_pair(IC_IMM, Val));
238 assert (OperandStack.size() == 1 && "Expected a single result.");
239 return OperandStack.pop_back_val().second;
243 enum IntelExprState {
264 class IntelExprStateMachine {
265 IntelExprState State, PrevState;
266 unsigned BaseReg, IndexReg, TmpReg, Scale;
270 bool StopOnLBrac, AddImmPrefix;
272 InlineAsmIdentifierInfo Info;
275 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
276 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
277 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
278 AddImmPrefix(addimmprefix) { Info.clear(); }
280 unsigned getBaseReg() { return BaseReg; }
281 unsigned getIndexReg() { return IndexReg; }
282 unsigned getScale() { return Scale; }
283 const MCExpr *getSym() { return Sym; }
284 StringRef getSymName() { return SymName; }
285 int64_t getImm() { return Imm + IC.execute(); }
286 bool isValidEndState() {
287 return State == IES_RBRAC || State == IES_INTEGER;
289 bool getStopOnLBrac() { return StopOnLBrac; }
290 bool getAddImmPrefix() { return AddImmPrefix; }
291 bool hadError() { return State == IES_ERROR; }
293 InlineAsmIdentifierInfo &getIdentifierInfo() {
298 IntelExprState CurrState = State;
307 IC.pushOperator(IC_OR);
310 PrevState = CurrState;
313 IntelExprState CurrState = State;
322 IC.pushOperator(IC_XOR);
325 PrevState = CurrState;
328 IntelExprState CurrState = State;
337 IC.pushOperator(IC_AND);
340 PrevState = CurrState;
343 IntelExprState CurrState = State;
352 IC.pushOperator(IC_LSHIFT);
355 PrevState = CurrState;
358 IntelExprState CurrState = State;
367 IC.pushOperator(IC_RSHIFT);
370 PrevState = CurrState;
373 IntelExprState CurrState = State;
382 IC.pushOperator(IC_PLUS);
383 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
384 // If we already have a BaseReg, then assume this is the IndexReg with
389 assert (!IndexReg && "BaseReg/IndexReg already set!");
396 PrevState = CurrState;
399 IntelExprState CurrState = State;
415 // Only push the minus operator if it is not a unary operator.
416 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
417 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
418 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
419 IC.pushOperator(IC_MINUS);
420 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
421 // If we already have a BaseReg, then assume this is the IndexReg with
426 assert (!IndexReg && "BaseReg/IndexReg already set!");
433 PrevState = CurrState;
436 IntelExprState CurrState = State;
446 PrevState = CurrState;
448 void onRegister(unsigned Reg) {
449 IntelExprState CurrState = State;
456 State = IES_REGISTER;
458 IC.pushOperand(IC_REGISTER);
461 // Index Register - Scale * Register
462 if (PrevState == IES_INTEGER) {
463 assert (!IndexReg && "IndexReg already set!");
464 State = IES_REGISTER;
466 // Get the scale and replace the 'Scale * Register' with '0'.
467 Scale = IC.popOperand();
468 IC.pushOperand(IC_IMM);
475 PrevState = CurrState;
477 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
488 SymName = SymRefName;
489 IC.pushOperand(IC_IMM);
493 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
494 IntelExprState CurrState = State;
511 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
512 // Index Register - Register * Scale
513 assert (!IndexReg && "IndexReg already set!");
516 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
517 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
520 // Get the scale and replace the 'Register * Scale' with '0'.
522 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
523 PrevState == IES_OR || PrevState == IES_AND ||
524 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
525 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
526 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
527 PrevState == IES_NOT || PrevState == IES_XOR) &&
528 CurrState == IES_MINUS) {
529 // Unary minus. No need to pop the minus operand because it was never
531 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
532 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
533 PrevState == IES_OR || PrevState == IES_AND ||
534 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
535 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
536 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
537 PrevState == IES_NOT || PrevState == IES_XOR) &&
538 CurrState == IES_NOT) {
539 // Unary not. No need to pop the not operand because it was never
541 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
543 IC.pushOperand(IC_IMM, TmpInt);
547 PrevState = CurrState;
559 State = IES_MULTIPLY;
560 IC.pushOperator(IC_MULTIPLY);
573 IC.pushOperator(IC_DIVIDE);
585 IC.pushOperator(IC_PLUS);
590 IntelExprState CurrState = State;
599 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
600 // If we already have a BaseReg, then assume this is the IndexReg with
605 assert (!IndexReg && "BaseReg/IndexReg already set!");
612 PrevState = CurrState;
615 IntelExprState CurrState = State;
631 // FIXME: We don't handle this type of unary minus or not, yet.
632 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
633 PrevState == IES_OR || PrevState == IES_AND ||
634 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
635 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
636 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
637 PrevState == IES_NOT || PrevState == IES_XOR) &&
638 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
643 IC.pushOperator(IC_LPAREN);
646 PrevState = CurrState;
658 IC.pushOperator(IC_RPAREN);
664 bool Error(SMLoc L, const Twine &Msg,
665 ArrayRef<SMRange> Ranges = None,
666 bool MatchingInlineAsm = false) {
667 MCAsmParser &Parser = getParser();
668 if (MatchingInlineAsm) return true;
669 return Parser.Error(L, Msg, Ranges);
672 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
673 ArrayRef<SMRange> Ranges = None,
674 bool MatchingInlineAsm = false) {
675 MCAsmParser &Parser = getParser();
676 Parser.eatToEndOfStatement();
677 return Error(L, Msg, Ranges, MatchingInlineAsm);
680 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
685 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
686 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
687 void AddDefaultSrcDestOperands(
688 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
689 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
690 std::unique_ptr<X86Operand> ParseOperand();
691 std::unique_ptr<X86Operand> ParseATTOperand();
692 std::unique_ptr<X86Operand> ParseIntelOperand();
693 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
694 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
695 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
696 std::unique_ptr<X86Operand>
697 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
698 std::unique_ptr<X86Operand>
699 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
700 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
701 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
702 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
706 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
707 InlineAsmIdentifierInfo &Info,
708 bool IsUnevaluatedOperand, SMLoc &End);
710 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
712 std::unique_ptr<X86Operand>
713 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
714 unsigned IndexReg, unsigned Scale, SMLoc Start,
715 SMLoc End, unsigned Size, StringRef Identifier,
716 InlineAsmIdentifierInfo &Info);
718 bool ParseDirectiveWord(unsigned Size, SMLoc L);
719 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
721 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
722 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
724 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
725 /// instrumentation around Inst.
726 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
728 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
729 OperandVector &Operands, MCStreamer &Out,
731 bool MatchingInlineAsm) override;
733 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
734 MCStreamer &Out, bool MatchingInlineAsm);
736 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
737 bool MatchingInlineAsm);
739 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
740 OperandVector &Operands, MCStreamer &Out,
742 bool MatchingInlineAsm);
744 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
745 OperandVector &Operands, MCStreamer &Out,
747 bool MatchingInlineAsm);
749 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
751 /// doSrcDstMatch - Returns true if operands are matching in their
752 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
753 /// the parsing mode (Intel vs. AT&T).
754 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
756 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
757 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
758 /// \return \c true if no parsing errors occurred, \c false otherwise.
759 bool HandleAVX512Operand(OperandVector &Operands,
760 const MCParsedAsmOperand &Op);
762 bool is64BitMode() const {
763 // FIXME: Can tablegen auto-generate this?
764 return STI.getFeatureBits()[X86::Mode64Bit];
766 bool is32BitMode() const {
767 // FIXME: Can tablegen auto-generate this?
768 return STI.getFeatureBits()[X86::Mode32Bit];
770 bool is16BitMode() const {
771 // FIXME: Can tablegen auto-generate this?
772 return STI.getFeatureBits()[X86::Mode16Bit];
774 void SwitchMode(unsigned mode) {
775 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
776 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
777 unsigned FB = ComputeAvailableFeatures(
778 STI.ToggleFeature(OldMode.flip(mode)));
779 setAvailableFeatures(FB);
781 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
784 unsigned getPointerWidth() {
785 if (is16BitMode()) return 16;
786 if (is32BitMode()) return 32;
787 if (is64BitMode()) return 64;
788 llvm_unreachable("invalid mode");
791 bool isParsingIntelSyntax() {
792 return getParser().getAssemblerDialect();
795 /// @name Auto-generated Matcher Functions
798 #define GET_ASSEMBLER_HEADER
799 #include "X86GenAsmMatcher.inc"
804 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &Parser,
805 const MCInstrInfo &mii, const MCTargetOptions &Options)
806 : MCTargetAsmParser(Options), STI(sti), MII(mii), InstInfo(nullptr) {
808 // Initialize the set of available features.
809 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
810 Instrumentation.reset(
811 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
814 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
816 void SetFrameRegister(unsigned RegNo) override;
818 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
819 SMLoc NameLoc, OperandVector &Operands) override;
821 bool ParseDirective(AsmToken DirectiveID) override;
823 } // end anonymous namespace
825 /// @name Auto-generated Match Functions
828 static unsigned MatchRegisterName(StringRef Name);
832 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
834 // If we have both a base register and an index register make sure they are
835 // both 64-bit or 32-bit registers.
836 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
837 if (BaseReg != 0 && IndexReg != 0) {
838 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
839 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
840 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
841 IndexReg != X86::RIZ) {
842 ErrMsg = "base register is 64-bit, but index register is not";
845 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
846 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
847 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
848 IndexReg != X86::EIZ){
849 ErrMsg = "base register is 32-bit, but index register is not";
852 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
853 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
854 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
855 ErrMsg = "base register is 16-bit, but index register is not";
858 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
859 IndexReg != X86::SI && IndexReg != X86::DI) ||
860 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
861 IndexReg != X86::BX && IndexReg != X86::BP)) {
862 ErrMsg = "invalid 16-bit base/index register combination";
870 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
872 // Return true and let a normal complaint about bogus operands happen.
873 if (!Op1.isMem() || !Op2.isMem())
876 // Actually these might be the other way round if Intel syntax is
877 // being used. It doesn't matter.
878 unsigned diReg = Op1.Mem.BaseReg;
879 unsigned siReg = Op2.Mem.BaseReg;
881 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
882 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
883 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
884 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
885 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
886 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
887 // Again, return true and let another error happen.
891 bool X86AsmParser::ParseRegister(unsigned &RegNo,
892 SMLoc &StartLoc, SMLoc &EndLoc) {
893 MCAsmParser &Parser = getParser();
895 const AsmToken &PercentTok = Parser.getTok();
896 StartLoc = PercentTok.getLoc();
898 // If we encounter a %, ignore it. This code handles registers with and
899 // without the prefix, unprefixed registers can occur in cfi directives.
900 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
901 Parser.Lex(); // Eat percent token.
903 const AsmToken &Tok = Parser.getTok();
904 EndLoc = Tok.getEndLoc();
906 if (Tok.isNot(AsmToken::Identifier)) {
907 if (isParsingIntelSyntax()) return true;
908 return Error(StartLoc, "invalid register name",
909 SMRange(StartLoc, EndLoc));
912 RegNo = MatchRegisterName(Tok.getString());
914 // If the match failed, try the register name as lowercase.
916 RegNo = MatchRegisterName(Tok.getString().lower());
918 // The "flags" register cannot be referenced directly.
919 // Treat it as an identifier instead.
920 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
923 if (!is64BitMode()) {
924 // FIXME: This should be done using Requires<Not64BitMode> and
925 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
927 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
929 if (RegNo == X86::RIZ ||
930 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
931 X86II::isX86_64NonExtLowByteReg(RegNo) ||
932 X86II::isX86_64ExtendedReg(RegNo))
933 return Error(StartLoc, "register %"
934 + Tok.getString() + " is only available in 64-bit mode",
935 SMRange(StartLoc, EndLoc));
938 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
939 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
941 Parser.Lex(); // Eat 'st'
943 // Check to see if we have '(4)' after %st.
944 if (getLexer().isNot(AsmToken::LParen))
949 const AsmToken &IntTok = Parser.getTok();
950 if (IntTok.isNot(AsmToken::Integer))
951 return Error(IntTok.getLoc(), "expected stack index");
952 switch (IntTok.getIntVal()) {
953 case 0: RegNo = X86::ST0; break;
954 case 1: RegNo = X86::ST1; break;
955 case 2: RegNo = X86::ST2; break;
956 case 3: RegNo = X86::ST3; break;
957 case 4: RegNo = X86::ST4; break;
958 case 5: RegNo = X86::ST5; break;
959 case 6: RegNo = X86::ST6; break;
960 case 7: RegNo = X86::ST7; break;
961 default: return Error(IntTok.getLoc(), "invalid stack index");
964 if (getParser().Lex().isNot(AsmToken::RParen))
965 return Error(Parser.getTok().getLoc(), "expected ')'");
967 EndLoc = Parser.getTok().getEndLoc();
968 Parser.Lex(); // Eat ')'
972 EndLoc = Parser.getTok().getEndLoc();
974 // If this is "db[0-7]", match it as an alias
976 if (RegNo == 0 && Tok.getString().size() == 3 &&
977 Tok.getString().startswith("db")) {
978 switch (Tok.getString()[2]) {
979 case '0': RegNo = X86::DR0; break;
980 case '1': RegNo = X86::DR1; break;
981 case '2': RegNo = X86::DR2; break;
982 case '3': RegNo = X86::DR3; break;
983 case '4': RegNo = X86::DR4; break;
984 case '5': RegNo = X86::DR5; break;
985 case '6': RegNo = X86::DR6; break;
986 case '7': RegNo = X86::DR7; break;
990 EndLoc = Parser.getTok().getEndLoc();
991 Parser.Lex(); // Eat it.
997 if (isParsingIntelSyntax()) return true;
998 return Error(StartLoc, "invalid register name",
999 SMRange(StartLoc, EndLoc));
1002 Parser.Lex(); // Eat identifier token.
1006 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1007 Instrumentation->SetInitialFrameRegister(RegNo);
1010 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1012 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1013 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1014 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1015 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1019 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1021 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1022 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1023 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1024 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1028 void X86AsmParser::AddDefaultSrcDestOperands(
1029 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1030 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1031 if (isParsingIntelSyntax()) {
1032 Operands.push_back(std::move(Dst));
1033 Operands.push_back(std::move(Src));
1036 Operands.push_back(std::move(Src));
1037 Operands.push_back(std::move(Dst));
1041 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1042 if (isParsingIntelSyntax())
1043 return ParseIntelOperand();
1044 return ParseATTOperand();
1047 /// getIntelMemOperandSize - Return intel memory operand size.
1048 static unsigned getIntelMemOperandSize(StringRef OpStr) {
1049 unsigned Size = StringSwitch<unsigned>(OpStr)
1050 .Cases("BYTE", "byte", 8)
1051 .Cases("WORD", "word", 16)
1052 .Cases("DWORD", "dword", 32)
1053 .Cases("QWORD", "qword", 64)
1054 .Cases("MMWORD","mmword", 64)
1055 .Cases("XWORD", "xword", 80)
1056 .Cases("TBYTE", "tbyte", 80)
1057 .Cases("XMMWORD", "xmmword", 128)
1058 .Cases("YMMWORD", "ymmword", 256)
1059 .Cases("ZMMWORD", "zmmword", 512)
1060 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1065 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1066 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1067 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1068 InlineAsmIdentifierInfo &Info) {
1069 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1070 // some other label reference.
1071 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1072 // Insert an explicit size if the user didn't have one.
1074 Size = getPointerWidth();
1075 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1079 // Create an absolute memory reference in order to match against
1080 // instructions taking a PC relative operand.
1081 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1082 Identifier, Info.OpDecl);
1085 // We either have a direct symbol reference, or an offset from a symbol. The
1086 // parser always puts the symbol on the LHS, so look there for size
1087 // calculation purposes.
1088 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1090 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1093 Size = Info.Type * 8; // Size is in terms of bits in this context.
1095 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
1100 // When parsing inline assembly we set the base register to a non-zero value
1101 // if we don't know the actual value at this time. This is necessary to
1102 // get the matching correct in some cases.
1103 BaseReg = BaseReg ? BaseReg : 1;
1104 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1105 IndexReg, Scale, Start, End, Size, Identifier,
1110 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> &AsmRewrites,
1111 StringRef SymName, int64_t ImmDisp,
1112 int64_t FinalImmDisp, SMLoc &BracLoc,
1113 SMLoc &StartInBrac, SMLoc &End) {
1114 // Remove the '[' and ']' from the IR string.
1115 AsmRewrites.emplace_back(AOK_Skip, BracLoc, 1);
1116 AsmRewrites.emplace_back(AOK_Skip, End, 1);
1118 // If ImmDisp is non-zero, then we parsed a displacement before the
1119 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1120 // If ImmDisp doesn't match the displacement computed by the state machine
1121 // then we have an additional displacement in the bracketed expression.
1122 if (ImmDisp != FinalImmDisp) {
1124 // We have an immediate displacement before the bracketed expression.
1125 // Adjust this to match the final immediate displacement.
1127 for (AsmRewrite &AR : AsmRewrites) {
1128 if (AR.Loc.getPointer() > BracLoc.getPointer())
1130 if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm) {
1131 assert (!Found && "ImmDisp already rewritten.");
1133 AR.Len = BracLoc.getPointer() - AR.Loc.getPointer();
1134 AR.Val = FinalImmDisp;
1139 assert (Found && "Unable to rewrite ImmDisp.");
1142 // We have a symbolic and an immediate displacement, but no displacement
1143 // before the bracketed expression. Put the immediate displacement
1144 // before the bracketed expression.
1145 AsmRewrites.emplace_back(AOK_Imm, BracLoc, 0, FinalImmDisp);
1148 // Remove all the ImmPrefix rewrites within the brackets.
1149 for (AsmRewrite &AR : AsmRewrites) {
1150 if (AR.Loc.getPointer() < StartInBrac.getPointer())
1152 if (AR.Kind == AOK_ImmPrefix)
1153 AR.Kind = AOK_Delete;
1155 const char *SymLocPtr = SymName.data();
1156 // Skip everything before the symbol.
1157 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1158 assert(Len > 0 && "Expected a non-negative length.");
1159 AsmRewrites.emplace_back(AOK_Skip, StartInBrac, Len);
1161 // Skip everything after the symbol.
1162 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1163 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1164 assert(Len > 0 && "Expected a non-negative length.");
1165 AsmRewrites.emplace_back(AOK_Skip, Loc, Len);
1169 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1170 MCAsmParser &Parser = getParser();
1171 const AsmToken &Tok = Parser.getTok();
1175 bool UpdateLocLex = true;
1177 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1178 // identifier. Don't try an parse it as a register.
1179 if (Tok.getString().startswith("."))
1182 // If we're parsing an immediate expression, we don't expect a '['.
1183 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1186 AsmToken::TokenKind TK = getLexer().getKind();
1189 if (SM.isValidEndState()) {
1193 return Error(Tok.getLoc(), "unknown token in expression");
1195 case AsmToken::EndOfStatement: {
1199 case AsmToken::String:
1200 case AsmToken::Identifier: {
1201 // This could be a register or a symbolic displacement.
1204 SMLoc IdentLoc = Tok.getLoc();
1205 StringRef Identifier = Tok.getString();
1206 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1207 SM.onRegister(TmpReg);
1208 UpdateLocLex = false;
1211 if (!isParsingInlineAsm()) {
1212 if (getParser().parsePrimaryExpr(Val, End))
1213 return Error(Tok.getLoc(), "Unexpected identifier!");
1215 // This is a dot operator, not an adjacent identifier.
1216 if (Identifier.find('.') != StringRef::npos) {
1219 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1220 if (ParseIntelIdentifier(Val, Identifier, Info,
1221 /*Unevaluated=*/false, End))
1225 SM.onIdentifierExpr(Val, Identifier);
1226 UpdateLocLex = false;
1229 return Error(Tok.getLoc(), "Unexpected identifier!");
1231 case AsmToken::Integer: {
1233 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1234 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Tok.getLoc());
1235 // Look for 'b' or 'f' following an Integer as a directional label
1236 SMLoc Loc = getTok().getLoc();
1237 int64_t IntVal = getTok().getIntVal();
1238 End = consumeToken();
1239 UpdateLocLex = false;
1240 if (getLexer().getKind() == AsmToken::Identifier) {
1241 StringRef IDVal = getTok().getString();
1242 if (IDVal == "f" || IDVal == "b") {
1244 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1245 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1247 MCSymbolRefExpr::create(Sym, Variant, getContext());
1248 if (IDVal == "b" && Sym->isUndefined())
1249 return Error(Loc, "invalid reference to undefined symbol");
1250 StringRef Identifier = Sym->getName();
1251 SM.onIdentifierExpr(Val, Identifier);
1252 End = consumeToken();
1254 if (SM.onInteger(IntVal, ErrMsg))
1255 return Error(Loc, ErrMsg);
1258 if (SM.onInteger(IntVal, ErrMsg))
1259 return Error(Loc, ErrMsg);
1263 case AsmToken::Plus: SM.onPlus(); break;
1264 case AsmToken::Minus: SM.onMinus(); break;
1265 case AsmToken::Tilde: SM.onNot(); break;
1266 case AsmToken::Star: SM.onStar(); break;
1267 case AsmToken::Slash: SM.onDivide(); break;
1268 case AsmToken::Pipe: SM.onOr(); break;
1269 case AsmToken::Caret: SM.onXor(); break;
1270 case AsmToken::Amp: SM.onAnd(); break;
1271 case AsmToken::LessLess:
1272 SM.onLShift(); break;
1273 case AsmToken::GreaterGreater:
1274 SM.onRShift(); break;
1275 case AsmToken::LBrac: SM.onLBrac(); break;
1276 case AsmToken::RBrac: SM.onRBrac(); break;
1277 case AsmToken::LParen: SM.onLParen(); break;
1278 case AsmToken::RParen: SM.onRParen(); break;
1281 return Error(Tok.getLoc(), "unknown token in expression");
1283 if (!Done && UpdateLocLex)
1284 End = consumeToken();
1289 std::unique_ptr<X86Operand>
1290 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1291 int64_t ImmDisp, unsigned Size) {
1292 MCAsmParser &Parser = getParser();
1293 const AsmToken &Tok = Parser.getTok();
1294 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1295 if (getLexer().isNot(AsmToken::LBrac))
1296 return ErrorOperand(BracLoc, "Expected '[' token!");
1297 Parser.Lex(); // Eat '['
1299 SMLoc StartInBrac = Tok.getLoc();
1300 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1301 // may have already parsed an immediate displacement before the bracketed
1303 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1304 if (ParseIntelExpression(SM, End))
1307 const MCExpr *Disp = nullptr;
1308 if (const MCExpr *Sym = SM.getSym()) {
1309 // A symbolic displacement.
1311 if (isParsingInlineAsm())
1312 RewriteIntelBracExpression(*InstInfo->AsmRewrites, SM.getSymName(),
1313 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1317 if (SM.getImm() || !Disp) {
1318 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1320 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1322 Disp = Imm; // An immediate displacement only.
1325 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1326 // will in fact do global lookup the field name inside all global typedefs,
1327 // but we don't emulate that.
1328 if (Tok.getString().find('.') != StringRef::npos) {
1329 const MCExpr *NewDisp;
1330 if (ParseIntelDotOperator(Disp, NewDisp))
1333 End = Tok.getEndLoc();
1334 Parser.Lex(); // Eat the field.
1338 int BaseReg = SM.getBaseReg();
1339 int IndexReg = SM.getIndexReg();
1340 int Scale = SM.getScale();
1341 if (!isParsingInlineAsm()) {
1343 if (!BaseReg && !IndexReg) {
1345 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1346 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1350 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1351 Error(StartInBrac, ErrMsg);
1354 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1355 IndexReg, Scale, Start, End, Size);
1358 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1359 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1360 End, Size, SM.getSymName(), Info);
1363 // Inline assembly may use variable names with namespace alias qualifiers.
1364 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1365 StringRef &Identifier,
1366 InlineAsmIdentifierInfo &Info,
1367 bool IsUnevaluatedOperand, SMLoc &End) {
1368 MCAsmParser &Parser = getParser();
1369 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1372 StringRef LineBuf(Identifier.data());
1374 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1376 const AsmToken &Tok = Parser.getTok();
1377 SMLoc Loc = Tok.getLoc();
1379 // Advance the token stream until the end of the current token is
1380 // after the end of what the frontend claimed.
1381 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1383 End = Tok.getEndLoc();
1385 } while (End.getPointer() < EndPtr);
1386 Identifier = LineBuf;
1388 // The frontend should end parsing on an assembler token boundary, unless it
1390 assert((End.getPointer() == EndPtr || !Result) &&
1391 "frontend claimed part of a token?");
1393 // If the identifier lookup was unsuccessful, assume that we are dealing with
1396 StringRef InternalName =
1397 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1399 assert(InternalName.size() && "We should have an internal name here.");
1400 // Push a rewrite for replacing the identifier name with the internal name.
1401 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1405 // Create the symbol reference.
1406 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1407 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1408 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1412 /// \brief Parse intel style segment override.
1413 std::unique_ptr<X86Operand>
1414 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1416 MCAsmParser &Parser = getParser();
1417 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1418 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1419 if (Tok.isNot(AsmToken::Colon))
1420 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1421 Parser.Lex(); // Eat ':'
1423 int64_t ImmDisp = 0;
1424 if (getLexer().is(AsmToken::Integer)) {
1425 ImmDisp = Tok.getIntVal();
1426 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1428 if (isParsingInlineAsm())
1429 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, ImmDispToken.getLoc());
1431 if (getLexer().isNot(AsmToken::LBrac)) {
1432 // An immediate following a 'segment register', 'colon' token sequence can
1433 // be followed by a bracketed expression. If it isn't we know we have our
1434 // final segment override.
1435 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1436 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1437 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1438 Start, ImmDispToken.getEndLoc(), Size);
1442 if (getLexer().is(AsmToken::LBrac))
1443 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1447 if (!isParsingInlineAsm()) {
1448 if (getParser().parsePrimaryExpr(Val, End))
1449 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1451 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1454 InlineAsmIdentifierInfo Info;
1455 StringRef Identifier = Tok.getString();
1456 if (ParseIntelIdentifier(Val, Identifier, Info,
1457 /*Unevaluated=*/false, End))
1459 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1460 /*Scale=*/1, Start, End, Size, Identifier, Info);
1463 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1464 std::unique_ptr<X86Operand>
1465 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1466 MCAsmParser &Parser = getParser();
1467 const AsmToken &Tok = Parser.getTok();
1468 // Eat "{" and mark the current place.
1469 const SMLoc consumedToken = consumeToken();
1470 if (Tok.getIdentifier().startswith("r")){
1471 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1472 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1473 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1474 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1475 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1478 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1479 Parser.Lex(); // Eat "r*" of r*-sae
1480 if (!getLexer().is(AsmToken::Minus))
1481 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1482 Parser.Lex(); // Eat "-"
1483 Parser.Lex(); // Eat the sae
1484 if (!getLexer().is(AsmToken::RCurly))
1485 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1486 Parser.Lex(); // Eat "}"
1487 const MCExpr *RndModeOp =
1488 MCConstantExpr::create(rndMode, Parser.getContext());
1489 return X86Operand::CreateImm(RndModeOp, Start, End);
1491 if(Tok.getIdentifier().equals("sae")){
1492 Parser.Lex(); // Eat the sae
1493 if (!getLexer().is(AsmToken::RCurly))
1494 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1495 Parser.Lex(); // Eat "}"
1496 return X86Operand::CreateToken("{sae}", consumedToken);
1498 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1500 /// ParseIntelMemOperand - Parse intel style memory operand.
1501 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1504 MCAsmParser &Parser = getParser();
1505 const AsmToken &Tok = Parser.getTok();
1508 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1509 if (getLexer().is(AsmToken::LBrac))
1510 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1511 assert(ImmDisp == 0);
1514 if (!isParsingInlineAsm()) {
1515 if (getParser().parsePrimaryExpr(Val, End))
1516 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1518 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1521 InlineAsmIdentifierInfo Info;
1522 StringRef Identifier = Tok.getString();
1523 if (ParseIntelIdentifier(Val, Identifier, Info,
1524 /*Unevaluated=*/false, End))
1527 if (!getLexer().is(AsmToken::LBrac))
1528 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1529 /*Scale=*/1, Start, End, Size, Identifier, Info);
1531 Parser.Lex(); // Eat '['
1533 // Parse Identifier [ ImmDisp ]
1534 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1535 /*AddImmPrefix=*/false);
1536 if (ParseIntelExpression(SM, End))
1540 Error(Start, "cannot use more than one symbol in memory operand");
1543 if (SM.getBaseReg()) {
1544 Error(Start, "cannot use base register with variable reference");
1547 if (SM.getIndexReg()) {
1548 Error(Start, "cannot use index register with variable reference");
1552 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1553 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1554 // we're pointing to a local variable in memory, so the base register is
1555 // really the frame or stack pointer.
1556 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1557 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1558 Start, End, Size, Identifier, Info.OpDecl);
1561 /// Parse the '.' operator.
1562 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1563 const MCExpr *&NewDisp) {
1564 MCAsmParser &Parser = getParser();
1565 const AsmToken &Tok = Parser.getTok();
1566 int64_t OrigDispVal, DotDispVal;
1568 // FIXME: Handle non-constant expressions.
1569 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1570 OrigDispVal = OrigDisp->getValue();
1572 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1574 // Drop the optional '.'.
1575 StringRef DotDispStr = Tok.getString();
1576 if (DotDispStr.startswith("."))
1577 DotDispStr = DotDispStr.drop_front(1);
1579 // .Imm gets lexed as a real.
1580 if (Tok.is(AsmToken::Real)) {
1582 DotDispStr.getAsInteger(10, DotDisp);
1583 DotDispVal = DotDisp.getZExtValue();
1584 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1586 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1587 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1589 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1590 DotDispVal = DotDisp;
1592 return Error(Tok.getLoc(), "Unexpected token type!");
1594 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1595 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1596 unsigned Len = DotDispStr.size();
1597 unsigned Val = OrigDispVal + DotDispVal;
1598 InstInfo->AsmRewrites->emplace_back(AOK_DotOperator, Loc, Len, Val);
1601 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1605 /// Parse the 'offset' operator. This operator is used to specify the
1606 /// location rather then the content of a variable.
1607 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1608 MCAsmParser &Parser = getParser();
1609 const AsmToken &Tok = Parser.getTok();
1610 SMLoc OffsetOfLoc = Tok.getLoc();
1611 Parser.Lex(); // Eat offset.
1614 InlineAsmIdentifierInfo Info;
1615 SMLoc Start = Tok.getLoc(), End;
1616 StringRef Identifier = Tok.getString();
1617 if (ParseIntelIdentifier(Val, Identifier, Info,
1618 /*Unevaluated=*/false, End))
1621 // Don't emit the offset operator.
1622 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1624 // The offset operator will have an 'r' constraint, thus we need to create
1625 // register operand to ensure proper matching. Just pick a GPR based on
1626 // the size of a pointer.
1628 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1629 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1630 OffsetOfLoc, Identifier, Info.OpDecl);
1633 enum IntelOperatorKind {
1639 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1640 /// returns the number of elements in an array. It returns the value 1 for
1641 /// non-array variables. The SIZE operator returns the size of a C or C++
1642 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1643 /// TYPE operator returns the size of a C or C++ type or variable. If the
1644 /// variable is an array, TYPE returns the size of a single element.
1645 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1646 MCAsmParser &Parser = getParser();
1647 const AsmToken &Tok = Parser.getTok();
1648 SMLoc TypeLoc = Tok.getLoc();
1649 Parser.Lex(); // Eat operator.
1651 const MCExpr *Val = nullptr;
1652 InlineAsmIdentifierInfo Info;
1653 SMLoc Start = Tok.getLoc(), End;
1654 StringRef Identifier = Tok.getString();
1655 if (ParseIntelIdentifier(Val, Identifier, Info,
1656 /*Unevaluated=*/true, End))
1660 return ErrorOperand(Start, "unable to lookup expression");
1664 default: llvm_unreachable("Unexpected operand kind!");
1665 case IOK_LENGTH: CVal = Info.Length; break;
1666 case IOK_SIZE: CVal = Info.Size; break;
1667 case IOK_TYPE: CVal = Info.Type; break;
1670 // Rewrite the type operator and the C or C++ type or variable in terms of an
1671 // immediate. E.g. TYPE foo -> $$4
1672 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1673 InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
1675 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1676 return X86Operand::CreateImm(Imm, Start, End);
1679 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1680 MCAsmParser &Parser = getParser();
1681 const AsmToken &Tok = Parser.getTok();
1684 // Offset, length, type and size operators.
1685 if (isParsingInlineAsm()) {
1686 StringRef AsmTokStr = Tok.getString();
1687 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1688 return ParseIntelOffsetOfOperator();
1689 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1690 return ParseIntelOperator(IOK_LENGTH);
1691 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1692 return ParseIntelOperator(IOK_SIZE);
1693 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1694 return ParseIntelOperator(IOK_TYPE);
1697 unsigned Size = getIntelMemOperandSize(Tok.getString());
1699 Parser.Lex(); // Eat operand size (e.g., byte, word).
1700 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1701 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1702 Parser.Lex(); // Eat ptr.
1704 Start = Tok.getLoc();
1707 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1708 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1709 AsmToken StartTok = Tok;
1710 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1711 /*AddImmPrefix=*/false);
1712 if (ParseIntelExpression(SM, End))
1715 int64_t Imm = SM.getImm();
1716 if (isParsingInlineAsm()) {
1717 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1718 if (StartTok.getString().size() == Len)
1719 // Just add a prefix if this wasn't a complex immediate expression.
1720 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1722 // Otherwise, rewrite the complex expression as a single immediate.
1723 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1726 if (getLexer().isNot(AsmToken::LBrac)) {
1727 // If a directional label (ie. 1f or 2b) was parsed above from
1728 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1729 // to the MCExpr with the directional local symbol and this is a
1730 // memory operand not an immediate operand.
1732 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1735 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1736 return X86Operand::CreateImm(ImmExpr, Start, End);
1739 // Only positive immediates are valid.
1741 return ErrorOperand(Start, "expected a positive immediate displacement "
1742 "before bracketed expr.");
1744 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1745 return ParseIntelMemOperand(Imm, Start, Size);
1748 // rounding mode token
1749 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1750 getLexer().is(AsmToken::LCurly))
1751 return ParseRoundingModeOp(Start, End);
1755 if (!ParseRegister(RegNo, Start, End)) {
1756 // If this is a segment register followed by a ':', then this is the start
1757 // of a segment override, otherwise this is a normal register reference.
1758 if (getLexer().isNot(AsmToken::Colon))
1759 return X86Operand::CreateReg(RegNo, Start, End);
1761 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1765 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1768 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1769 MCAsmParser &Parser = getParser();
1770 switch (getLexer().getKind()) {
1772 // Parse a memory operand with no segment register.
1773 return ParseMemOperand(0, Parser.getTok().getLoc());
1774 case AsmToken::Percent: {
1775 // Read the register.
1778 if (ParseRegister(RegNo, Start, End)) return nullptr;
1779 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1780 Error(Start, "%eiz and %riz can only be used as index registers",
1781 SMRange(Start, End));
1785 // If this is a segment register followed by a ':', then this is the start
1786 // of a memory reference, otherwise this is a normal register reference.
1787 if (getLexer().isNot(AsmToken::Colon))
1788 return X86Operand::CreateReg(RegNo, Start, End);
1790 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1791 return ErrorOperand(Start, "invalid segment register");
1793 getParser().Lex(); // Eat the colon.
1794 return ParseMemOperand(RegNo, Start);
1796 case AsmToken::Dollar: {
1797 // $42 -> immediate.
1798 SMLoc Start = Parser.getTok().getLoc(), End;
1801 if (getParser().parseExpression(Val, End))
1803 return X86Operand::CreateImm(Val, Start, End);
1805 case AsmToken::LCurly:{
1806 SMLoc Start = Parser.getTok().getLoc(), End;
1807 if (STI.getFeatureBits()[X86::FeatureAVX512])
1808 return ParseRoundingModeOp(Start, End);
1809 return ErrorOperand(Start, "unknown token in expression");
1814 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1815 const MCParsedAsmOperand &Op) {
1816 MCAsmParser &Parser = getParser();
1817 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1818 if (getLexer().is(AsmToken::LCurly)) {
1819 // Eat "{" and mark the current place.
1820 const SMLoc consumedToken = consumeToken();
1821 // Distinguish {1to<NUM>} from {%k<NUM>}.
1822 if(getLexer().is(AsmToken::Integer)) {
1823 // Parse memory broadcasting ({1to<NUM>}).
1824 if (getLexer().getTok().getIntVal() != 1)
1825 return !ErrorAndEatStatement(getLexer().getLoc(),
1826 "Expected 1to<NUM> at this point");
1827 Parser.Lex(); // Eat "1" of 1to8
1828 if (!getLexer().is(AsmToken::Identifier) ||
1829 !getLexer().getTok().getIdentifier().startswith("to"))
1830 return !ErrorAndEatStatement(getLexer().getLoc(),
1831 "Expected 1to<NUM> at this point");
1832 // Recognize only reasonable suffixes.
1833 const char *BroadcastPrimitive =
1834 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1835 .Case("to2", "{1to2}")
1836 .Case("to4", "{1to4}")
1837 .Case("to8", "{1to8}")
1838 .Case("to16", "{1to16}")
1840 if (!BroadcastPrimitive)
1841 return !ErrorAndEatStatement(getLexer().getLoc(),
1842 "Invalid memory broadcast primitive.");
1843 Parser.Lex(); // Eat "toN" of 1toN
1844 if (!getLexer().is(AsmToken::RCurly))
1845 return !ErrorAndEatStatement(getLexer().getLoc(),
1846 "Expected } at this point");
1847 Parser.Lex(); // Eat "}"
1848 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1850 // No AVX512 specific primitives can pass
1851 // after memory broadcasting, so return.
1854 // Parse mask register {%k1}
1855 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1856 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1857 Operands.push_back(std::move(Op));
1858 if (!getLexer().is(AsmToken::RCurly))
1859 return !ErrorAndEatStatement(getLexer().getLoc(),
1860 "Expected } at this point");
1861 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1863 // Parse "zeroing non-masked" semantic {z}
1864 if (getLexer().is(AsmToken::LCurly)) {
1865 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1866 if (!getLexer().is(AsmToken::Identifier) ||
1867 getLexer().getTok().getIdentifier() != "z")
1868 return !ErrorAndEatStatement(getLexer().getLoc(),
1869 "Expected z at this point");
1870 Parser.Lex(); // Eat the z
1871 if (!getLexer().is(AsmToken::RCurly))
1872 return !ErrorAndEatStatement(getLexer().getLoc(),
1873 "Expected } at this point");
1874 Parser.Lex(); // Eat the }
1883 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1884 /// has already been parsed if present.
1885 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1888 MCAsmParser &Parser = getParser();
1889 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1890 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1891 // only way to do this without lookahead is to eat the '(' and see what is
1893 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1894 if (getLexer().isNot(AsmToken::LParen)) {
1896 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1898 // After parsing the base expression we could either have a parenthesized
1899 // memory address or not. If not, return now. If so, eat the (.
1900 if (getLexer().isNot(AsmToken::LParen)) {
1901 // Unless we have a segment register, treat this as an immediate.
1903 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1904 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1911 // Okay, we have a '('. We don't know if this is an expression or not, but
1912 // so we have to eat the ( to see beyond it.
1913 SMLoc LParenLoc = Parser.getTok().getLoc();
1914 Parser.Lex(); // Eat the '('.
1916 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1917 // Nothing to do here, fall into the code below with the '(' part of the
1918 // memory operand consumed.
1922 // It must be an parenthesized expression, parse it now.
1923 if (getParser().parseParenExpression(Disp, ExprEnd))
1926 // After parsing the base expression we could either have a parenthesized
1927 // memory address or not. If not, return now. If so, eat the (.
1928 if (getLexer().isNot(AsmToken::LParen)) {
1929 // Unless we have a segment register, treat this as an immediate.
1931 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1933 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1942 // If we reached here, then we just ate the ( of the memory operand. Process
1943 // the rest of the memory operand.
1944 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1945 SMLoc IndexLoc, BaseLoc;
1947 if (getLexer().is(AsmToken::Percent)) {
1948 SMLoc StartLoc, EndLoc;
1949 BaseLoc = Parser.getTok().getLoc();
1950 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1951 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1952 Error(StartLoc, "eiz and riz can only be used as index registers",
1953 SMRange(StartLoc, EndLoc));
1958 if (getLexer().is(AsmToken::Comma)) {
1959 Parser.Lex(); // Eat the comma.
1960 IndexLoc = Parser.getTok().getLoc();
1962 // Following the comma we should have either an index register, or a scale
1963 // value. We don't support the later form, but we want to parse it
1966 // Not that even though it would be completely consistent to support syntax
1967 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1968 if (getLexer().is(AsmToken::Percent)) {
1970 if (ParseRegister(IndexReg, L, L)) return nullptr;
1972 if (getLexer().isNot(AsmToken::RParen)) {
1973 // Parse the scale amount:
1974 // ::= ',' [scale-expression]
1975 if (getLexer().isNot(AsmToken::Comma)) {
1976 Error(Parser.getTok().getLoc(),
1977 "expected comma in scale expression");
1980 Parser.Lex(); // Eat the comma.
1982 if (getLexer().isNot(AsmToken::RParen)) {
1983 SMLoc Loc = Parser.getTok().getLoc();
1986 if (getParser().parseAbsoluteExpression(ScaleVal)){
1987 Error(Loc, "expected scale expression");
1991 // Validate the scale amount.
1992 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1994 Error(Loc, "scale factor in 16-bit address must be 1");
1997 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
1999 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2002 Scale = (unsigned)ScaleVal;
2005 } else if (getLexer().isNot(AsmToken::RParen)) {
2006 // A scale amount without an index is ignored.
2008 SMLoc Loc = Parser.getTok().getLoc();
2011 if (getParser().parseAbsoluteExpression(Value))
2015 Warning(Loc, "scale factor without index register is ignored");
2020 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2021 if (getLexer().isNot(AsmToken::RParen)) {
2022 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2025 SMLoc MemEnd = Parser.getTok().getEndLoc();
2026 Parser.Lex(); // Eat the ')'.
2028 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2029 // and then only in non-64-bit modes. Except for DX, which is a special case
2030 // because an unofficial form of in/out instructions uses it.
2031 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2032 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2033 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2034 BaseReg != X86::DX) {
2035 Error(BaseLoc, "invalid 16-bit base register");
2039 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2040 Error(IndexLoc, "16-bit memory operand may not include only index register");
2045 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2046 Error(BaseLoc, ErrMsg);
2050 if (SegReg || BaseReg || IndexReg)
2051 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2052 IndexReg, Scale, MemStart, MemEnd);
2053 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2056 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2057 SMLoc NameLoc, OperandVector &Operands) {
2058 MCAsmParser &Parser = getParser();
2060 StringRef PatchedName = Name;
2062 // FIXME: Hack to recognize setneb as setne.
2063 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2064 PatchedName != "setb" && PatchedName != "setnb")
2065 PatchedName = PatchedName.substr(0, Name.size()-1);
2067 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2068 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2069 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2070 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2071 bool IsVCMP = PatchedName[0] == 'v';
2072 unsigned CCIdx = IsVCMP ? 4 : 3;
2073 unsigned ComparisonCode = StringSwitch<unsigned>(
2074 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2078 .Case("unord", 0x03)
2083 /* AVX only from here */
2084 .Case("eq_uq", 0x08)
2087 .Case("false", 0x0B)
2088 .Case("neq_oq", 0x0C)
2092 .Case("eq_os", 0x10)
2093 .Case("lt_oq", 0x11)
2094 .Case("le_oq", 0x12)
2095 .Case("unord_s", 0x13)
2096 .Case("neq_us", 0x14)
2097 .Case("nlt_uq", 0x15)
2098 .Case("nle_uq", 0x16)
2099 .Case("ord_s", 0x17)
2100 .Case("eq_us", 0x18)
2101 .Case("nge_uq", 0x19)
2102 .Case("ngt_uq", 0x1A)
2103 .Case("false_os", 0x1B)
2104 .Case("neq_os", 0x1C)
2105 .Case("ge_oq", 0x1D)
2106 .Case("gt_oq", 0x1E)
2107 .Case("true_us", 0x1F)
2109 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2111 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2114 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2115 getParser().getContext());
2116 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2118 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2122 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2123 if (PatchedName.startswith("vpcmp") &&
2124 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2125 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2126 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2127 unsigned ComparisonCode = StringSwitch<unsigned>(
2128 PatchedName.slice(5, PatchedName.size() - CCIdx))
2129 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2132 //.Case("false", 0x3) // Not a documented alias.
2136 //.Case("true", 0x7) // Not a documented alias.
2138 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2139 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2141 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2142 getParser().getContext());
2143 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2145 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2149 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2150 if (PatchedName.startswith("vpcom") &&
2151 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2152 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2153 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2154 unsigned ComparisonCode = StringSwitch<unsigned>(
2155 PatchedName.slice(5, PatchedName.size() - CCIdx))
2165 if (ComparisonCode != ~0U) {
2166 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2168 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2169 getParser().getContext());
2170 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2172 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2176 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2178 // Determine whether this is an instruction prefix.
2180 Name == "lock" || Name == "rep" ||
2181 Name == "repe" || Name == "repz" ||
2182 Name == "repne" || Name == "repnz" ||
2183 Name == "rex64" || Name == "data16";
2185 // This does the actual operand parsing. Don't parse any more if we have a
2186 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2187 // just want to parse the "lock" as the first instruction and the "incl" as
2189 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2191 // Parse '*' modifier.
2192 if (getLexer().is(AsmToken::Star))
2193 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2195 // Read the operands.
2197 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2198 Operands.push_back(std::move(Op));
2199 if (!HandleAVX512Operand(Operands, *Operands.back()))
2202 Parser.eatToEndOfStatement();
2205 // check for comma and eat it
2206 if (getLexer().is(AsmToken::Comma))
2212 if (getLexer().isNot(AsmToken::EndOfStatement))
2213 return ErrorAndEatStatement(getLexer().getLoc(),
2214 "unexpected token in argument list");
2217 // Consume the EndOfStatement or the prefix separator Slash
2218 if (getLexer().is(AsmToken::EndOfStatement) ||
2219 (isPrefix && getLexer().is(AsmToken::Slash)))
2222 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2223 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2224 // documented form in various unofficial manuals, so a lot of code uses it.
2225 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2226 Operands.size() == 3) {
2227 X86Operand &Op = (X86Operand &)*Operands.back();
2228 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2229 isa<MCConstantExpr>(Op.Mem.Disp) &&
2230 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2231 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2232 SMLoc Loc = Op.getEndLoc();
2233 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2236 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2237 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2238 Operands.size() == 3) {
2239 X86Operand &Op = (X86Operand &)*Operands[1];
2240 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2241 isa<MCConstantExpr>(Op.Mem.Disp) &&
2242 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2243 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2244 SMLoc Loc = Op.getEndLoc();
2245 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2249 // Append default arguments to "ins[bwld]"
2250 if (Name.startswith("ins") && Operands.size() == 1 &&
2251 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {
2252 AddDefaultSrcDestOperands(Operands,
2253 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2254 DefaultMemDIOperand(NameLoc));
2257 // Append default arguments to "outs[bwld]"
2258 if (Name.startswith("outs") && Operands.size() == 1 &&
2259 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2260 Name == "outsd" )) {
2261 AddDefaultSrcDestOperands(Operands,
2262 DefaultMemSIOperand(NameLoc),
2263 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2266 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2267 // values of $SIREG according to the mode. It would be nice if this
2268 // could be achieved with InstAlias in the tables.
2269 if (Name.startswith("lods") && Operands.size() == 1 &&
2270 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2271 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2272 Operands.push_back(DefaultMemSIOperand(NameLoc));
2274 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2275 // values of $DIREG according to the mode. It would be nice if this
2276 // could be achieved with InstAlias in the tables.
2277 if (Name.startswith("stos") && Operands.size() == 1 &&
2278 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2279 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2280 Operands.push_back(DefaultMemDIOperand(NameLoc));
2282 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2283 // values of $DIREG according to the mode. It would be nice if this
2284 // could be achieved with InstAlias in the tables.
2285 if (Name.startswith("scas") && Operands.size() == 1 &&
2286 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2287 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2288 Operands.push_back(DefaultMemDIOperand(NameLoc));
2290 // Add default SI and DI operands to "cmps[bwlq]".
2291 if (Name.startswith("cmps") &&
2292 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2293 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2294 if (Operands.size() == 1) {
2295 AddDefaultSrcDestOperands(Operands,
2296 DefaultMemDIOperand(NameLoc),
2297 DefaultMemSIOperand(NameLoc));
2298 } else if (Operands.size() == 3) {
2299 X86Operand &Op = (X86Operand &)*Operands[1];
2300 X86Operand &Op2 = (X86Operand &)*Operands[2];
2301 if (!doSrcDstMatch(Op, Op2))
2302 return Error(Op.getStartLoc(),
2303 "mismatching source and destination index registers");
2307 // Add default SI and DI operands to "movs[bwlq]".
2308 if ((Name.startswith("movs") &&
2309 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2310 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2311 (Name.startswith("smov") &&
2312 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2313 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2314 if (Operands.size() == 1) {
2315 if (Name == "movsd")
2316 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2317 AddDefaultSrcDestOperands(Operands,
2318 DefaultMemSIOperand(NameLoc),
2319 DefaultMemDIOperand(NameLoc));
2320 } else if (Operands.size() == 3) {
2321 X86Operand &Op = (X86Operand &)*Operands[1];
2322 X86Operand &Op2 = (X86Operand &)*Operands[2];
2323 if (!doSrcDstMatch(Op, Op2))
2324 return Error(Op.getStartLoc(),
2325 "mismatching source and destination index registers");
2329 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2331 if ((Name.startswith("shr") || Name.startswith("sar") ||
2332 Name.startswith("shl") || Name.startswith("sal") ||
2333 Name.startswith("rcl") || Name.startswith("rcr") ||
2334 Name.startswith("rol") || Name.startswith("ror")) &&
2335 Operands.size() == 3) {
2336 if (isParsingIntelSyntax()) {
2338 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2339 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2340 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2341 Operands.pop_back();
2343 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2344 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2345 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2346 Operands.erase(Operands.begin() + 1);
2350 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2351 // instalias with an immediate operand yet.
2352 if (Name == "int" && Operands.size() == 2) {
2353 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2355 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2356 if (CE->getValue() == 3) {
2357 Operands.erase(Operands.begin() + 1);
2358 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2365 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2368 TmpInst.setOpcode(Opcode);
2370 TmpInst.addOperand(MCOperand::createReg(Reg));
2371 TmpInst.addOperand(MCOperand::createReg(Reg));
2372 TmpInst.addOperand(Inst.getOperand(0));
2377 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2378 bool isCmp = false) {
2379 if (!Inst.getOperand(0).isImm() ||
2380 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2383 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2386 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2387 bool isCmp = false) {
2388 if (!Inst.getOperand(0).isImm() ||
2389 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2392 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2395 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2396 bool isCmp = false) {
2397 if (!Inst.getOperand(0).isImm() ||
2398 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2401 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2404 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2405 switch (Inst.getOpcode()) {
2406 default: return true;
2408 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2409 assert(Op.isImm() && "expected immediate");
2411 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2412 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2417 llvm_unreachable("handle the instruction appropriately");
2420 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2421 switch (Inst.getOpcode()) {
2422 default: return false;
2423 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2424 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2425 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2426 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2427 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2428 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2429 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2430 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2431 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2432 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2433 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2434 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2435 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2436 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2437 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2438 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2439 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2440 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2441 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2442 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2443 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2444 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2445 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2446 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2447 case X86::VMOVAPDrr:
2448 case X86::VMOVAPDYrr:
2449 case X86::VMOVAPSrr:
2450 case X86::VMOVAPSYrr:
2451 case X86::VMOVDQArr:
2452 case X86::VMOVDQAYrr:
2453 case X86::VMOVDQUrr:
2454 case X86::VMOVDQUYrr:
2455 case X86::VMOVUPDrr:
2456 case X86::VMOVUPDYrr:
2457 case X86::VMOVUPSrr:
2458 case X86::VMOVUPSYrr: {
2459 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2460 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2464 switch (Inst.getOpcode()) {
2465 default: llvm_unreachable("Invalid opcode");
2466 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2467 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2468 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2469 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2470 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2471 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2472 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2473 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2474 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2475 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2476 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2477 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2479 Inst.setOpcode(NewOpc);
2483 case X86::VMOVSSrr: {
2484 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2485 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2488 switch (Inst.getOpcode()) {
2489 default: llvm_unreachable("Invalid opcode");
2490 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2491 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2493 Inst.setOpcode(NewOpc);
2499 static const char *getSubtargetFeatureName(uint64_t Val);
2501 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2503 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2507 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2508 OperandVector &Operands,
2509 MCStreamer &Out, uint64_t &ErrorInfo,
2510 bool MatchingInlineAsm) {
2511 if (isParsingIntelSyntax())
2512 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2514 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2518 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2519 OperandVector &Operands, MCStreamer &Out,
2520 bool MatchingInlineAsm) {
2521 // FIXME: This should be replaced with a real .td file alias mechanism.
2522 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2524 const char *Repl = StringSwitch<const char *>(Op.getToken())
2525 .Case("finit", "fninit")
2526 .Case("fsave", "fnsave")
2527 .Case("fstcw", "fnstcw")
2528 .Case("fstcww", "fnstcw")
2529 .Case("fstenv", "fnstenv")
2530 .Case("fstsw", "fnstsw")
2531 .Case("fstsww", "fnstsw")
2532 .Case("fclex", "fnclex")
2536 Inst.setOpcode(X86::WAIT);
2538 if (!MatchingInlineAsm)
2539 EmitInstruction(Inst, Operands, Out);
2540 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2544 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2545 bool MatchingInlineAsm) {
2546 assert(ErrorInfo && "Unknown missing feature!");
2547 ArrayRef<SMRange> EmptyRanges = None;
2548 SmallString<126> Msg;
2549 raw_svector_ostream OS(Msg);
2550 OS << "instruction requires:";
2552 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2553 if (ErrorInfo & Mask)
2554 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2557 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2560 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2561 OperandVector &Operands,
2563 uint64_t &ErrorInfo,
2564 bool MatchingInlineAsm) {
2565 assert(!Operands.empty() && "Unexpect empty operand list!");
2566 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2567 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2568 ArrayRef<SMRange> EmptyRanges = None;
2570 // First, handle aliases that expand to multiple instructions.
2571 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2573 bool WasOriginallyInvalidOperand = false;
2576 // First, try a direct match.
2577 switch (MatchInstructionImpl(Operands, Inst,
2578 ErrorInfo, MatchingInlineAsm,
2579 isParsingIntelSyntax())) {
2580 default: llvm_unreachable("Unexpected match result!");
2582 if (!validateInstruction(Inst, Operands))
2585 // Some instructions need post-processing to, for example, tweak which
2586 // encoding is selected. Loop on it while changes happen so the
2587 // individual transformations can chain off each other.
2588 if (!MatchingInlineAsm)
2589 while (processInstruction(Inst, Operands))
2593 if (!MatchingInlineAsm)
2594 EmitInstruction(Inst, Operands, Out);
2595 Opcode = Inst.getOpcode();
2597 case Match_MissingFeature:
2598 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2599 case Match_InvalidOperand:
2600 WasOriginallyInvalidOperand = true;
2602 case Match_MnemonicFail:
2606 // FIXME: Ideally, we would only attempt suffix matches for things which are
2607 // valid prefixes, and we could just infer the right unambiguous
2608 // type. However, that requires substantially more matcher support than the
2611 // Change the operand to point to a temporary token.
2612 StringRef Base = Op.getToken();
2613 SmallString<16> Tmp;
2616 Op.setTokenValue(Tmp);
2618 // If this instruction starts with an 'f', then it is a floating point stack
2619 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2620 // 80-bit floating point, which use the suffixes s,l,t respectively.
2622 // Otherwise, we assume that this may be an integer instruction, which comes
2623 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2624 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2626 // Check for the various suffix matches.
2627 uint64_t ErrorInfoIgnore;
2628 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2631 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2632 Tmp.back() = Suffixes[I];
2633 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2634 MatchingInlineAsm, isParsingIntelSyntax());
2635 // If this returned as a missing feature failure, remember that.
2636 if (Match[I] == Match_MissingFeature)
2637 ErrorInfoMissingFeature = ErrorInfoIgnore;
2640 // Restore the old token.
2641 Op.setTokenValue(Base);
2643 // If exactly one matched, then we treat that as a successful match (and the
2644 // instruction will already have been filled in correctly, since the failing
2645 // matches won't have modified it).
2646 unsigned NumSuccessfulMatches =
2647 std::count(std::begin(Match), std::end(Match), Match_Success);
2648 if (NumSuccessfulMatches == 1) {
2650 if (!MatchingInlineAsm)
2651 EmitInstruction(Inst, Operands, Out);
2652 Opcode = Inst.getOpcode();
2656 // Otherwise, the match failed, try to produce a decent error message.
2658 // If we had multiple suffix matches, then identify this as an ambiguous
2660 if (NumSuccessfulMatches > 1) {
2662 unsigned NumMatches = 0;
2663 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2664 if (Match[I] == Match_Success)
2665 MatchChars[NumMatches++] = Suffixes[I];
2667 SmallString<126> Msg;
2668 raw_svector_ostream OS(Msg);
2669 OS << "ambiguous instructions require an explicit suffix (could be ";
2670 for (unsigned i = 0; i != NumMatches; ++i) {
2673 if (i + 1 == NumMatches)
2675 OS << "'" << Base << MatchChars[i] << "'";
2678 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2682 // Okay, we know that none of the variants matched successfully.
2684 // If all of the instructions reported an invalid mnemonic, then the original
2685 // mnemonic was invalid.
2686 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2687 if (!WasOriginallyInvalidOperand) {
2688 ArrayRef<SMRange> Ranges =
2689 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2690 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2691 Ranges, MatchingInlineAsm);
2694 // Recover location info for the operand if we know which was the problem.
2695 if (ErrorInfo != ~0ULL) {
2696 if (ErrorInfo >= Operands.size())
2697 return Error(IDLoc, "too few operands for instruction",
2698 EmptyRanges, MatchingInlineAsm);
2700 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2701 if (Operand.getStartLoc().isValid()) {
2702 SMRange OperandRange = Operand.getLocRange();
2703 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2704 OperandRange, MatchingInlineAsm);
2708 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2712 // If one instruction matched with a missing feature, report this as a
2714 if (std::count(std::begin(Match), std::end(Match),
2715 Match_MissingFeature) == 1) {
2716 ErrorInfo = ErrorInfoMissingFeature;
2717 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2721 // If one instruction matched with an invalid operand, report this as an
2723 if (std::count(std::begin(Match), std::end(Match),
2724 Match_InvalidOperand) == 1) {
2725 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2729 // If all of these were an outright failure, report it in a useless way.
2730 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2731 EmptyRanges, MatchingInlineAsm);
2735 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2736 OperandVector &Operands,
2738 uint64_t &ErrorInfo,
2739 bool MatchingInlineAsm) {
2740 assert(!Operands.empty() && "Unexpect empty operand list!");
2741 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2742 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2743 StringRef Mnemonic = Op.getToken();
2744 ArrayRef<SMRange> EmptyRanges = None;
2746 // First, handle aliases that expand to multiple instructions.
2747 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2751 // Find one unsized memory operand, if present.
2752 X86Operand *UnsizedMemOp = nullptr;
2753 for (const auto &Op : Operands) {
2754 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2755 if (X86Op->isMemUnsized())
2756 UnsizedMemOp = X86Op;
2759 // Allow some instructions to have implicitly pointer-sized operands. This is
2760 // compatible with gas.
2762 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2763 for (const char *Instr : PtrSizedInstrs) {
2764 if (Mnemonic == Instr) {
2765 UnsizedMemOp->Mem.Size = getPointerWidth();
2771 // If an unsized memory operand is present, try to match with each memory
2772 // operand size. In Intel assembly, the size is not part of the instruction
2774 SmallVector<unsigned, 8> Match;
2775 uint64_t ErrorInfoMissingFeature = 0;
2776 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2777 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2778 for (unsigned Size : MopSizes) {
2779 UnsizedMemOp->Mem.Size = Size;
2780 uint64_t ErrorInfoIgnore;
2781 unsigned LastOpcode = Inst.getOpcode();
2783 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2784 MatchingInlineAsm, isParsingIntelSyntax());
2785 if (Match.empty() || LastOpcode != Inst.getOpcode())
2788 // If this returned as a missing feature failure, remember that.
2789 if (Match.back() == Match_MissingFeature)
2790 ErrorInfoMissingFeature = ErrorInfoIgnore;
2793 // Restore the size of the unsized memory operand if we modified it.
2795 UnsizedMemOp->Mem.Size = 0;
2798 // If we haven't matched anything yet, this is not a basic integer or FPU
2799 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2800 // matching with the unsized operand.
2801 if (Match.empty()) {
2802 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2804 isParsingIntelSyntax()));
2805 // If this returned as a missing feature failure, remember that.
2806 if (Match.back() == Match_MissingFeature)
2807 ErrorInfoMissingFeature = ErrorInfo;
2810 // Restore the size of the unsized memory operand if we modified it.
2812 UnsizedMemOp->Mem.Size = 0;
2814 // If it's a bad mnemonic, all results will be the same.
2815 if (Match.back() == Match_MnemonicFail) {
2816 ArrayRef<SMRange> Ranges =
2817 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2818 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2819 Ranges, MatchingInlineAsm);
2822 // If exactly one matched, then we treat that as a successful match (and the
2823 // instruction will already have been filled in correctly, since the failing
2824 // matches won't have modified it).
2825 unsigned NumSuccessfulMatches =
2826 std::count(std::begin(Match), std::end(Match), Match_Success);
2827 if (NumSuccessfulMatches == 1) {
2828 if (!validateInstruction(Inst, Operands))
2831 // Some instructions need post-processing to, for example, tweak which
2832 // encoding is selected. Loop on it while changes happen so the individual
2833 // transformations can chain off each other.
2834 if (!MatchingInlineAsm)
2835 while (processInstruction(Inst, Operands))
2838 if (!MatchingInlineAsm)
2839 EmitInstruction(Inst, Operands, Out);
2840 Opcode = Inst.getOpcode();
2842 } else if (NumSuccessfulMatches > 1) {
2843 assert(UnsizedMemOp &&
2844 "multiple matches only possible with unsized memory operands");
2845 ArrayRef<SMRange> Ranges =
2846 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2847 return Error(UnsizedMemOp->getStartLoc(),
2848 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2849 Ranges, MatchingInlineAsm);
2852 // If one instruction matched with a missing feature, report this as a
2854 if (std::count(std::begin(Match), std::end(Match),
2855 Match_MissingFeature) == 1) {
2856 ErrorInfo = ErrorInfoMissingFeature;
2857 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2861 // If one instruction matched with an invalid operand, report this as an
2863 if (std::count(std::begin(Match), std::end(Match),
2864 Match_InvalidOperand) == 1) {
2865 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2869 // If all of these were an outright failure, report it in a useless way.
2870 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2874 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2875 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2878 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2879 MCAsmParser &Parser = getParser();
2880 StringRef IDVal = DirectiveID.getIdentifier();
2881 if (IDVal == ".word")
2882 return ParseDirectiveWord(2, DirectiveID.getLoc());
2883 else if (IDVal.startswith(".code"))
2884 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2885 else if (IDVal.startswith(".att_syntax")) {
2886 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2887 if (Parser.getTok().getString() == "prefix")
2889 else if (Parser.getTok().getString() == "noprefix")
2890 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2891 "supported: registers must have a "
2892 "'%' prefix in .att_syntax");
2894 getParser().setAssemblerDialect(0);
2896 } else if (IDVal.startswith(".intel_syntax")) {
2897 getParser().setAssemblerDialect(1);
2898 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2899 if (Parser.getTok().getString() == "noprefix")
2901 else if (Parser.getTok().getString() == "prefix")
2902 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2903 "supported: registers must not have "
2904 "a '%' prefix in .intel_syntax");
2911 /// ParseDirectiveWord
2912 /// ::= .word [ expression (, expression)* ]
2913 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2914 MCAsmParser &Parser = getParser();
2915 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2917 const MCExpr *Value;
2918 if (getParser().parseExpression(Value))
2921 getParser().getStreamer().EmitValue(Value, Size);
2923 if (getLexer().is(AsmToken::EndOfStatement))
2926 // FIXME: Improve diagnostic.
2927 if (getLexer().isNot(AsmToken::Comma)) {
2928 Error(L, "unexpected token in directive");
2939 /// ParseDirectiveCode
2940 /// ::= .code16 | .code32 | .code64
2941 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2942 MCAsmParser &Parser = getParser();
2943 if (IDVal == ".code16") {
2945 if (!is16BitMode()) {
2946 SwitchMode(X86::Mode16Bit);
2947 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2949 } else if (IDVal == ".code32") {
2951 if (!is32BitMode()) {
2952 SwitchMode(X86::Mode32Bit);
2953 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2955 } else if (IDVal == ".code64") {
2957 if (!is64BitMode()) {
2958 SwitchMode(X86::Mode64Bit);
2959 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2962 Error(L, "unknown directive " + IDVal);
2969 // Force static initialization.
2970 extern "C" void LLVMInitializeX86AsmParser() {
2971 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2972 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2975 #define GET_REGISTER_MATCHER
2976 #define GET_MATCHER_IMPLEMENTATION
2977 #define GET_SUBTARGET_FEATURE_NAME
2978 #include "X86GenAsmMatcher.inc"