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 (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1128 E = AsmRewrites->end(); I != E; ++I) {
1129 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1131 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1132 assert (!Found && "ImmDisp already rewritten.");
1133 (*I).Kind = AOK_Imm;
1134 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1135 (*I).Val = FinalImmDisp;
1140 assert (Found && "Unable to rewrite ImmDisp.");
1143 // We have a symbolic and an immediate displacement, but no displacement
1144 // before the bracketed expression. Put the immediate displacement
1145 // before the bracketed expression.
1146 AsmRewrites->emplace_back(AOK_Imm, BracLoc, 0, FinalImmDisp);
1149 // Remove all the ImmPrefix rewrites within the brackets.
1150 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1151 E = AsmRewrites->end(); I != E; ++I) {
1152 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1154 if ((*I).Kind == AOK_ImmPrefix)
1155 (*I).Kind = AOK_Delete;
1157 const char *SymLocPtr = SymName.data();
1158 // Skip everything before the symbol.
1159 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1160 assert(Len > 0 && "Expected a non-negative length.");
1161 AsmRewrites.emplace_back(AOK_Skip, StartInBrac, Len);
1163 // Skip everything after the symbol.
1164 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1165 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1166 assert(Len > 0 && "Expected a non-negative length.");
1167 AsmRewrites.emplace_back(AOK_Skip, Loc, Len);
1171 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1172 MCAsmParser &Parser = getParser();
1173 const AsmToken &Tok = Parser.getTok();
1177 bool UpdateLocLex = true;
1179 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1180 // identifier. Don't try an parse it as a register.
1181 if (Tok.getString().startswith("."))
1184 // If we're parsing an immediate expression, we don't expect a '['.
1185 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1188 AsmToken::TokenKind TK = getLexer().getKind();
1191 if (SM.isValidEndState()) {
1195 return Error(Tok.getLoc(), "unknown token in expression");
1197 case AsmToken::EndOfStatement: {
1201 case AsmToken::String:
1202 case AsmToken::Identifier: {
1203 // This could be a register or a symbolic displacement.
1206 SMLoc IdentLoc = Tok.getLoc();
1207 StringRef Identifier = Tok.getString();
1208 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1209 SM.onRegister(TmpReg);
1210 UpdateLocLex = false;
1213 if (!isParsingInlineAsm()) {
1214 if (getParser().parsePrimaryExpr(Val, End))
1215 return Error(Tok.getLoc(), "Unexpected identifier!");
1217 // This is a dot operator, not an adjacent identifier.
1218 if (Identifier.find('.') != StringRef::npos) {
1221 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1222 if (ParseIntelIdentifier(Val, Identifier, Info,
1223 /*Unevaluated=*/false, End))
1227 SM.onIdentifierExpr(Val, Identifier);
1228 UpdateLocLex = false;
1231 return Error(Tok.getLoc(), "Unexpected identifier!");
1233 case AsmToken::Integer: {
1235 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1236 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Tok.getLoc());
1237 // Look for 'b' or 'f' following an Integer as a directional label
1238 SMLoc Loc = getTok().getLoc();
1239 int64_t IntVal = getTok().getIntVal();
1240 End = consumeToken();
1241 UpdateLocLex = false;
1242 if (getLexer().getKind() == AsmToken::Identifier) {
1243 StringRef IDVal = getTok().getString();
1244 if (IDVal == "f" || IDVal == "b") {
1246 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1247 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1249 MCSymbolRefExpr::create(Sym, Variant, getContext());
1250 if (IDVal == "b" && Sym->isUndefined())
1251 return Error(Loc, "invalid reference to undefined symbol");
1252 StringRef Identifier = Sym->getName();
1253 SM.onIdentifierExpr(Val, Identifier);
1254 End = consumeToken();
1256 if (SM.onInteger(IntVal, ErrMsg))
1257 return Error(Loc, ErrMsg);
1260 if (SM.onInteger(IntVal, ErrMsg))
1261 return Error(Loc, ErrMsg);
1265 case AsmToken::Plus: SM.onPlus(); break;
1266 case AsmToken::Minus: SM.onMinus(); break;
1267 case AsmToken::Tilde: SM.onNot(); break;
1268 case AsmToken::Star: SM.onStar(); break;
1269 case AsmToken::Slash: SM.onDivide(); break;
1270 case AsmToken::Pipe: SM.onOr(); break;
1271 case AsmToken::Caret: SM.onXor(); break;
1272 case AsmToken::Amp: SM.onAnd(); break;
1273 case AsmToken::LessLess:
1274 SM.onLShift(); break;
1275 case AsmToken::GreaterGreater:
1276 SM.onRShift(); break;
1277 case AsmToken::LBrac: SM.onLBrac(); break;
1278 case AsmToken::RBrac: SM.onRBrac(); break;
1279 case AsmToken::LParen: SM.onLParen(); break;
1280 case AsmToken::RParen: SM.onRParen(); break;
1283 return Error(Tok.getLoc(), "unknown token in expression");
1285 if (!Done && UpdateLocLex)
1286 End = consumeToken();
1291 std::unique_ptr<X86Operand>
1292 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1293 int64_t ImmDisp, unsigned Size) {
1294 MCAsmParser &Parser = getParser();
1295 const AsmToken &Tok = Parser.getTok();
1296 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1297 if (getLexer().isNot(AsmToken::LBrac))
1298 return ErrorOperand(BracLoc, "Expected '[' token!");
1299 Parser.Lex(); // Eat '['
1301 SMLoc StartInBrac = Tok.getLoc();
1302 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1303 // may have already parsed an immediate displacement before the bracketed
1305 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1306 if (ParseIntelExpression(SM, End))
1309 const MCExpr *Disp = nullptr;
1310 if (const MCExpr *Sym = SM.getSym()) {
1311 // A symbolic displacement.
1313 if (isParsingInlineAsm())
1314 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1315 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1319 if (SM.getImm() || !Disp) {
1320 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1322 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1324 Disp = Imm; // An immediate displacement only.
1327 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1328 // will in fact do global lookup the field name inside all global typedefs,
1329 // but we don't emulate that.
1330 if (Tok.getString().find('.') != StringRef::npos) {
1331 const MCExpr *NewDisp;
1332 if (ParseIntelDotOperator(Disp, NewDisp))
1335 End = Tok.getEndLoc();
1336 Parser.Lex(); // Eat the field.
1340 int BaseReg = SM.getBaseReg();
1341 int IndexReg = SM.getIndexReg();
1342 int Scale = SM.getScale();
1343 if (!isParsingInlineAsm()) {
1345 if (!BaseReg && !IndexReg) {
1347 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1348 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1352 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1353 Error(StartInBrac, ErrMsg);
1356 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1357 IndexReg, Scale, Start, End, Size);
1360 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1361 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1362 End, Size, SM.getSymName(), Info);
1365 // Inline assembly may use variable names with namespace alias qualifiers.
1366 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1367 StringRef &Identifier,
1368 InlineAsmIdentifierInfo &Info,
1369 bool IsUnevaluatedOperand, SMLoc &End) {
1370 MCAsmParser &Parser = getParser();
1371 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1374 StringRef LineBuf(Identifier.data());
1376 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1378 const AsmToken &Tok = Parser.getTok();
1379 SMLoc Loc = Tok.getLoc();
1381 // Advance the token stream until the end of the current token is
1382 // after the end of what the frontend claimed.
1383 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1385 End = Tok.getEndLoc();
1387 } while (End.getPointer() < EndPtr);
1388 Identifier = LineBuf;
1390 // The frontend should end parsing on an assembler token boundary, unless it
1392 assert((End.getPointer() == EndPtr || !Result) &&
1393 "frontend claimed part of a token?");
1395 // If the identifier lookup was unsuccessful, assume that we are dealing with
1398 StringRef InternalName =
1399 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1401 assert(InternalName.size() && "We should have an internal name here.");
1402 // Push a rewrite for replacing the identifier name with the internal name.
1403 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
1407 // Create the symbol reference.
1408 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1409 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1410 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1414 /// \brief Parse intel style segment override.
1415 std::unique_ptr<X86Operand>
1416 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1418 MCAsmParser &Parser = getParser();
1419 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1420 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1421 if (Tok.isNot(AsmToken::Colon))
1422 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1423 Parser.Lex(); // Eat ':'
1425 int64_t ImmDisp = 0;
1426 if (getLexer().is(AsmToken::Integer)) {
1427 ImmDisp = Tok.getIntVal();
1428 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1430 if (isParsingInlineAsm())
1431 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, ImmDispToken.getLoc());
1433 if (getLexer().isNot(AsmToken::LBrac)) {
1434 // An immediate following a 'segment register', 'colon' token sequence can
1435 // be followed by a bracketed expression. If it isn't we know we have our
1436 // final segment override.
1437 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1438 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1439 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1440 Start, ImmDispToken.getEndLoc(), Size);
1444 if (getLexer().is(AsmToken::LBrac))
1445 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1449 if (!isParsingInlineAsm()) {
1450 if (getParser().parsePrimaryExpr(Val, End))
1451 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1453 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1456 InlineAsmIdentifierInfo Info;
1457 StringRef Identifier = Tok.getString();
1458 if (ParseIntelIdentifier(Val, Identifier, Info,
1459 /*Unevaluated=*/false, End))
1461 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1462 /*Scale=*/1, Start, End, Size, Identifier, Info);
1465 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1466 std::unique_ptr<X86Operand>
1467 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1468 MCAsmParser &Parser = getParser();
1469 const AsmToken &Tok = Parser.getTok();
1470 // Eat "{" and mark the current place.
1471 const SMLoc consumedToken = consumeToken();
1472 if (Tok.getIdentifier().startswith("r")){
1473 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1474 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1475 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1476 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1477 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1480 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1481 Parser.Lex(); // Eat "r*" of r*-sae
1482 if (!getLexer().is(AsmToken::Minus))
1483 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1484 Parser.Lex(); // Eat "-"
1485 Parser.Lex(); // Eat the sae
1486 if (!getLexer().is(AsmToken::RCurly))
1487 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1488 Parser.Lex(); // Eat "}"
1489 const MCExpr *RndModeOp =
1490 MCConstantExpr::create(rndMode, Parser.getContext());
1491 return X86Operand::CreateImm(RndModeOp, Start, End);
1493 if(Tok.getIdentifier().equals("sae")){
1494 Parser.Lex(); // Eat the sae
1495 if (!getLexer().is(AsmToken::RCurly))
1496 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1497 Parser.Lex(); // Eat "}"
1498 return X86Operand::CreateToken("{sae}", consumedToken);
1500 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1502 /// ParseIntelMemOperand - Parse intel style memory operand.
1503 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1506 MCAsmParser &Parser = getParser();
1507 const AsmToken &Tok = Parser.getTok();
1510 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1511 if (getLexer().is(AsmToken::LBrac))
1512 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1513 assert(ImmDisp == 0);
1516 if (!isParsingInlineAsm()) {
1517 if (getParser().parsePrimaryExpr(Val, End))
1518 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1520 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1523 InlineAsmIdentifierInfo Info;
1524 StringRef Identifier = Tok.getString();
1525 if (ParseIntelIdentifier(Val, Identifier, Info,
1526 /*Unevaluated=*/false, End))
1529 if (!getLexer().is(AsmToken::LBrac))
1530 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1531 /*Scale=*/1, Start, End, Size, Identifier, Info);
1533 Parser.Lex(); // Eat '['
1535 // Parse Identifier [ ImmDisp ]
1536 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1537 /*AddImmPrefix=*/false);
1538 if (ParseIntelExpression(SM, End))
1542 Error(Start, "cannot use more than one symbol in memory operand");
1545 if (SM.getBaseReg()) {
1546 Error(Start, "cannot use base register with variable reference");
1549 if (SM.getIndexReg()) {
1550 Error(Start, "cannot use index register with variable reference");
1554 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1555 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1556 // we're pointing to a local variable in memory, so the base register is
1557 // really the frame or stack pointer.
1558 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1559 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1560 Start, End, Size, Identifier, Info.OpDecl);
1563 /// Parse the '.' operator.
1564 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1565 const MCExpr *&NewDisp) {
1566 MCAsmParser &Parser = getParser();
1567 const AsmToken &Tok = Parser.getTok();
1568 int64_t OrigDispVal, DotDispVal;
1570 // FIXME: Handle non-constant expressions.
1571 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1572 OrigDispVal = OrigDisp->getValue();
1574 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1576 // Drop the optional '.'.
1577 StringRef DotDispStr = Tok.getString();
1578 if (DotDispStr.startswith("."))
1579 DotDispStr = DotDispStr.drop_front(1);
1581 // .Imm gets lexed as a real.
1582 if (Tok.is(AsmToken::Real)) {
1584 DotDispStr.getAsInteger(10, DotDisp);
1585 DotDispVal = DotDisp.getZExtValue();
1586 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1588 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1589 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1591 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1592 DotDispVal = DotDisp;
1594 return Error(Tok.getLoc(), "Unexpected token type!");
1596 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1597 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1598 unsigned Len = DotDispStr.size();
1599 unsigned Val = OrigDispVal + DotDispVal;
1600 InstInfo->AsmRewrites->emplace_back(AOK_DotOperator, Loc, Len, Val);
1603 NewDisp = MCConstantExpr::create(OrigDispVal + DotDispVal, getContext());
1607 /// Parse the 'offset' operator. This operator is used to specify the
1608 /// location rather then the content of a variable.
1609 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1610 MCAsmParser &Parser = getParser();
1611 const AsmToken &Tok = Parser.getTok();
1612 SMLoc OffsetOfLoc = Tok.getLoc();
1613 Parser.Lex(); // Eat offset.
1616 InlineAsmIdentifierInfo Info;
1617 SMLoc Start = Tok.getLoc(), End;
1618 StringRef Identifier = Tok.getString();
1619 if (ParseIntelIdentifier(Val, Identifier, Info,
1620 /*Unevaluated=*/false, End))
1623 // Don't emit the offset operator.
1624 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7);
1626 // The offset operator will have an 'r' constraint, thus we need to create
1627 // register operand to ensure proper matching. Just pick a GPR based on
1628 // the size of a pointer.
1630 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1631 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1632 OffsetOfLoc, Identifier, Info.OpDecl);
1635 enum IntelOperatorKind {
1641 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1642 /// returns the number of elements in an array. It returns the value 1 for
1643 /// non-array variables. The SIZE operator returns the size of a C or C++
1644 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1645 /// TYPE operator returns the size of a C or C++ type or variable. If the
1646 /// variable is an array, TYPE returns the size of a single element.
1647 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1648 MCAsmParser &Parser = getParser();
1649 const AsmToken &Tok = Parser.getTok();
1650 SMLoc TypeLoc = Tok.getLoc();
1651 Parser.Lex(); // Eat operator.
1653 const MCExpr *Val = nullptr;
1654 InlineAsmIdentifierInfo Info;
1655 SMLoc Start = Tok.getLoc(), End;
1656 StringRef Identifier = Tok.getString();
1657 if (ParseIntelIdentifier(Val, Identifier, Info,
1658 /*Unevaluated=*/true, End))
1662 return ErrorOperand(Start, "unable to lookup expression");
1666 default: llvm_unreachable("Unexpected operand kind!");
1667 case IOK_LENGTH: CVal = Info.Length; break;
1668 case IOK_SIZE: CVal = Info.Size; break;
1669 case IOK_TYPE: CVal = Info.Type; break;
1672 // Rewrite the type operator and the C or C++ type or variable in terms of an
1673 // immediate. E.g. TYPE foo -> $$4
1674 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1675 InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
1677 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1678 return X86Operand::CreateImm(Imm, Start, End);
1681 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1682 MCAsmParser &Parser = getParser();
1683 const AsmToken &Tok = Parser.getTok();
1686 // Offset, length, type and size operators.
1687 if (isParsingInlineAsm()) {
1688 StringRef AsmTokStr = Tok.getString();
1689 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1690 return ParseIntelOffsetOfOperator();
1691 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1692 return ParseIntelOperator(IOK_LENGTH);
1693 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1694 return ParseIntelOperator(IOK_SIZE);
1695 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1696 return ParseIntelOperator(IOK_TYPE);
1699 unsigned Size = getIntelMemOperandSize(Tok.getString());
1701 Parser.Lex(); // Eat operand size (e.g., byte, word).
1702 if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
1703 return ErrorOperand(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
1704 Parser.Lex(); // Eat ptr.
1706 Start = Tok.getLoc();
1709 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1710 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1711 AsmToken StartTok = Tok;
1712 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1713 /*AddImmPrefix=*/false);
1714 if (ParseIntelExpression(SM, End))
1717 int64_t Imm = SM.getImm();
1718 if (isParsingInlineAsm()) {
1719 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1720 if (StartTok.getString().size() == Len)
1721 // Just add a prefix if this wasn't a complex immediate expression.
1722 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1724 // Otherwise, rewrite the complex expression as a single immediate.
1725 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1728 if (getLexer().isNot(AsmToken::LBrac)) {
1729 // If a directional label (ie. 1f or 2b) was parsed above from
1730 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1731 // to the MCExpr with the directional local symbol and this is a
1732 // memory operand not an immediate operand.
1734 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1737 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1738 return X86Operand::CreateImm(ImmExpr, Start, End);
1741 // Only positive immediates are valid.
1743 return ErrorOperand(Start, "expected a positive immediate displacement "
1744 "before bracketed expr.");
1746 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1747 return ParseIntelMemOperand(Imm, Start, Size);
1750 // rounding mode token
1751 if (STI.getFeatureBits()[X86::FeatureAVX512] &&
1752 getLexer().is(AsmToken::LCurly))
1753 return ParseRoundingModeOp(Start, End);
1757 if (!ParseRegister(RegNo, Start, End)) {
1758 // If this is a segment register followed by a ':', then this is the start
1759 // of a segment override, otherwise this is a normal register reference.
1760 if (getLexer().isNot(AsmToken::Colon))
1761 return X86Operand::CreateReg(RegNo, Start, End);
1763 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
1767 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
1770 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1771 MCAsmParser &Parser = getParser();
1772 switch (getLexer().getKind()) {
1774 // Parse a memory operand with no segment register.
1775 return ParseMemOperand(0, Parser.getTok().getLoc());
1776 case AsmToken::Percent: {
1777 // Read the register.
1780 if (ParseRegister(RegNo, Start, End)) return nullptr;
1781 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1782 Error(Start, "%eiz and %riz can only be used as index registers",
1783 SMRange(Start, End));
1787 // If this is a segment register followed by a ':', then this is the start
1788 // of a memory reference, otherwise this is a normal register reference.
1789 if (getLexer().isNot(AsmToken::Colon))
1790 return X86Operand::CreateReg(RegNo, Start, End);
1792 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
1793 return ErrorOperand(Start, "invalid segment register");
1795 getParser().Lex(); // Eat the colon.
1796 return ParseMemOperand(RegNo, Start);
1798 case AsmToken::Dollar: {
1799 // $42 -> immediate.
1800 SMLoc Start = Parser.getTok().getLoc(), End;
1803 if (getParser().parseExpression(Val, End))
1805 return X86Operand::CreateImm(Val, Start, End);
1807 case AsmToken::LCurly:{
1808 SMLoc Start = Parser.getTok().getLoc(), End;
1809 if (STI.getFeatureBits()[X86::FeatureAVX512])
1810 return ParseRoundingModeOp(Start, End);
1811 return ErrorOperand(Start, "unknown token in expression");
1816 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
1817 const MCParsedAsmOperand &Op) {
1818 MCAsmParser &Parser = getParser();
1819 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
1820 if (getLexer().is(AsmToken::LCurly)) {
1821 // Eat "{" and mark the current place.
1822 const SMLoc consumedToken = consumeToken();
1823 // Distinguish {1to<NUM>} from {%k<NUM>}.
1824 if(getLexer().is(AsmToken::Integer)) {
1825 // Parse memory broadcasting ({1to<NUM>}).
1826 if (getLexer().getTok().getIntVal() != 1)
1827 return !ErrorAndEatStatement(getLexer().getLoc(),
1828 "Expected 1to<NUM> at this point");
1829 Parser.Lex(); // Eat "1" of 1to8
1830 if (!getLexer().is(AsmToken::Identifier) ||
1831 !getLexer().getTok().getIdentifier().startswith("to"))
1832 return !ErrorAndEatStatement(getLexer().getLoc(),
1833 "Expected 1to<NUM> at this point");
1834 // Recognize only reasonable suffixes.
1835 const char *BroadcastPrimitive =
1836 StringSwitch<const char*>(getLexer().getTok().getIdentifier())
1837 .Case("to2", "{1to2}")
1838 .Case("to4", "{1to4}")
1839 .Case("to8", "{1to8}")
1840 .Case("to16", "{1to16}")
1842 if (!BroadcastPrimitive)
1843 return !ErrorAndEatStatement(getLexer().getLoc(),
1844 "Invalid memory broadcast primitive.");
1845 Parser.Lex(); // Eat "toN" of 1toN
1846 if (!getLexer().is(AsmToken::RCurly))
1847 return !ErrorAndEatStatement(getLexer().getLoc(),
1848 "Expected } at this point");
1849 Parser.Lex(); // Eat "}"
1850 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
1852 // No AVX512 specific primitives can pass
1853 // after memory broadcasting, so return.
1856 // Parse mask register {%k1}
1857 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
1858 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
1859 Operands.push_back(std::move(Op));
1860 if (!getLexer().is(AsmToken::RCurly))
1861 return !ErrorAndEatStatement(getLexer().getLoc(),
1862 "Expected } at this point");
1863 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
1865 // Parse "zeroing non-masked" semantic {z}
1866 if (getLexer().is(AsmToken::LCurly)) {
1867 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
1868 if (!getLexer().is(AsmToken::Identifier) ||
1869 getLexer().getTok().getIdentifier() != "z")
1870 return !ErrorAndEatStatement(getLexer().getLoc(),
1871 "Expected z at this point");
1872 Parser.Lex(); // Eat the z
1873 if (!getLexer().is(AsmToken::RCurly))
1874 return !ErrorAndEatStatement(getLexer().getLoc(),
1875 "Expected } at this point");
1876 Parser.Lex(); // Eat the }
1885 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1886 /// has already been parsed if present.
1887 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
1890 MCAsmParser &Parser = getParser();
1891 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1892 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1893 // only way to do this without lookahead is to eat the '(' and see what is
1895 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext());
1896 if (getLexer().isNot(AsmToken::LParen)) {
1898 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
1900 // After parsing the base expression we could either have a parenthesized
1901 // memory address or not. If not, return now. If so, eat the (.
1902 if (getLexer().isNot(AsmToken::LParen)) {
1903 // Unless we have a segment register, treat this as an immediate.
1905 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1906 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1913 // Okay, we have a '('. We don't know if this is an expression or not, but
1914 // so we have to eat the ( to see beyond it.
1915 SMLoc LParenLoc = Parser.getTok().getLoc();
1916 Parser.Lex(); // Eat the '('.
1918 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1919 // Nothing to do here, fall into the code below with the '(' part of the
1920 // memory operand consumed.
1924 // It must be an parenthesized expression, parse it now.
1925 if (getParser().parseParenExpression(Disp, ExprEnd))
1928 // After parsing the base expression we could either have a parenthesized
1929 // memory address or not. If not, return now. If so, eat the (.
1930 if (getLexer().isNot(AsmToken::LParen)) {
1931 // Unless we have a segment register, treat this as an immediate.
1933 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1935 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1944 // If we reached here, then we just ate the ( of the memory operand. Process
1945 // the rest of the memory operand.
1946 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1947 SMLoc IndexLoc, BaseLoc;
1949 if (getLexer().is(AsmToken::Percent)) {
1950 SMLoc StartLoc, EndLoc;
1951 BaseLoc = Parser.getTok().getLoc();
1952 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr;
1953 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1954 Error(StartLoc, "eiz and riz can only be used as index registers",
1955 SMRange(StartLoc, EndLoc));
1960 if (getLexer().is(AsmToken::Comma)) {
1961 Parser.Lex(); // Eat the comma.
1962 IndexLoc = Parser.getTok().getLoc();
1964 // Following the comma we should have either an index register, or a scale
1965 // value. We don't support the later form, but we want to parse it
1968 // Not that even though it would be completely consistent to support syntax
1969 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1970 if (getLexer().is(AsmToken::Percent)) {
1972 if (ParseRegister(IndexReg, L, L)) return nullptr;
1974 if (getLexer().isNot(AsmToken::RParen)) {
1975 // Parse the scale amount:
1976 // ::= ',' [scale-expression]
1977 if (getLexer().isNot(AsmToken::Comma)) {
1978 Error(Parser.getTok().getLoc(),
1979 "expected comma in scale expression");
1982 Parser.Lex(); // Eat the comma.
1984 if (getLexer().isNot(AsmToken::RParen)) {
1985 SMLoc Loc = Parser.getTok().getLoc();
1988 if (getParser().parseAbsoluteExpression(ScaleVal)){
1989 Error(Loc, "expected scale expression");
1993 // Validate the scale amount.
1994 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1996 Error(Loc, "scale factor in 16-bit address must be 1");
1999 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 &&
2001 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2004 Scale = (unsigned)ScaleVal;
2007 } else if (getLexer().isNot(AsmToken::RParen)) {
2008 // A scale amount without an index is ignored.
2010 SMLoc Loc = Parser.getTok().getLoc();
2013 if (getParser().parseAbsoluteExpression(Value))
2017 Warning(Loc, "scale factor without index register is ignored");
2022 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2023 if (getLexer().isNot(AsmToken::RParen)) {
2024 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2027 SMLoc MemEnd = Parser.getTok().getEndLoc();
2028 Parser.Lex(); // Eat the ')'.
2030 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2031 // and then only in non-64-bit modes. Except for DX, which is a special case
2032 // because an unofficial form of in/out instructions uses it.
2033 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2034 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2035 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2036 BaseReg != X86::DX) {
2037 Error(BaseLoc, "invalid 16-bit base register");
2041 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2042 Error(IndexLoc, "16-bit memory operand may not include only index register");
2047 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2048 Error(BaseLoc, ErrMsg);
2052 if (SegReg || BaseReg || IndexReg)
2053 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2054 IndexReg, Scale, MemStart, MemEnd);
2055 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2058 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2059 SMLoc NameLoc, OperandVector &Operands) {
2060 MCAsmParser &Parser = getParser();
2062 StringRef PatchedName = Name;
2064 // FIXME: Hack to recognize setneb as setne.
2065 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2066 PatchedName != "setb" && PatchedName != "setnb")
2067 PatchedName = PatchedName.substr(0, Name.size()-1);
2069 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2070 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2071 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2072 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2073 bool IsVCMP = PatchedName[0] == 'v';
2074 unsigned CCIdx = IsVCMP ? 4 : 3;
2075 unsigned ComparisonCode = StringSwitch<unsigned>(
2076 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2080 .Case("unord", 0x03)
2085 /* AVX only from here */
2086 .Case("eq_uq", 0x08)
2089 .Case("false", 0x0B)
2090 .Case("neq_oq", 0x0C)
2094 .Case("eq_os", 0x10)
2095 .Case("lt_oq", 0x11)
2096 .Case("le_oq", 0x12)
2097 .Case("unord_s", 0x13)
2098 .Case("neq_us", 0x14)
2099 .Case("nlt_uq", 0x15)
2100 .Case("nle_uq", 0x16)
2101 .Case("ord_s", 0x17)
2102 .Case("eq_us", 0x18)
2103 .Case("nge_uq", 0x19)
2104 .Case("ngt_uq", 0x1A)
2105 .Case("false_os", 0x1B)
2106 .Case("neq_os", 0x1C)
2107 .Case("ge_oq", 0x1D)
2108 .Case("gt_oq", 0x1E)
2109 .Case("true_us", 0x1F)
2111 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2113 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2116 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2117 getParser().getContext());
2118 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2120 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2124 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2125 if (PatchedName.startswith("vpcmp") &&
2126 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2127 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2128 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2129 unsigned ComparisonCode = StringSwitch<unsigned>(
2130 PatchedName.slice(5, PatchedName.size() - CCIdx))
2131 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2134 //.Case("false", 0x3) // Not a documented alias.
2138 //.Case("true", 0x7) // Not a documented alias.
2140 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2141 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2143 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2144 getParser().getContext());
2145 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2147 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2151 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2152 if (PatchedName.startswith("vpcom") &&
2153 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2154 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2155 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2156 unsigned ComparisonCode = StringSwitch<unsigned>(
2157 PatchedName.slice(5, PatchedName.size() - CCIdx))
2167 if (ComparisonCode != ~0U) {
2168 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2170 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2171 getParser().getContext());
2172 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2174 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2178 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2180 // Determine whether this is an instruction prefix.
2182 Name == "lock" || Name == "rep" ||
2183 Name == "repe" || Name == "repz" ||
2184 Name == "repne" || Name == "repnz" ||
2185 Name == "rex64" || Name == "data16";
2187 // This does the actual operand parsing. Don't parse any more if we have a
2188 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
2189 // just want to parse the "lock" as the first instruction and the "incl" as
2191 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
2193 // Parse '*' modifier.
2194 if (getLexer().is(AsmToken::Star))
2195 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
2197 // Read the operands.
2199 if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
2200 Operands.push_back(std::move(Op));
2201 if (!HandleAVX512Operand(Operands, *Operands.back()))
2204 Parser.eatToEndOfStatement();
2207 // check for comma and eat it
2208 if (getLexer().is(AsmToken::Comma))
2214 if (getLexer().isNot(AsmToken::EndOfStatement))
2215 return ErrorAndEatStatement(getLexer().getLoc(),
2216 "unexpected token in argument list");
2219 // Consume the EndOfStatement or the prefix separator Slash
2220 if (getLexer().is(AsmToken::EndOfStatement) ||
2221 (isPrefix && getLexer().is(AsmToken::Slash)))
2224 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
2225 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
2226 // documented form in various unofficial manuals, so a lot of code uses it.
2227 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
2228 Operands.size() == 3) {
2229 X86Operand &Op = (X86Operand &)*Operands.back();
2230 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2231 isa<MCConstantExpr>(Op.Mem.Disp) &&
2232 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2233 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2234 SMLoc Loc = Op.getEndLoc();
2235 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2238 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
2239 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
2240 Operands.size() == 3) {
2241 X86Operand &Op = (X86Operand &)*Operands[1];
2242 if (Op.isMem() && Op.Mem.SegReg == 0 &&
2243 isa<MCConstantExpr>(Op.Mem.Disp) &&
2244 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
2245 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
2246 SMLoc Loc = Op.getEndLoc();
2247 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
2251 // Append default arguments to "ins[bwld]"
2252 if (Name.startswith("ins") && Operands.size() == 1 &&
2253 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd")) {
2254 AddDefaultSrcDestOperands(Operands,
2255 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2256 DefaultMemDIOperand(NameLoc));
2259 // Append default arguments to "outs[bwld]"
2260 if (Name.startswith("outs") && Operands.size() == 1 &&
2261 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2262 Name == "outsd" )) {
2263 AddDefaultSrcDestOperands(Operands,
2264 DefaultMemSIOperand(NameLoc),
2265 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2268 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2269 // values of $SIREG according to the mode. It would be nice if this
2270 // could be achieved with InstAlias in the tables.
2271 if (Name.startswith("lods") && Operands.size() == 1 &&
2272 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2273 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2274 Operands.push_back(DefaultMemSIOperand(NameLoc));
2276 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2277 // values of $DIREG according to the mode. It would be nice if this
2278 // could be achieved with InstAlias in the tables.
2279 if (Name.startswith("stos") && Operands.size() == 1 &&
2280 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2281 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2282 Operands.push_back(DefaultMemDIOperand(NameLoc));
2284 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2285 // values of $DIREG according to the mode. It would be nice if this
2286 // could be achieved with InstAlias in the tables.
2287 if (Name.startswith("scas") && Operands.size() == 1 &&
2288 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2289 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2290 Operands.push_back(DefaultMemDIOperand(NameLoc));
2292 // Add default SI and DI operands to "cmps[bwlq]".
2293 if (Name.startswith("cmps") &&
2294 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2295 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2296 if (Operands.size() == 1) {
2297 AddDefaultSrcDestOperands(Operands,
2298 DefaultMemDIOperand(NameLoc),
2299 DefaultMemSIOperand(NameLoc));
2300 } else if (Operands.size() == 3) {
2301 X86Operand &Op = (X86Operand &)*Operands[1];
2302 X86Operand &Op2 = (X86Operand &)*Operands[2];
2303 if (!doSrcDstMatch(Op, Op2))
2304 return Error(Op.getStartLoc(),
2305 "mismatching source and destination index registers");
2309 // Add default SI and DI operands to "movs[bwlq]".
2310 if ((Name.startswith("movs") &&
2311 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2312 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2313 (Name.startswith("smov") &&
2314 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2315 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2316 if (Operands.size() == 1) {
2317 if (Name == "movsd")
2318 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2319 AddDefaultSrcDestOperands(Operands,
2320 DefaultMemSIOperand(NameLoc),
2321 DefaultMemDIOperand(NameLoc));
2322 } else if (Operands.size() == 3) {
2323 X86Operand &Op = (X86Operand &)*Operands[1];
2324 X86Operand &Op2 = (X86Operand &)*Operands[2];
2325 if (!doSrcDstMatch(Op, Op2))
2326 return Error(Op.getStartLoc(),
2327 "mismatching source and destination index registers");
2331 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2333 if ((Name.startswith("shr") || Name.startswith("sar") ||
2334 Name.startswith("shl") || Name.startswith("sal") ||
2335 Name.startswith("rcl") || Name.startswith("rcr") ||
2336 Name.startswith("rol") || Name.startswith("ror")) &&
2337 Operands.size() == 3) {
2338 if (isParsingIntelSyntax()) {
2340 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2341 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2342 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2343 Operands.pop_back();
2345 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2346 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2347 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2348 Operands.erase(Operands.begin() + 1);
2352 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2353 // instalias with an immediate operand yet.
2354 if (Name == "int" && Operands.size() == 2) {
2355 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2357 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2358 if (CE->getValue() == 3) {
2359 Operands.erase(Operands.begin() + 1);
2360 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2367 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2370 TmpInst.setOpcode(Opcode);
2372 TmpInst.addOperand(MCOperand::createReg(Reg));
2373 TmpInst.addOperand(MCOperand::createReg(Reg));
2374 TmpInst.addOperand(Inst.getOperand(0));
2379 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2380 bool isCmp = false) {
2381 if (!Inst.getOperand(0).isImm() ||
2382 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2385 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2388 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2389 bool isCmp = false) {
2390 if (!Inst.getOperand(0).isImm() ||
2391 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2394 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2397 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2398 bool isCmp = false) {
2399 if (!Inst.getOperand(0).isImm() ||
2400 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2403 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2406 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2407 switch (Inst.getOpcode()) {
2408 default: return true;
2410 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2411 assert(Op.isImm() && "expected immediate");
2413 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2414 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2419 llvm_unreachable("handle the instruction appropriately");
2422 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2423 switch (Inst.getOpcode()) {
2424 default: return false;
2425 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2426 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2427 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2428 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2429 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2430 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2431 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2432 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2433 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2434 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2435 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2436 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2437 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2438 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2439 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2440 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2441 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2442 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2443 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2444 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2445 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2446 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2447 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2448 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2449 case X86::VMOVAPDrr:
2450 case X86::VMOVAPDYrr:
2451 case X86::VMOVAPSrr:
2452 case X86::VMOVAPSYrr:
2453 case X86::VMOVDQArr:
2454 case X86::VMOVDQAYrr:
2455 case X86::VMOVDQUrr:
2456 case X86::VMOVDQUYrr:
2457 case X86::VMOVUPDrr:
2458 case X86::VMOVUPDYrr:
2459 case X86::VMOVUPSrr:
2460 case X86::VMOVUPSYrr: {
2461 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2462 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2466 switch (Inst.getOpcode()) {
2467 default: llvm_unreachable("Invalid opcode");
2468 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2469 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2470 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2471 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2472 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2473 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2474 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2475 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2476 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2477 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2478 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2479 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2481 Inst.setOpcode(NewOpc);
2485 case X86::VMOVSSrr: {
2486 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2487 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2490 switch (Inst.getOpcode()) {
2491 default: llvm_unreachable("Invalid opcode");
2492 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2493 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2495 Inst.setOpcode(NewOpc);
2501 static const char *getSubtargetFeatureName(uint64_t Val);
2503 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2505 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2509 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2510 OperandVector &Operands,
2511 MCStreamer &Out, uint64_t &ErrorInfo,
2512 bool MatchingInlineAsm) {
2513 if (isParsingIntelSyntax())
2514 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2516 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2520 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2521 OperandVector &Operands, MCStreamer &Out,
2522 bool MatchingInlineAsm) {
2523 // FIXME: This should be replaced with a real .td file alias mechanism.
2524 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2526 const char *Repl = StringSwitch<const char *>(Op.getToken())
2527 .Case("finit", "fninit")
2528 .Case("fsave", "fnsave")
2529 .Case("fstcw", "fnstcw")
2530 .Case("fstcww", "fnstcw")
2531 .Case("fstenv", "fnstenv")
2532 .Case("fstsw", "fnstsw")
2533 .Case("fstsww", "fnstsw")
2534 .Case("fclex", "fnclex")
2538 Inst.setOpcode(X86::WAIT);
2540 if (!MatchingInlineAsm)
2541 EmitInstruction(Inst, Operands, Out);
2542 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2546 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2547 bool MatchingInlineAsm) {
2548 assert(ErrorInfo && "Unknown missing feature!");
2549 ArrayRef<SMRange> EmptyRanges = None;
2550 SmallString<126> Msg;
2551 raw_svector_ostream OS(Msg);
2552 OS << "instruction requires:";
2554 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2555 if (ErrorInfo & Mask)
2556 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2559 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2562 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2563 OperandVector &Operands,
2565 uint64_t &ErrorInfo,
2566 bool MatchingInlineAsm) {
2567 assert(!Operands.empty() && "Unexpect empty operand list!");
2568 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2569 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2570 ArrayRef<SMRange> EmptyRanges = None;
2572 // First, handle aliases that expand to multiple instructions.
2573 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2575 bool WasOriginallyInvalidOperand = false;
2578 // First, try a direct match.
2579 switch (MatchInstructionImpl(Operands, Inst,
2580 ErrorInfo, MatchingInlineAsm,
2581 isParsingIntelSyntax())) {
2582 default: llvm_unreachable("Unexpected match result!");
2584 if (!validateInstruction(Inst, Operands))
2587 // Some instructions need post-processing to, for example, tweak which
2588 // encoding is selected. Loop on it while changes happen so the
2589 // individual transformations can chain off each other.
2590 if (!MatchingInlineAsm)
2591 while (processInstruction(Inst, Operands))
2595 if (!MatchingInlineAsm)
2596 EmitInstruction(Inst, Operands, Out);
2597 Opcode = Inst.getOpcode();
2599 case Match_MissingFeature:
2600 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2601 case Match_InvalidOperand:
2602 WasOriginallyInvalidOperand = true;
2604 case Match_MnemonicFail:
2608 // FIXME: Ideally, we would only attempt suffix matches for things which are
2609 // valid prefixes, and we could just infer the right unambiguous
2610 // type. However, that requires substantially more matcher support than the
2613 // Change the operand to point to a temporary token.
2614 StringRef Base = Op.getToken();
2615 SmallString<16> Tmp;
2618 Op.setTokenValue(Tmp);
2620 // If this instruction starts with an 'f', then it is a floating point stack
2621 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2622 // 80-bit floating point, which use the suffixes s,l,t respectively.
2624 // Otherwise, we assume that this may be an integer instruction, which comes
2625 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2626 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2628 // Check for the various suffix matches.
2629 uint64_t ErrorInfoIgnore;
2630 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2633 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2634 Tmp.back() = Suffixes[I];
2635 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2636 MatchingInlineAsm, isParsingIntelSyntax());
2637 // If this returned as a missing feature failure, remember that.
2638 if (Match[I] == Match_MissingFeature)
2639 ErrorInfoMissingFeature = ErrorInfoIgnore;
2642 // Restore the old token.
2643 Op.setTokenValue(Base);
2645 // If exactly one matched, then we treat that as a successful match (and the
2646 // instruction will already have been filled in correctly, since the failing
2647 // matches won't have modified it).
2648 unsigned NumSuccessfulMatches =
2649 std::count(std::begin(Match), std::end(Match), Match_Success);
2650 if (NumSuccessfulMatches == 1) {
2652 if (!MatchingInlineAsm)
2653 EmitInstruction(Inst, Operands, Out);
2654 Opcode = Inst.getOpcode();
2658 // Otherwise, the match failed, try to produce a decent error message.
2660 // If we had multiple suffix matches, then identify this as an ambiguous
2662 if (NumSuccessfulMatches > 1) {
2664 unsigned NumMatches = 0;
2665 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2666 if (Match[I] == Match_Success)
2667 MatchChars[NumMatches++] = Suffixes[I];
2669 SmallString<126> Msg;
2670 raw_svector_ostream OS(Msg);
2671 OS << "ambiguous instructions require an explicit suffix (could be ";
2672 for (unsigned i = 0; i != NumMatches; ++i) {
2675 if (i + 1 == NumMatches)
2677 OS << "'" << Base << MatchChars[i] << "'";
2680 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2684 // Okay, we know that none of the variants matched successfully.
2686 // If all of the instructions reported an invalid mnemonic, then the original
2687 // mnemonic was invalid.
2688 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2689 if (!WasOriginallyInvalidOperand) {
2690 ArrayRef<SMRange> Ranges =
2691 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2692 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2693 Ranges, MatchingInlineAsm);
2696 // Recover location info for the operand if we know which was the problem.
2697 if (ErrorInfo != ~0ULL) {
2698 if (ErrorInfo >= Operands.size())
2699 return Error(IDLoc, "too few operands for instruction",
2700 EmptyRanges, MatchingInlineAsm);
2702 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2703 if (Operand.getStartLoc().isValid()) {
2704 SMRange OperandRange = Operand.getLocRange();
2705 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2706 OperandRange, MatchingInlineAsm);
2710 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2714 // If one instruction matched with a missing feature, report this as a
2716 if (std::count(std::begin(Match), std::end(Match),
2717 Match_MissingFeature) == 1) {
2718 ErrorInfo = ErrorInfoMissingFeature;
2719 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2723 // If one instruction matched with an invalid operand, report this as an
2725 if (std::count(std::begin(Match), std::end(Match),
2726 Match_InvalidOperand) == 1) {
2727 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2731 // If all of these were an outright failure, report it in a useless way.
2732 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2733 EmptyRanges, MatchingInlineAsm);
2737 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2738 OperandVector &Operands,
2740 uint64_t &ErrorInfo,
2741 bool MatchingInlineAsm) {
2742 assert(!Operands.empty() && "Unexpect empty operand list!");
2743 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2744 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2745 StringRef Mnemonic = Op.getToken();
2746 ArrayRef<SMRange> EmptyRanges = None;
2748 // First, handle aliases that expand to multiple instructions.
2749 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2753 // Find one unsized memory operand, if present.
2754 X86Operand *UnsizedMemOp = nullptr;
2755 for (const auto &Op : Operands) {
2756 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2757 if (X86Op->isMemUnsized())
2758 UnsizedMemOp = X86Op;
2761 // Allow some instructions to have implicitly pointer-sized operands. This is
2762 // compatible with gas.
2764 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2765 for (const char *Instr : PtrSizedInstrs) {
2766 if (Mnemonic == Instr) {
2767 UnsizedMemOp->Mem.Size = getPointerWidth();
2773 // If an unsized memory operand is present, try to match with each memory
2774 // operand size. In Intel assembly, the size is not part of the instruction
2776 SmallVector<unsigned, 8> Match;
2777 uint64_t ErrorInfoMissingFeature = 0;
2778 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2779 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2780 for (unsigned Size : MopSizes) {
2781 UnsizedMemOp->Mem.Size = Size;
2782 uint64_t ErrorInfoIgnore;
2783 unsigned LastOpcode = Inst.getOpcode();
2785 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2786 MatchingInlineAsm, isParsingIntelSyntax());
2787 if (Match.empty() || LastOpcode != Inst.getOpcode())
2790 // If this returned as a missing feature failure, remember that.
2791 if (Match.back() == Match_MissingFeature)
2792 ErrorInfoMissingFeature = ErrorInfoIgnore;
2795 // Restore the size of the unsized memory operand if we modified it.
2797 UnsizedMemOp->Mem.Size = 0;
2800 // If we haven't matched anything yet, this is not a basic integer or FPU
2801 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2802 // matching with the unsized operand.
2803 if (Match.empty()) {
2804 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2806 isParsingIntelSyntax()));
2807 // If this returned as a missing feature failure, remember that.
2808 if (Match.back() == Match_MissingFeature)
2809 ErrorInfoMissingFeature = ErrorInfo;
2812 // Restore the size of the unsized memory operand if we modified it.
2814 UnsizedMemOp->Mem.Size = 0;
2816 // If it's a bad mnemonic, all results will be the same.
2817 if (Match.back() == Match_MnemonicFail) {
2818 ArrayRef<SMRange> Ranges =
2819 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2820 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2821 Ranges, MatchingInlineAsm);
2824 // If exactly one matched, then we treat that as a successful match (and the
2825 // instruction will already have been filled in correctly, since the failing
2826 // matches won't have modified it).
2827 unsigned NumSuccessfulMatches =
2828 std::count(std::begin(Match), std::end(Match), Match_Success);
2829 if (NumSuccessfulMatches == 1) {
2830 if (!validateInstruction(Inst, Operands))
2833 // Some instructions need post-processing to, for example, tweak which
2834 // encoding is selected. Loop on it while changes happen so the individual
2835 // transformations can chain off each other.
2836 if (!MatchingInlineAsm)
2837 while (processInstruction(Inst, Operands))
2840 if (!MatchingInlineAsm)
2841 EmitInstruction(Inst, Operands, Out);
2842 Opcode = Inst.getOpcode();
2844 } else if (NumSuccessfulMatches > 1) {
2845 assert(UnsizedMemOp &&
2846 "multiple matches only possible with unsized memory operands");
2847 ArrayRef<SMRange> Ranges =
2848 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2849 return Error(UnsizedMemOp->getStartLoc(),
2850 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2851 Ranges, MatchingInlineAsm);
2854 // If one instruction matched with a missing feature, report this as a
2856 if (std::count(std::begin(Match), std::end(Match),
2857 Match_MissingFeature) == 1) {
2858 ErrorInfo = ErrorInfoMissingFeature;
2859 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2863 // If one instruction matched with an invalid operand, report this as an
2865 if (std::count(std::begin(Match), std::end(Match),
2866 Match_InvalidOperand) == 1) {
2867 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2871 // If all of these were an outright failure, report it in a useless way.
2872 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2876 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2877 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2880 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2881 MCAsmParser &Parser = getParser();
2882 StringRef IDVal = DirectiveID.getIdentifier();
2883 if (IDVal == ".word")
2884 return ParseDirectiveWord(2, DirectiveID.getLoc());
2885 else if (IDVal.startswith(".code"))
2886 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2887 else if (IDVal.startswith(".att_syntax")) {
2888 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2889 if (Parser.getTok().getString() == "prefix")
2891 else if (Parser.getTok().getString() == "noprefix")
2892 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2893 "supported: registers must have a "
2894 "'%' prefix in .att_syntax");
2896 getParser().setAssemblerDialect(0);
2898 } else if (IDVal.startswith(".intel_syntax")) {
2899 getParser().setAssemblerDialect(1);
2900 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2901 if (Parser.getTok().getString() == "noprefix")
2903 else if (Parser.getTok().getString() == "prefix")
2904 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2905 "supported: registers must not have "
2906 "a '%' prefix in .intel_syntax");
2913 /// ParseDirectiveWord
2914 /// ::= .word [ expression (, expression)* ]
2915 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2916 MCAsmParser &Parser = getParser();
2917 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2919 const MCExpr *Value;
2920 if (getParser().parseExpression(Value))
2923 getParser().getStreamer().EmitValue(Value, Size);
2925 if (getLexer().is(AsmToken::EndOfStatement))
2928 // FIXME: Improve diagnostic.
2929 if (getLexer().isNot(AsmToken::Comma)) {
2930 Error(L, "unexpected token in directive");
2941 /// ParseDirectiveCode
2942 /// ::= .code16 | .code32 | .code64
2943 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2944 MCAsmParser &Parser = getParser();
2945 if (IDVal == ".code16") {
2947 if (!is16BitMode()) {
2948 SwitchMode(X86::Mode16Bit);
2949 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2951 } else if (IDVal == ".code32") {
2953 if (!is32BitMode()) {
2954 SwitchMode(X86::Mode32Bit);
2955 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2957 } else if (IDVal == ".code64") {
2959 if (!is64BitMode()) {
2960 SwitchMode(X86::Mode64Bit);
2961 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2964 Error(L, "unknown directive " + IDVal);
2971 // Force static initialization.
2972 extern "C" void LLVMInitializeX86AsmParser() {
2973 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2974 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2977 #define GET_REGISTER_MATCHER
2978 #define GET_MATCHER_IMPLEMENTATION
2979 #define GET_SUBTARGET_FEATURE_NAME
2980 #include "X86GenAsmMatcher.inc"