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;
65 SMLoc consumeToken() {
66 MCAsmParser &Parser = getParser();
67 SMLoc Result = Parser.getTok().getLoc();
72 enum InfixCalculatorTok {
88 class InfixCalculator {
89 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
90 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
91 SmallVector<ICToken, 4> PostfixStack;
94 int64_t popOperand() {
95 assert (!PostfixStack.empty() && "Poped an empty stack!");
96 ICToken Op = PostfixStack.pop_back_val();
97 assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
98 && "Expected and immediate or register!");
101 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
102 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
103 "Unexpected operand!");
104 PostfixStack.push_back(std::make_pair(Op, Val));
107 void popOperator() { InfixOperatorStack.pop_back(); }
108 void pushOperator(InfixCalculatorTok Op) {
109 // Push the new operator if the stack is empty.
110 if (InfixOperatorStack.empty()) {
111 InfixOperatorStack.push_back(Op);
115 // Push the new operator if it has a higher precedence than the operator
116 // on the top of the stack or the operator on the top of the stack is a
118 unsigned Idx = InfixOperatorStack.size() - 1;
119 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
120 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
121 InfixOperatorStack.push_back(Op);
125 // The operator on the top of the stack has higher precedence than the
127 unsigned ParenCount = 0;
129 // Nothing to process.
130 if (InfixOperatorStack.empty())
133 Idx = InfixOperatorStack.size() - 1;
134 StackOp = InfixOperatorStack[Idx];
135 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
138 // If we have an even parentheses count and we see a left parentheses,
139 // then stop processing.
140 if (!ParenCount && StackOp == IC_LPAREN)
143 if (StackOp == IC_RPAREN) {
145 InfixOperatorStack.pop_back();
146 } else if (StackOp == IC_LPAREN) {
148 InfixOperatorStack.pop_back();
150 InfixOperatorStack.pop_back();
151 PostfixStack.push_back(std::make_pair(StackOp, 0));
154 // Push the new operator.
155 InfixOperatorStack.push_back(Op);
158 // Push any remaining operators onto the postfix stack.
159 while (!InfixOperatorStack.empty()) {
160 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
161 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
162 PostfixStack.push_back(std::make_pair(StackOp, 0));
165 if (PostfixStack.empty())
168 SmallVector<ICToken, 16> OperandStack;
169 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
170 ICToken Op = PostfixStack[i];
171 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
172 OperandStack.push_back(Op);
174 assert (OperandStack.size() > 1 && "Too few operands.");
176 ICToken Op2 = OperandStack.pop_back_val();
177 ICToken Op1 = OperandStack.pop_back_val();
180 report_fatal_error("Unexpected operator!");
183 Val = Op1.second + Op2.second;
184 OperandStack.push_back(std::make_pair(IC_IMM, Val));
187 Val = Op1.second - Op2.second;
188 OperandStack.push_back(std::make_pair(IC_IMM, Val));
191 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
192 "Multiply operation with an immediate and a register!");
193 Val = Op1.second * Op2.second;
194 OperandStack.push_back(std::make_pair(IC_IMM, Val));
197 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
198 "Divide operation with an immediate and a register!");
199 assert (Op2.second != 0 && "Division by zero!");
200 Val = Op1.second / Op2.second;
201 OperandStack.push_back(std::make_pair(IC_IMM, Val));
204 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
205 "Or operation with an immediate and a register!");
206 Val = Op1.second | Op2.second;
207 OperandStack.push_back(std::make_pair(IC_IMM, Val));
210 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
211 "Xor operation with an immediate and a register!");
212 Val = Op1.second ^ Op2.second;
213 OperandStack.push_back(std::make_pair(IC_IMM, Val));
216 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
217 "And operation with an immediate and a register!");
218 Val = Op1.second & Op2.second;
219 OperandStack.push_back(std::make_pair(IC_IMM, Val));
222 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
223 "Left shift operation with an immediate and a register!");
224 Val = Op1.second << Op2.second;
225 OperandStack.push_back(std::make_pair(IC_IMM, Val));
228 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
229 "Right shift operation with an immediate and a register!");
230 Val = Op1.second >> Op2.second;
231 OperandStack.push_back(std::make_pair(IC_IMM, Val));
236 assert (OperandStack.size() == 1 && "Expected a single result.");
237 return OperandStack.pop_back_val().second;
241 enum IntelExprState {
262 class IntelExprStateMachine {
263 IntelExprState State, PrevState;
264 unsigned BaseReg, IndexReg, TmpReg, Scale;
268 bool StopOnLBrac, AddImmPrefix;
270 InlineAsmIdentifierInfo Info;
272 IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
273 State(IES_PLUS), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), TmpReg(0),
274 Scale(1), Imm(imm), Sym(nullptr), StopOnLBrac(stoponlbrac),
275 AddImmPrefix(addimmprefix) { Info.clear(); }
277 unsigned getBaseReg() { return BaseReg; }
278 unsigned getIndexReg() { return IndexReg; }
279 unsigned getScale() { return Scale; }
280 const MCExpr *getSym() { return Sym; }
281 StringRef getSymName() { return SymName; }
282 int64_t getImm() { return Imm + IC.execute(); }
283 bool isValidEndState() {
284 return State == IES_RBRAC || State == IES_INTEGER;
286 bool getStopOnLBrac() { return StopOnLBrac; }
287 bool getAddImmPrefix() { return AddImmPrefix; }
288 bool hadError() { return State == IES_ERROR; }
290 InlineAsmIdentifierInfo &getIdentifierInfo() {
295 IntelExprState CurrState = State;
304 IC.pushOperator(IC_OR);
307 PrevState = CurrState;
310 IntelExprState CurrState = State;
319 IC.pushOperator(IC_XOR);
322 PrevState = CurrState;
325 IntelExprState CurrState = State;
334 IC.pushOperator(IC_AND);
337 PrevState = CurrState;
340 IntelExprState CurrState = State;
349 IC.pushOperator(IC_LSHIFT);
352 PrevState = CurrState;
355 IntelExprState CurrState = State;
364 IC.pushOperator(IC_RSHIFT);
367 PrevState = CurrState;
370 IntelExprState CurrState = State;
379 IC.pushOperator(IC_PLUS);
380 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
381 // If we already have a BaseReg, then assume this is the IndexReg with
386 assert (!IndexReg && "BaseReg/IndexReg already set!");
393 PrevState = CurrState;
396 IntelExprState CurrState = State;
412 // Only push the minus operator if it is not a unary operator.
413 if (!(CurrState == IES_PLUS || CurrState == IES_MINUS ||
414 CurrState == IES_MULTIPLY || CurrState == IES_DIVIDE ||
415 CurrState == IES_LPAREN || CurrState == IES_LBRAC))
416 IC.pushOperator(IC_MINUS);
417 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
418 // If we already have a BaseReg, then assume this is the IndexReg with
423 assert (!IndexReg && "BaseReg/IndexReg already set!");
430 PrevState = CurrState;
433 IntelExprState CurrState = State;
443 PrevState = CurrState;
445 void onRegister(unsigned Reg) {
446 IntelExprState CurrState = State;
453 State = IES_REGISTER;
455 IC.pushOperand(IC_REGISTER);
458 // Index Register - Scale * Register
459 if (PrevState == IES_INTEGER) {
460 assert (!IndexReg && "IndexReg already set!");
461 State = IES_REGISTER;
463 // Get the scale and replace the 'Scale * Register' with '0'.
464 Scale = IC.popOperand();
465 IC.pushOperand(IC_IMM);
472 PrevState = CurrState;
474 void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) {
485 SymName = SymRefName;
486 IC.pushOperand(IC_IMM);
490 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
491 IntelExprState CurrState = State;
508 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
509 // Index Register - Register * Scale
510 assert (!IndexReg && "IndexReg already set!");
513 if(Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
514 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
517 // Get the scale and replace the 'Register * Scale' with '0'.
519 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
520 PrevState == IES_OR || PrevState == IES_AND ||
521 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
522 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
523 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
524 PrevState == IES_NOT || PrevState == IES_XOR) &&
525 CurrState == IES_MINUS) {
526 // Unary minus. No need to pop the minus operand because it was never
528 IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm.
529 } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
530 PrevState == IES_OR || PrevState == IES_AND ||
531 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
532 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
533 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
534 PrevState == IES_NOT || PrevState == IES_XOR) &&
535 CurrState == IES_NOT) {
536 // Unary not. No need to pop the not operand because it was never
538 IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.
540 IC.pushOperand(IC_IMM, TmpInt);
544 PrevState = CurrState;
556 State = IES_MULTIPLY;
557 IC.pushOperator(IC_MULTIPLY);
570 IC.pushOperator(IC_DIVIDE);
582 IC.pushOperator(IC_PLUS);
587 IntelExprState CurrState = State;
596 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
597 // If we already have a BaseReg, then assume this is the IndexReg with
602 assert (!IndexReg && "BaseReg/IndexReg already set!");
609 PrevState = CurrState;
612 IntelExprState CurrState = State;
628 // FIXME: We don't handle this type of unary minus or not, yet.
629 if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
630 PrevState == IES_OR || PrevState == IES_AND ||
631 PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
632 PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
633 PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
634 PrevState == IES_NOT || PrevState == IES_XOR) &&
635 (CurrState == IES_MINUS || CurrState == IES_NOT)) {
640 IC.pushOperator(IC_LPAREN);
643 PrevState = CurrState;
655 IC.pushOperator(IC_RPAREN);
661 bool Error(SMLoc L, const Twine &Msg,
662 ArrayRef<SMRange> Ranges = None,
663 bool MatchingInlineAsm = false) {
664 MCAsmParser &Parser = getParser();
665 if (MatchingInlineAsm) return true;
666 return Parser.Error(L, Msg, Ranges);
669 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
670 ArrayRef<SMRange> Ranges = None,
671 bool MatchingInlineAsm = false) {
672 MCAsmParser &Parser = getParser();
673 Parser.eatToEndOfStatement();
674 return Error(L, Msg, Ranges, MatchingInlineAsm);
677 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) {
682 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
683 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
684 void AddDefaultSrcDestOperands(
685 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
686 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
687 std::unique_ptr<X86Operand> ParseOperand();
688 std::unique_ptr<X86Operand> ParseATTOperand();
689 std::unique_ptr<X86Operand> ParseIntelOperand();
690 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
691 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
692 std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
693 std::unique_ptr<X86Operand>
694 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
695 std::unique_ptr<X86Operand>
696 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
697 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
698 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
699 std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg,
703 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
704 InlineAsmIdentifierInfo &Info,
705 bool IsUnevaluatedOperand, SMLoc &End);
707 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
709 std::unique_ptr<X86Operand>
710 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
711 unsigned IndexReg, unsigned Scale, SMLoc Start,
712 SMLoc End, unsigned Size, StringRef Identifier,
713 InlineAsmIdentifierInfo &Info);
715 bool ParseDirectiveWord(unsigned Size, SMLoc L);
716 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
718 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
719 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
721 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
722 /// instrumentation around Inst.
723 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
725 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
726 OperandVector &Operands, MCStreamer &Out,
728 bool MatchingInlineAsm) override;
730 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
731 MCStreamer &Out, bool MatchingInlineAsm);
733 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
734 bool MatchingInlineAsm);
736 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
737 OperandVector &Operands, MCStreamer &Out,
739 bool MatchingInlineAsm);
741 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
742 OperandVector &Operands, MCStreamer &Out,
744 bool MatchingInlineAsm);
746 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
748 /// doSrcDstMatch - Returns true if operands are matching in their
749 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
750 /// the parsing mode (Intel vs. AT&T).
751 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
753 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
754 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
755 /// \return \c true if no parsing errors occurred, \c false otherwise.
756 bool HandleAVX512Operand(OperandVector &Operands,
757 const MCParsedAsmOperand &Op);
759 bool is64BitMode() const {
760 // FIXME: Can tablegen auto-generate this?
761 return STI.getFeatureBits()[X86::Mode64Bit];
763 bool is32BitMode() const {
764 // FIXME: Can tablegen auto-generate this?
765 return STI.getFeatureBits()[X86::Mode32Bit];
767 bool is16BitMode() const {
768 // FIXME: Can tablegen auto-generate this?
769 return STI.getFeatureBits()[X86::Mode16Bit];
771 void SwitchMode(unsigned mode) {
772 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
773 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
774 unsigned FB = ComputeAvailableFeatures(
775 STI.ToggleFeature(OldMode.flip(mode)));
776 setAvailableFeatures(FB);
778 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
781 unsigned getPointerWidth() {
782 if (is16BitMode()) return 16;
783 if (is32BitMode()) return 32;
784 if (is64BitMode()) return 64;
785 llvm_unreachable("invalid mode");
788 bool isParsingIntelSyntax() {
789 return getParser().getAssemblerDialect();
792 /// @name Auto-generated Matcher Functions
795 #define GET_ASSEMBLER_HEADER
796 #include "X86GenAsmMatcher.inc"
801 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &Parser,
802 const MCInstrInfo &mii, const MCTargetOptions &Options)
803 : MCTargetAsmParser(Options), STI(sti), MII(mii), InstInfo(nullptr) {
805 // Initialize the set of available features.
806 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
807 Instrumentation.reset(
808 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI));
811 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
813 void SetFrameRegister(unsigned RegNo) override;
815 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
816 SMLoc NameLoc, OperandVector &Operands) override;
818 bool ParseDirective(AsmToken DirectiveID) override;
820 } // end anonymous namespace
822 /// @name Auto-generated Match Functions
825 static unsigned MatchRegisterName(StringRef Name);
829 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
831 // If we have both a base register and an index register make sure they are
832 // both 64-bit or 32-bit registers.
833 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
834 if (BaseReg != 0 && IndexReg != 0) {
835 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
836 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
837 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
838 IndexReg != X86::RIZ) {
839 ErrMsg = "base register is 64-bit, but index register is not";
842 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
843 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
844 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
845 IndexReg != X86::EIZ){
846 ErrMsg = "base register is 32-bit, but index register is not";
849 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
850 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
851 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
852 ErrMsg = "base register is 16-bit, but index register is not";
855 if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
856 IndexReg != X86::SI && IndexReg != X86::DI) ||
857 ((BaseReg == X86::SI || BaseReg == X86::DI) &&
858 IndexReg != X86::BX && IndexReg != X86::BP)) {
859 ErrMsg = "invalid 16-bit base/index register combination";
867 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
869 // Return true and let a normal complaint about bogus operands happen.
870 if (!Op1.isMem() || !Op2.isMem())
873 // Actually these might be the other way round if Intel syntax is
874 // being used. It doesn't matter.
875 unsigned diReg = Op1.Mem.BaseReg;
876 unsigned siReg = Op2.Mem.BaseReg;
878 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
879 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
880 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
881 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
882 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
883 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
884 // Again, return true and let another error happen.
888 bool X86AsmParser::ParseRegister(unsigned &RegNo,
889 SMLoc &StartLoc, SMLoc &EndLoc) {
890 MCAsmParser &Parser = getParser();
892 const AsmToken &PercentTok = Parser.getTok();
893 StartLoc = PercentTok.getLoc();
895 // If we encounter a %, ignore it. This code handles registers with and
896 // without the prefix, unprefixed registers can occur in cfi directives.
897 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
898 Parser.Lex(); // Eat percent token.
900 const AsmToken &Tok = Parser.getTok();
901 EndLoc = Tok.getEndLoc();
903 if (Tok.isNot(AsmToken::Identifier)) {
904 if (isParsingIntelSyntax()) return true;
905 return Error(StartLoc, "invalid register name",
906 SMRange(StartLoc, EndLoc));
909 RegNo = MatchRegisterName(Tok.getString());
911 // If the match failed, try the register name as lowercase.
913 RegNo = MatchRegisterName(Tok.getString().lower());
915 // The "flags" register cannot be referenced directly.
916 // Treat it as an identifier instead.
917 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS)
920 if (!is64BitMode()) {
921 // FIXME: This should be done using Requires<Not64BitMode> and
922 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
924 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
926 if (RegNo == X86::RIZ ||
927 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
928 X86II::isX86_64NonExtLowByteReg(RegNo) ||
929 X86II::isX86_64ExtendedReg(RegNo))
930 return Error(StartLoc, "register %"
931 + Tok.getString() + " is only available in 64-bit mode",
932 SMRange(StartLoc, EndLoc));
935 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
936 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
938 Parser.Lex(); // Eat 'st'
940 // Check to see if we have '(4)' after %st.
941 if (getLexer().isNot(AsmToken::LParen))
946 const AsmToken &IntTok = Parser.getTok();
947 if (IntTok.isNot(AsmToken::Integer))
948 return Error(IntTok.getLoc(), "expected stack index");
949 switch (IntTok.getIntVal()) {
950 case 0: RegNo = X86::ST0; break;
951 case 1: RegNo = X86::ST1; break;
952 case 2: RegNo = X86::ST2; break;
953 case 3: RegNo = X86::ST3; break;
954 case 4: RegNo = X86::ST4; break;
955 case 5: RegNo = X86::ST5; break;
956 case 6: RegNo = X86::ST6; break;
957 case 7: RegNo = X86::ST7; break;
958 default: return Error(IntTok.getLoc(), "invalid stack index");
961 if (getParser().Lex().isNot(AsmToken::RParen))
962 return Error(Parser.getTok().getLoc(), "expected ')'");
964 EndLoc = Parser.getTok().getEndLoc();
965 Parser.Lex(); // Eat ')'
969 EndLoc = Parser.getTok().getEndLoc();
971 // If this is "db[0-7]", match it as an alias
973 if (RegNo == 0 && Tok.getString().size() == 3 &&
974 Tok.getString().startswith("db")) {
975 switch (Tok.getString()[2]) {
976 case '0': RegNo = X86::DR0; break;
977 case '1': RegNo = X86::DR1; break;
978 case '2': RegNo = X86::DR2; break;
979 case '3': RegNo = X86::DR3; break;
980 case '4': RegNo = X86::DR4; break;
981 case '5': RegNo = X86::DR5; break;
982 case '6': RegNo = X86::DR6; break;
983 case '7': RegNo = X86::DR7; break;
987 EndLoc = Parser.getTok().getEndLoc();
988 Parser.Lex(); // Eat it.
994 if (isParsingIntelSyntax()) return true;
995 return Error(StartLoc, "invalid register name",
996 SMRange(StartLoc, EndLoc));
999 Parser.Lex(); // Eat identifier token.
1003 void X86AsmParser::SetFrameRegister(unsigned RegNo) {
1004 Instrumentation->SetInitialFrameRegister(RegNo);
1007 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1009 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1010 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1011 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1012 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1016 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1018 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1019 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
1020 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1021 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1025 void X86AsmParser::AddDefaultSrcDestOperands(
1026 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
1027 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
1028 if (isParsingIntelSyntax()) {
1029 Operands.push_back(std::move(Dst));
1030 Operands.push_back(std::move(Src));
1033 Operands.push_back(std::move(Src));
1034 Operands.push_back(std::move(Dst));
1038 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
1039 if (isParsingIntelSyntax())
1040 return ParseIntelOperand();
1041 return ParseATTOperand();
1044 /// getIntelMemOperandSize - Return intel memory operand size.
1045 static unsigned getIntelMemOperandSize(StringRef OpStr) {
1046 unsigned Size = StringSwitch<unsigned>(OpStr)
1047 .Cases("BYTE", "byte", 8)
1048 .Cases("WORD", "word", 16)
1049 .Cases("DWORD", "dword", 32)
1050 .Cases("QWORD", "qword", 64)
1051 .Cases("XWORD", "xword", 80)
1052 .Cases("TBYTE", "tbyte", 80)
1053 .Cases("XMMWORD", "xmmword", 128)
1054 .Cases("YMMWORD", "ymmword", 256)
1055 .Cases("ZMMWORD", "zmmword", 512)
1056 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter
1061 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
1062 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
1063 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
1064 InlineAsmIdentifierInfo &Info) {
1065 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
1066 // some other label reference.
1067 if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
1068 // Insert an explicit size if the user didn't have one.
1070 Size = getPointerWidth();
1071 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1075 // Create an absolute memory reference in order to match against
1076 // instructions taking a PC relative operand.
1077 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1078 Identifier, Info.OpDecl);
1081 // We either have a direct symbol reference, or an offset from a symbol. The
1082 // parser always puts the symbol on the LHS, so look there for size
1083 // calculation purposes.
1084 const MCBinaryExpr *BinOp = dyn_cast<MCBinaryExpr>(Disp);
1086 isa<MCSymbolRefExpr>(BinOp ? BinOp->getLHS() : Disp);
1089 Size = Info.Type * 8; // Size is in terms of bits in this context.
1091 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, Start,
1096 // When parsing inline assembly we set the base register to a non-zero value
1097 // if we don't know the actual value at this time. This is necessary to
1098 // get the matching correct in some cases.
1099 BaseReg = BaseReg ? BaseReg : 1;
1100 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1101 IndexReg, Scale, Start, End, Size, Identifier,
1106 RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
1107 StringRef SymName, int64_t ImmDisp,
1108 int64_t FinalImmDisp, SMLoc &BracLoc,
1109 SMLoc &StartInBrac, SMLoc &End) {
1110 // Remove the '[' and ']' from the IR string.
1111 AsmRewrites->push_back(AsmRewrite(AOK_Skip, BracLoc, 1));
1112 AsmRewrites->push_back(AsmRewrite(AOK_Skip, End, 1));
1114 // If ImmDisp is non-zero, then we parsed a displacement before the
1115 // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp])
1116 // If ImmDisp doesn't match the displacement computed by the state machine
1117 // then we have an additional displacement in the bracketed expression.
1118 if (ImmDisp != FinalImmDisp) {
1120 // We have an immediate displacement before the bracketed expression.
1121 // Adjust this to match the final immediate displacement.
1123 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1124 E = AsmRewrites->end(); I != E; ++I) {
1125 if ((*I).Loc.getPointer() > BracLoc.getPointer())
1127 if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
1128 assert (!Found && "ImmDisp already rewritten.");
1129 (*I).Kind = AOK_Imm;
1130 (*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
1131 (*I).Val = FinalImmDisp;
1136 assert (Found && "Unable to rewrite ImmDisp.");
1139 // We have a symbolic and an immediate displacement, but no displacement
1140 // before the bracketed expression. Put the immediate displacement
1141 // before the bracketed expression.
1142 AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
1145 // Remove all the ImmPrefix rewrites within the brackets.
1146 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmRewrites->begin(),
1147 E = AsmRewrites->end(); I != E; ++I) {
1148 if ((*I).Loc.getPointer() < StartInBrac.getPointer())
1150 if ((*I).Kind == AOK_ImmPrefix)
1151 (*I).Kind = AOK_Delete;
1153 const char *SymLocPtr = SymName.data();
1154 // Skip everything before the symbol.
1155 if (unsigned Len = SymLocPtr - StartInBrac.getPointer()) {
1156 assert(Len > 0 && "Expected a non-negative length.");
1157 AsmRewrites->push_back(AsmRewrite(AOK_Skip, StartInBrac, Len));
1159 // Skip everything after the symbol.
1160 if (unsigned Len = End.getPointer() - (SymLocPtr + SymName.size())) {
1161 SMLoc Loc = SMLoc::getFromPointer(SymLocPtr + SymName.size());
1162 assert(Len > 0 && "Expected a non-negative length.");
1163 AsmRewrites->push_back(AsmRewrite(AOK_Skip, Loc, Len));
1167 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1168 MCAsmParser &Parser = getParser();
1169 const AsmToken &Tok = Parser.getTok();
1173 bool UpdateLocLex = true;
1175 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1176 // identifier. Don't try an parse it as a register.
1177 if (Tok.getString().startswith("."))
1180 // If we're parsing an immediate expression, we don't expect a '['.
1181 if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
1184 AsmToken::TokenKind TK = getLexer().getKind();
1187 if (SM.isValidEndState()) {
1191 return Error(Tok.getLoc(), "unknown token in expression");
1193 case AsmToken::EndOfStatement: {
1197 case AsmToken::String:
1198 case AsmToken::Identifier: {
1199 // This could be a register or a symbolic displacement.
1202 SMLoc IdentLoc = Tok.getLoc();
1203 StringRef Identifier = Tok.getString();
1204 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
1205 SM.onRegister(TmpReg);
1206 UpdateLocLex = false;
1209 if (!isParsingInlineAsm()) {
1210 if (getParser().parsePrimaryExpr(Val, End))
1211 return Error(Tok.getLoc(), "Unexpected identifier!");
1213 // This is a dot operator, not an adjacent identifier.
1214 if (Identifier.find('.') != StringRef::npos) {
1217 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1218 if (ParseIntelIdentifier(Val, Identifier, Info,
1219 /*Unevaluated=*/false, End))
1223 SM.onIdentifierExpr(Val, Identifier);
1224 UpdateLocLex = false;
1227 return Error(Tok.getLoc(), "Unexpected identifier!");
1229 case AsmToken::Integer: {
1231 if (isParsingInlineAsm() && SM.getAddImmPrefix())
1232 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1234 // Look for 'b' or 'f' following an Integer as a directional label
1235 SMLoc Loc = getTok().getLoc();
1236 int64_t IntVal = getTok().getIntVal();
1237 End = consumeToken();
1238 UpdateLocLex = false;
1239 if (getLexer().getKind() == AsmToken::Identifier) {
1240 StringRef IDVal = getTok().getString();
1241 if (IDVal == "f" || IDVal == "b") {
1243 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
1244 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1246 MCSymbolRefExpr::create(Sym, Variant, getContext());
1247 if (IDVal == "b" && Sym->isUndefined())
1248 return Error(Loc, "invalid reference to undefined symbol");
1249 StringRef Identifier = Sym->getName();
1250 SM.onIdentifierExpr(Val, Identifier);
1251 End = consumeToken();
1253 if (SM.onInteger(IntVal, ErrMsg))
1254 return Error(Loc, ErrMsg);
1257 if (SM.onInteger(IntVal, ErrMsg))
1258 return Error(Loc, ErrMsg);
1262 case AsmToken::Plus: SM.onPlus(); break;
1263 case AsmToken::Minus: SM.onMinus(); break;
1264 case AsmToken::Tilde: SM.onNot(); break;
1265 case AsmToken::Star: SM.onStar(); break;
1266 case AsmToken::Slash: SM.onDivide(); break;
1267 case AsmToken::Pipe: SM.onOr(); break;
1268 case AsmToken::Caret: SM.onXor(); break;
1269 case AsmToken::Amp: SM.onAnd(); break;
1270 case AsmToken::LessLess:
1271 SM.onLShift(); break;
1272 case AsmToken::GreaterGreater:
1273 SM.onRShift(); break;
1274 case AsmToken::LBrac: SM.onLBrac(); break;
1275 case AsmToken::RBrac: SM.onRBrac(); break;
1276 case AsmToken::LParen: SM.onLParen(); break;
1277 case AsmToken::RParen: SM.onRParen(); break;
1280 return Error(Tok.getLoc(), "unknown token in expression");
1282 if (!Done && UpdateLocLex)
1283 End = consumeToken();
1288 std::unique_ptr<X86Operand>
1289 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1290 int64_t ImmDisp, unsigned Size) {
1291 MCAsmParser &Parser = getParser();
1292 const AsmToken &Tok = Parser.getTok();
1293 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
1294 if (getLexer().isNot(AsmToken::LBrac))
1295 return ErrorOperand(BracLoc, "Expected '[' token!");
1296 Parser.Lex(); // Eat '['
1298 SMLoc StartInBrac = Tok.getLoc();
1299 // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
1300 // may have already parsed an immediate displacement before the bracketed
1302 IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
1303 if (ParseIntelExpression(SM, End))
1306 const MCExpr *Disp = nullptr;
1307 if (const MCExpr *Sym = SM.getSym()) {
1308 // A symbolic displacement.
1310 if (isParsingInlineAsm())
1311 RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
1312 ImmDisp, SM.getImm(), BracLoc, StartInBrac,
1316 if (SM.getImm() || !Disp) {
1317 const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext());
1319 Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext());
1321 Disp = Imm; // An immediate displacement only.
1324 // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC
1325 // will in fact do global lookup the field name inside all global typedefs,
1326 // but we don't emulate that.
1327 if (Tok.getString().find('.') != StringRef::npos) {
1328 const MCExpr *NewDisp;
1329 if (ParseIntelDotOperator(Disp, NewDisp))
1332 End = Tok.getEndLoc();
1333 Parser.Lex(); // Eat the field.
1337 int BaseReg = SM.getBaseReg();
1338 int IndexReg = SM.getIndexReg();
1339 int Scale = SM.getScale();
1340 if (!isParsingInlineAsm()) {
1342 if (!BaseReg && !IndexReg) {
1344 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1345 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1349 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
1350 Error(StartInBrac, ErrMsg);
1353 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1354 IndexReg, Scale, Start, End, Size);
1357 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1358 return CreateMemForInlineAsm(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1359 End, Size, SM.getSymName(), Info);
1362 // Inline assembly may use variable names with namespace alias qualifiers.
1363 bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
1364 StringRef &Identifier,
1365 InlineAsmIdentifierInfo &Info,
1366 bool IsUnevaluatedOperand, SMLoc &End) {
1367 MCAsmParser &Parser = getParser();
1368 assert (isParsingInlineAsm() && "Expected to be parsing inline assembly.");
1371 StringRef LineBuf(Identifier.data());
1373 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
1375 const AsmToken &Tok = Parser.getTok();
1376 SMLoc Loc = Tok.getLoc();
1378 // Advance the token stream until the end of the current token is
1379 // after the end of what the frontend claimed.
1380 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
1382 End = Tok.getEndLoc();
1385 assert(End.getPointer() <= EndPtr && "frontend claimed part of a token?");
1386 if (End.getPointer() == EndPtr) break;
1388 Identifier = LineBuf;
1390 // If the identifier lookup was unsuccessful, assume that we are dealing with
1393 StringRef InternalName =
1394 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
1396 assert(InternalName.size() && "We should have an internal name here.");
1397 // Push a rewrite for replacing the identifier name with the internal name.
1398 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Label, Loc,
1403 // Create the symbol reference.
1404 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1405 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1406 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
1410 /// \brief Parse intel style segment override.
1411 std::unique_ptr<X86Operand>
1412 X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1414 MCAsmParser &Parser = getParser();
1415 assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
1416 const AsmToken &Tok = Parser.getTok(); // Eat colon.
1417 if (Tok.isNot(AsmToken::Colon))
1418 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1419 Parser.Lex(); // Eat ':'
1421 int64_t ImmDisp = 0;
1422 if (getLexer().is(AsmToken::Integer)) {
1423 ImmDisp = Tok.getIntVal();
1424 AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
1426 if (isParsingInlineAsm())
1427 InstInfo->AsmRewrites->push_back(
1428 AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
1430 if (getLexer().isNot(AsmToken::LBrac)) {
1431 // An immediate following a 'segment register', 'colon' token sequence can
1432 // be followed by a bracketed expression. If it isn't we know we have our
1433 // final segment override.
1434 const MCExpr *Disp = MCConstantExpr::create(ImmDisp, getContext());
1435 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1436 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1437 Start, ImmDispToken.getEndLoc(), Size);
1441 if (getLexer().is(AsmToken::LBrac))
1442 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
1446 if (!isParsingInlineAsm()) {
1447 if (getParser().parsePrimaryExpr(Val, End))
1448 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1450 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1453 InlineAsmIdentifierInfo Info;
1454 StringRef Identifier = Tok.getString();
1455 if (ParseIntelIdentifier(Val, Identifier, Info,
1456 /*Unevaluated=*/false, End))
1458 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
1459 /*Scale=*/1, Start, End, Size, Identifier, Info);
1462 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
1463 std::unique_ptr<X86Operand>
1464 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1465 MCAsmParser &Parser = getParser();
1466 const AsmToken &Tok = Parser.getTok();
1467 // Eat "{" and mark the current place.
1468 const SMLoc consumedToken = consumeToken();
1469 if (Tok.getIdentifier().startswith("r")){
1470 int rndMode = StringSwitch<int>(Tok.getIdentifier())
1471 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
1472 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
1473 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
1474 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
1477 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode.");
1478 Parser.Lex(); // Eat "r*" of r*-sae
1479 if (!getLexer().is(AsmToken::Minus))
1480 return ErrorOperand(Tok.getLoc(), "Expected - at this point");
1481 Parser.Lex(); // Eat "-"
1482 Parser.Lex(); // Eat the sae
1483 if (!getLexer().is(AsmToken::RCurly))
1484 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1485 Parser.Lex(); // Eat "}"
1486 const MCExpr *RndModeOp =
1487 MCConstantExpr::create(rndMode, Parser.getContext());
1488 return X86Operand::CreateImm(RndModeOp, Start, End);
1490 if(Tok.getIdentifier().equals("sae")){
1491 Parser.Lex(); // Eat the sae
1492 if (!getLexer().is(AsmToken::RCurly))
1493 return ErrorOperand(Tok.getLoc(), "Expected } at this point");
1494 Parser.Lex(); // Eat "}"
1495 return X86Operand::CreateToken("{sae}", consumedToken);
1497 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1499 /// ParseIntelMemOperand - Parse intel style memory operand.
1500 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1503 MCAsmParser &Parser = getParser();
1504 const AsmToken &Tok = Parser.getTok();
1507 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1508 if (getLexer().is(AsmToken::LBrac))
1509 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1510 assert(ImmDisp == 0);
1513 if (!isParsingInlineAsm()) {
1514 if (getParser().parsePrimaryExpr(Val, End))
1515 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1517 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1520 InlineAsmIdentifierInfo Info;
1521 StringRef Identifier = Tok.getString();
1522 if (ParseIntelIdentifier(Val, Identifier, Info,
1523 /*Unevaluated=*/false, End))
1526 if (!getLexer().is(AsmToken::LBrac))
1527 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1528 /*Scale=*/1, Start, End, Size, Identifier, Info);
1530 Parser.Lex(); // Eat '['
1532 // Parse Identifier [ ImmDisp ]
1533 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1534 /*AddImmPrefix=*/false);
1535 if (ParseIntelExpression(SM, End))
1539 Error(Start, "cannot use more than one symbol in memory operand");
1542 if (SM.getBaseReg()) {
1543 Error(Start, "cannot use base register with variable reference");
1546 if (SM.getIndexReg()) {
1547 Error(Start, "cannot use index register with variable reference");
1551 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1552 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1553 // we're pointing to a local variable in memory, so the base register is
1554 // really the frame or stack pointer.
1555 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1556 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1557 Start, End, Size, Identifier, Info.OpDecl);
1560 /// Parse the '.' operator.
1561 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1562 const MCExpr *&NewDisp) {
1563 MCAsmParser &Parser = getParser();
1564 const AsmToken &Tok = Parser.getTok();
1565 int64_t OrigDispVal, DotDispVal;
1567 // FIXME: Handle non-constant expressions.
1568 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp))
1569 OrigDispVal = OrigDisp->getValue();
1571 return Error(Tok.getLoc(), "Non-constant offsets are not supported!");
1573 // Drop the optional '.'.
1574 StringRef DotDispStr = Tok.getString();
1575 if (DotDispStr.startswith("."))
1576 DotDispStr = DotDispStr.drop_front(1);
1578 // .Imm gets lexed as a real.
1579 if (Tok.is(AsmToken::Real)) {
1581 DotDispStr.getAsInteger(10, DotDisp);
1582 DotDispVal = DotDisp.getZExtValue();
1583 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1585 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1586 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1588 return Error(Tok.getLoc(), "Unable to lookup field reference!");
1589 DotDispVal = DotDisp;
1591 return Error(Tok.getLoc(), "Unexpected token type!");
1593 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1594 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1595 unsigned Len = DotDispStr.size();
1596 unsigned Val = OrigDispVal + DotDispVal;
1597 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
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->push_back(AsmRewrite(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->push_back(AsmRewrite(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->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1722 // Otherwise, rewrite the complex expression as a single immediate.
1723 InstInfo->AsmRewrites->push_back(AsmRewrite(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 && ScaleVal != 8){
1998 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
2001 Scale = (unsigned)ScaleVal;
2004 } else if (getLexer().isNot(AsmToken::RParen)) {
2005 // A scale amount without an index is ignored.
2007 SMLoc Loc = Parser.getTok().getLoc();
2010 if (getParser().parseAbsoluteExpression(Value))
2014 Warning(Loc, "scale factor without index register is ignored");
2019 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
2020 if (getLexer().isNot(AsmToken::RParen)) {
2021 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
2024 SMLoc MemEnd = Parser.getTok().getEndLoc();
2025 Parser.Lex(); // Eat the ')'.
2027 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
2028 // and then only in non-64-bit modes. Except for DX, which is a special case
2029 // because an unofficial form of in/out instructions uses it.
2030 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
2031 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP &&
2032 BaseReg != X86::SI && BaseReg != X86::DI)) &&
2033 BaseReg != X86::DX) {
2034 Error(BaseLoc, "invalid 16-bit base register");
2038 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
2039 Error(IndexLoc, "16-bit memory operand may not include only index register");
2044 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
2045 Error(BaseLoc, ErrMsg);
2049 if (SegReg || BaseReg || IndexReg)
2050 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
2051 IndexReg, Scale, MemStart, MemEnd);
2052 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
2055 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2056 SMLoc NameLoc, OperandVector &Operands) {
2057 MCAsmParser &Parser = getParser();
2059 StringRef PatchedName = Name;
2061 // FIXME: Hack to recognize setneb as setne.
2062 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
2063 PatchedName != "setb" && PatchedName != "setnb")
2064 PatchedName = PatchedName.substr(0, Name.size()-1);
2066 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
2067 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
2068 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
2069 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
2070 bool IsVCMP = PatchedName[0] == 'v';
2071 unsigned CCIdx = IsVCMP ? 4 : 3;
2072 unsigned ComparisonCode = StringSwitch<unsigned>(
2073 PatchedName.slice(CCIdx, PatchedName.size() - 2))
2077 .Case("unord", 0x03)
2082 /* AVX only from here */
2083 .Case("eq_uq", 0x08)
2086 .Case("false", 0x0B)
2087 .Case("neq_oq", 0x0C)
2091 .Case("eq_os", 0x10)
2092 .Case("lt_oq", 0x11)
2093 .Case("le_oq", 0x12)
2094 .Case("unord_s", 0x13)
2095 .Case("neq_us", 0x14)
2096 .Case("nlt_uq", 0x15)
2097 .Case("nle_uq", 0x16)
2098 .Case("ord_s", 0x17)
2099 .Case("eq_us", 0x18)
2100 .Case("nge_uq", 0x19)
2101 .Case("ngt_uq", 0x1A)
2102 .Case("false_os", 0x1B)
2103 .Case("neq_os", 0x1C)
2104 .Case("ge_oq", 0x1D)
2105 .Case("gt_oq", 0x1E)
2106 .Case("true_us", 0x1F)
2108 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) {
2110 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx),
2113 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2114 getParser().getContext());
2115 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2117 PatchedName = PatchedName.substr(PatchedName.size() - 2);
2121 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2122 if (PatchedName.startswith("vpcmp") &&
2123 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2124 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2125 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2126 unsigned ComparisonCode = StringSwitch<unsigned>(
2127 PatchedName.slice(5, PatchedName.size() - CCIdx))
2128 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
2131 //.Case("false", 0x3) // Not a documented alias.
2135 //.Case("true", 0x7) // Not a documented alias.
2137 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) {
2138 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc));
2140 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2141 getParser().getContext());
2142 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2144 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2148 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
2149 if (PatchedName.startswith("vpcom") &&
2150 (PatchedName.endswith("b") || PatchedName.endswith("w") ||
2151 PatchedName.endswith("d") || PatchedName.endswith("q"))) {
2152 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1;
2153 unsigned ComparisonCode = StringSwitch<unsigned>(
2154 PatchedName.slice(5, PatchedName.size() - CCIdx))
2164 if (ComparisonCode != ~0U) {
2165 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc));
2167 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode,
2168 getParser().getContext());
2169 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
2171 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx);
2175 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
2177 // Determine whether this is an instruction prefix.
2179 Name == "lock" || Name == "rep" ||
2180 Name == "repe" || Name == "repz" ||
2181 Name == "repne" || Name == "repnz" ||
2182 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" ||
2253 AddDefaultSrcDestOperands(Operands,
2254 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
2255 DefaultMemDIOperand(NameLoc));
2258 // Append default arguments to "outs[bwld]"
2259 if (Name.startswith("outs") && Operands.size() == 1 &&
2260 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
2261 Name == "outsd" )) {
2262 AddDefaultSrcDestOperands(Operands,
2263 DefaultMemSIOperand(NameLoc),
2264 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
2267 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
2268 // values of $SIREG according to the mode. It would be nice if this
2269 // could be achieved with InstAlias in the tables.
2270 if (Name.startswith("lods") && Operands.size() == 1 &&
2271 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
2272 Name == "lodsl" || Name == "lodsd" || Name == "lodsq"))
2273 Operands.push_back(DefaultMemSIOperand(NameLoc));
2275 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
2276 // values of $DIREG according to the mode. It would be nice if this
2277 // could be achieved with InstAlias in the tables.
2278 if (Name.startswith("stos") && Operands.size() == 1 &&
2279 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
2280 Name == "stosl" || Name == "stosd" || Name == "stosq"))
2281 Operands.push_back(DefaultMemDIOperand(NameLoc));
2283 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
2284 // values of $DIREG according to the mode. It would be nice if this
2285 // could be achieved with InstAlias in the tables.
2286 if (Name.startswith("scas") && Operands.size() == 1 &&
2287 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
2288 Name == "scasl" || Name == "scasd" || Name == "scasq"))
2289 Operands.push_back(DefaultMemDIOperand(NameLoc));
2291 // Add default SI and DI operands to "cmps[bwlq]".
2292 if (Name.startswith("cmps") &&
2293 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2294 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2295 if (Operands.size() == 1) {
2296 AddDefaultSrcDestOperands(Operands,
2297 DefaultMemDIOperand(NameLoc),
2298 DefaultMemSIOperand(NameLoc));
2299 } else if (Operands.size() == 3) {
2300 X86Operand &Op = (X86Operand &)*Operands[1];
2301 X86Operand &Op2 = (X86Operand &)*Operands[2];
2302 if (!doSrcDstMatch(Op, Op2))
2303 return Error(Op.getStartLoc(),
2304 "mismatching source and destination index registers");
2308 // Add default SI and DI operands to "movs[bwlq]".
2309 if ((Name.startswith("movs") &&
2310 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
2311 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
2312 (Name.startswith("smov") &&
2313 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
2314 Name == "smovl" || Name == "smovd" || Name == "smovq"))) {
2315 if (Operands.size() == 1) {
2316 if (Name == "movsd")
2317 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
2318 AddDefaultSrcDestOperands(Operands,
2319 DefaultMemSIOperand(NameLoc),
2320 DefaultMemDIOperand(NameLoc));
2321 } else if (Operands.size() == 3) {
2322 X86Operand &Op = (X86Operand &)*Operands[1];
2323 X86Operand &Op2 = (X86Operand &)*Operands[2];
2324 if (!doSrcDstMatch(Op, Op2))
2325 return Error(Op.getStartLoc(),
2326 "mismatching source and destination index registers");
2330 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
2332 if ((Name.startswith("shr") || Name.startswith("sar") ||
2333 Name.startswith("shl") || Name.startswith("sal") ||
2334 Name.startswith("rcl") || Name.startswith("rcr") ||
2335 Name.startswith("rol") || Name.startswith("ror")) &&
2336 Operands.size() == 3) {
2337 if (isParsingIntelSyntax()) {
2339 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]);
2340 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2341 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2342 Operands.pop_back();
2344 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2345 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) &&
2346 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1)
2347 Operands.erase(Operands.begin() + 1);
2351 // Transforms "int $3" into "int3" as a size optimization. We can't write an
2352 // instalias with an immediate operand yet.
2353 if (Name == "int" && Operands.size() == 2) {
2354 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
2356 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm()))
2357 if (CE->getValue() == 3) {
2358 Operands.erase(Operands.begin() + 1);
2359 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3");
2366 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
2369 TmpInst.setOpcode(Opcode);
2371 TmpInst.addOperand(MCOperand::createReg(Reg));
2372 TmpInst.addOperand(MCOperand::createReg(Reg));
2373 TmpInst.addOperand(Inst.getOperand(0));
2378 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
2379 bool isCmp = false) {
2380 if (!Inst.getOperand(0).isImm() ||
2381 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
2384 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
2387 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
2388 bool isCmp = false) {
2389 if (!Inst.getOperand(0).isImm() ||
2390 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
2393 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
2396 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
2397 bool isCmp = false) {
2398 if (!Inst.getOperand(0).isImm() ||
2399 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
2402 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
2405 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
2406 switch (Inst.getOpcode()) {
2407 default: return true;
2409 X86Operand &Op = static_cast<X86Operand &>(*Ops[1]);
2410 assert(Op.isImm() && "expected immediate");
2412 if (!Op.getImm()->evaluateAsAbsolute(Res) || Res > 255) {
2413 Error(Op.getStartLoc(), "interrupt vector must be in range [0-255]");
2418 llvm_unreachable("handle the instruction appropriately");
2421 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
2422 switch (Inst.getOpcode()) {
2423 default: return false;
2424 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
2425 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
2426 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
2427 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
2428 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
2429 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
2430 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
2431 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
2432 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
2433 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
2434 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
2435 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
2436 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
2437 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
2438 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
2439 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
2440 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
2441 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
2442 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
2443 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
2444 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
2445 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
2446 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
2447 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
2448 case X86::VMOVAPDrr:
2449 case X86::VMOVAPDYrr:
2450 case X86::VMOVAPSrr:
2451 case X86::VMOVAPSYrr:
2452 case X86::VMOVDQArr:
2453 case X86::VMOVDQAYrr:
2454 case X86::VMOVDQUrr:
2455 case X86::VMOVDQUYrr:
2456 case X86::VMOVUPDrr:
2457 case X86::VMOVUPDYrr:
2458 case X86::VMOVUPSrr:
2459 case X86::VMOVUPSYrr: {
2460 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2461 !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg()))
2465 switch (Inst.getOpcode()) {
2466 default: llvm_unreachable("Invalid opcode");
2467 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break;
2468 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break;
2469 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break;
2470 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break;
2471 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break;
2472 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break;
2473 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break;
2474 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break;
2475 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break;
2476 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break;
2477 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break;
2478 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break;
2480 Inst.setOpcode(NewOpc);
2484 case X86::VMOVSSrr: {
2485 if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) ||
2486 !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg()))
2489 switch (Inst.getOpcode()) {
2490 default: llvm_unreachable("Invalid opcode");
2491 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
2492 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
2494 Inst.setOpcode(NewOpc);
2500 static const char *getSubtargetFeatureName(uint64_t Val);
2502 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
2504 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
2508 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2509 OperandVector &Operands,
2510 MCStreamer &Out, uint64_t &ErrorInfo,
2511 bool MatchingInlineAsm) {
2512 if (isParsingIntelSyntax())
2513 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2515 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
2519 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
2520 OperandVector &Operands, MCStreamer &Out,
2521 bool MatchingInlineAsm) {
2522 // FIXME: This should be replaced with a real .td file alias mechanism.
2523 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
2525 const char *Repl = StringSwitch<const char *>(Op.getToken())
2526 .Case("finit", "fninit")
2527 .Case("fsave", "fnsave")
2528 .Case("fstcw", "fnstcw")
2529 .Case("fstcww", "fnstcw")
2530 .Case("fstenv", "fnstenv")
2531 .Case("fstsw", "fnstsw")
2532 .Case("fstsww", "fnstsw")
2533 .Case("fclex", "fnclex")
2537 Inst.setOpcode(X86::WAIT);
2539 if (!MatchingInlineAsm)
2540 EmitInstruction(Inst, Operands, Out);
2541 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
2545 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2546 bool MatchingInlineAsm) {
2547 assert(ErrorInfo && "Unknown missing feature!");
2548 ArrayRef<SMRange> EmptyRanges = None;
2549 SmallString<126> Msg;
2550 raw_svector_ostream OS(Msg);
2551 OS << "instruction requires:";
2553 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2554 if (ErrorInfo & Mask)
2555 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2558 return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2561 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2562 OperandVector &Operands,
2564 uint64_t &ErrorInfo,
2565 bool MatchingInlineAsm) {
2566 assert(!Operands.empty() && "Unexpect empty operand list!");
2567 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2568 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2569 ArrayRef<SMRange> EmptyRanges = None;
2571 // First, handle aliases that expand to multiple instructions.
2572 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2574 bool WasOriginallyInvalidOperand = false;
2577 // First, try a direct match.
2578 switch (MatchInstructionImpl(Operands, Inst,
2579 ErrorInfo, MatchingInlineAsm,
2580 isParsingIntelSyntax())) {
2581 default: llvm_unreachable("Unexpected match result!");
2583 if (!validateInstruction(Inst, Operands))
2586 // Some instructions need post-processing to, for example, tweak which
2587 // encoding is selected. Loop on it while changes happen so the
2588 // individual transformations can chain off each other.
2589 if (!MatchingInlineAsm)
2590 while (processInstruction(Inst, Operands))
2594 if (!MatchingInlineAsm)
2595 EmitInstruction(Inst, Operands, Out);
2596 Opcode = Inst.getOpcode();
2598 case Match_MissingFeature:
2599 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2600 case Match_InvalidOperand:
2601 WasOriginallyInvalidOperand = true;
2603 case Match_MnemonicFail:
2607 // FIXME: Ideally, we would only attempt suffix matches for things which are
2608 // valid prefixes, and we could just infer the right unambiguous
2609 // type. However, that requires substantially more matcher support than the
2612 // Change the operand to point to a temporary token.
2613 StringRef Base = Op.getToken();
2614 SmallString<16> Tmp;
2617 Op.setTokenValue(Tmp);
2619 // If this instruction starts with an 'f', then it is a floating point stack
2620 // instruction. These come in up to three forms for 32-bit, 64-bit, and
2621 // 80-bit floating point, which use the suffixes s,l,t respectively.
2623 // Otherwise, we assume that this may be an integer instruction, which comes
2624 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2625 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2627 // Check for the various suffix matches.
2628 uint64_t ErrorInfoIgnore;
2629 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2632 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
2633 Tmp.back() = Suffixes[I];
2634 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2635 MatchingInlineAsm, isParsingIntelSyntax());
2636 // If this returned as a missing feature failure, remember that.
2637 if (Match[I] == Match_MissingFeature)
2638 ErrorInfoMissingFeature = ErrorInfoIgnore;
2641 // Restore the old token.
2642 Op.setTokenValue(Base);
2644 // If exactly one matched, then we treat that as a successful match (and the
2645 // instruction will already have been filled in correctly, since the failing
2646 // matches won't have modified it).
2647 unsigned NumSuccessfulMatches =
2648 std::count(std::begin(Match), std::end(Match), Match_Success);
2649 if (NumSuccessfulMatches == 1) {
2651 if (!MatchingInlineAsm)
2652 EmitInstruction(Inst, Operands, Out);
2653 Opcode = Inst.getOpcode();
2657 // Otherwise, the match failed, try to produce a decent error message.
2659 // If we had multiple suffix matches, then identify this as an ambiguous
2661 if (NumSuccessfulMatches > 1) {
2663 unsigned NumMatches = 0;
2664 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I)
2665 if (Match[I] == Match_Success)
2666 MatchChars[NumMatches++] = Suffixes[I];
2668 SmallString<126> Msg;
2669 raw_svector_ostream OS(Msg);
2670 OS << "ambiguous instructions require an explicit suffix (could be ";
2671 for (unsigned i = 0; i != NumMatches; ++i) {
2674 if (i + 1 == NumMatches)
2676 OS << "'" << Base << MatchChars[i] << "'";
2679 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2683 // Okay, we know that none of the variants matched successfully.
2685 // If all of the instructions reported an invalid mnemonic, then the original
2686 // mnemonic was invalid.
2687 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) {
2688 if (!WasOriginallyInvalidOperand) {
2689 ArrayRef<SMRange> Ranges =
2690 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2691 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2692 Ranges, MatchingInlineAsm);
2695 // Recover location info for the operand if we know which was the problem.
2696 if (ErrorInfo != ~0ULL) {
2697 if (ErrorInfo >= Operands.size())
2698 return Error(IDLoc, "too few operands for instruction",
2699 EmptyRanges, MatchingInlineAsm);
2701 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
2702 if (Operand.getStartLoc().isValid()) {
2703 SMRange OperandRange = Operand.getLocRange();
2704 return Error(Operand.getStartLoc(), "invalid operand for instruction",
2705 OperandRange, MatchingInlineAsm);
2709 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2713 // If one instruction matched with a missing feature, report this as a
2715 if (std::count(std::begin(Match), std::end(Match),
2716 Match_MissingFeature) == 1) {
2717 ErrorInfo = ErrorInfoMissingFeature;
2718 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2722 // If one instruction matched with an invalid operand, report this as an
2724 if (std::count(std::begin(Match), std::end(Match),
2725 Match_InvalidOperand) == 1) {
2726 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2730 // If all of these were an outright failure, report it in a useless way.
2731 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2732 EmptyRanges, MatchingInlineAsm);
2736 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2737 OperandVector &Operands,
2739 uint64_t &ErrorInfo,
2740 bool MatchingInlineAsm) {
2741 assert(!Operands.empty() && "Unexpect empty operand list!");
2742 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
2743 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
2744 StringRef Mnemonic = Op.getToken();
2745 ArrayRef<SMRange> EmptyRanges = None;
2747 // First, handle aliases that expand to multiple instructions.
2748 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm);
2752 // Find one unsized memory operand, if present.
2753 X86Operand *UnsizedMemOp = nullptr;
2754 for (const auto &Op : Operands) {
2755 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
2756 if (X86Op->isMemUnsized())
2757 UnsizedMemOp = X86Op;
2760 // Allow some instructions to have implicitly pointer-sized operands. This is
2761 // compatible with gas.
2763 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
2764 for (const char *Instr : PtrSizedInstrs) {
2765 if (Mnemonic == Instr) {
2766 UnsizedMemOp->Mem.Size = getPointerWidth();
2772 // If an unsized memory operand is present, try to match with each memory
2773 // operand size. In Intel assembly, the size is not part of the instruction
2775 SmallVector<unsigned, 8> Match;
2776 uint64_t ErrorInfoMissingFeature = 0;
2777 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
2778 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
2779 for (unsigned Size : MopSizes) {
2780 UnsizedMemOp->Mem.Size = Size;
2781 uint64_t ErrorInfoIgnore;
2782 unsigned LastOpcode = Inst.getOpcode();
2784 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2785 MatchingInlineAsm, isParsingIntelSyntax());
2786 if (Match.empty() || LastOpcode != Inst.getOpcode())
2789 // If this returned as a missing feature failure, remember that.
2790 if (Match.back() == Match_MissingFeature)
2791 ErrorInfoMissingFeature = ErrorInfoIgnore;
2794 // Restore the size of the unsized memory operand if we modified it.
2796 UnsizedMemOp->Mem.Size = 0;
2799 // If we haven't matched anything yet, this is not a basic integer or FPU
2800 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
2801 // matching with the unsized operand.
2802 if (Match.empty()) {
2803 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2805 isParsingIntelSyntax()));
2806 // If this returned as a missing feature failure, remember that.
2807 if (Match.back() == Match_MissingFeature)
2808 ErrorInfoMissingFeature = ErrorInfo;
2811 // Restore the size of the unsized memory operand if we modified it.
2813 UnsizedMemOp->Mem.Size = 0;
2815 // If it's a bad mnemonic, all results will be the same.
2816 if (Match.back() == Match_MnemonicFail) {
2817 ArrayRef<SMRange> Ranges =
2818 MatchingInlineAsm ? EmptyRanges : Op.getLocRange();
2819 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
2820 Ranges, MatchingInlineAsm);
2823 // If exactly one matched, then we treat that as a successful match (and the
2824 // instruction will already have been filled in correctly, since the failing
2825 // matches won't have modified it).
2826 unsigned NumSuccessfulMatches =
2827 std::count(std::begin(Match), std::end(Match), Match_Success);
2828 if (NumSuccessfulMatches == 1) {
2829 if (!validateInstruction(Inst, Operands))
2832 // Some instructions need post-processing to, for example, tweak which
2833 // encoding is selected. Loop on it while changes happen so the individual
2834 // transformations can chain off each other.
2835 if (!MatchingInlineAsm)
2836 while (processInstruction(Inst, Operands))
2839 if (!MatchingInlineAsm)
2840 EmitInstruction(Inst, Operands, Out);
2841 Opcode = Inst.getOpcode();
2843 } else if (NumSuccessfulMatches > 1) {
2844 assert(UnsizedMemOp &&
2845 "multiple matches only possible with unsized memory operands");
2846 ArrayRef<SMRange> Ranges =
2847 MatchingInlineAsm ? EmptyRanges : UnsizedMemOp->getLocRange();
2848 return Error(UnsizedMemOp->getStartLoc(),
2849 "ambiguous operand size for instruction '" + Mnemonic + "\'",
2850 Ranges, MatchingInlineAsm);
2853 // If one instruction matched with a missing feature, report this as a
2855 if (std::count(std::begin(Match), std::end(Match),
2856 Match_MissingFeature) == 1) {
2857 ErrorInfo = ErrorInfoMissingFeature;
2858 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
2862 // If one instruction matched with an invalid operand, report this as an
2864 if (std::count(std::begin(Match), std::end(Match),
2865 Match_InvalidOperand) == 1) {
2866 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2870 // If all of these were an outright failure, report it in a useless way.
2871 return Error(IDLoc, "unknown instruction mnemonic", EmptyRanges,
2875 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
2876 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
2879 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2880 MCAsmParser &Parser = getParser();
2881 StringRef IDVal = DirectiveID.getIdentifier();
2882 if (IDVal == ".word")
2883 return ParseDirectiveWord(2, DirectiveID.getLoc());
2884 else if (IDVal.startswith(".code"))
2885 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2886 else if (IDVal.startswith(".att_syntax")) {
2887 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2888 if (Parser.getTok().getString() == "prefix")
2890 else if (Parser.getTok().getString() == "noprefix")
2891 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
2892 "supported: registers must have a "
2893 "'%' prefix in .att_syntax");
2895 getParser().setAssemblerDialect(0);
2897 } else if (IDVal.startswith(".intel_syntax")) {
2898 getParser().setAssemblerDialect(1);
2899 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2900 if (Parser.getTok().getString() == "noprefix")
2902 else if (Parser.getTok().getString() == "prefix")
2903 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
2904 "supported: registers must not have "
2905 "a '%' prefix in .intel_syntax");
2912 /// ParseDirectiveWord
2913 /// ::= .word [ expression (, expression)* ]
2914 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2915 MCAsmParser &Parser = getParser();
2916 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2918 const MCExpr *Value;
2919 if (getParser().parseExpression(Value))
2922 getParser().getStreamer().EmitValue(Value, Size);
2924 if (getLexer().is(AsmToken::EndOfStatement))
2927 // FIXME: Improve diagnostic.
2928 if (getLexer().isNot(AsmToken::Comma)) {
2929 Error(L, "unexpected token in directive");
2940 /// ParseDirectiveCode
2941 /// ::= .code16 | .code32 | .code64
2942 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2943 MCAsmParser &Parser = getParser();
2944 if (IDVal == ".code16") {
2946 if (!is16BitMode()) {
2947 SwitchMode(X86::Mode16Bit);
2948 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2950 } else if (IDVal == ".code32") {
2952 if (!is32BitMode()) {
2953 SwitchMode(X86::Mode32Bit);
2954 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2956 } else if (IDVal == ".code64") {
2958 if (!is64BitMode()) {
2959 SwitchMode(X86::Mode64Bit);
2960 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2963 Error(L, "unknown directive " + IDVal);
2970 // Force static initialization.
2971 extern "C" void LLVMInitializeX86AsmParser() {
2972 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2973 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2976 #define GET_REGISTER_MATCHER
2977 #define GET_MATCHER_IMPLEMENTATION
2978 #define GET_SUBTARGET_FEATURE_NAME
2979 #include "X86GenAsmMatcher.inc"